Kotlin - Get new index of item in shuffled list

Viewed 294

I have a multiple choice quiz with 4 choices per answer. In the ArrayList with the questions and choices, the correct answer is set to the index of the correct option. I want to shuffle the choices but am not sure how to identify the new index of the correct answer. Any thoughts?

Question object

object ConstantsAnalysis {
        const val TOTAL_CORRECT: String = "total_correct"
        const val TOTAL_OPP: String = "total_opp"
        fun getQuestions3(): ArrayList<Questions3> {
            val questionList = ArrayList<Questions3>()
            val q1 = Questions3(1, null,
                "On a graph, the horizontal line along which data are plotted is the _____",
                "y axis", "x axis", "origin", "quadrant", 2, R.string.Jones_1995, null)
questionList.addAll(listOf(q1))
            questionList.shuffle()
            return questionList
        }
    }

Data class

data class Questions3(
    val id: Int, val image: Int?, val question: String, val option1: String, val option2: String,
    val option3: String, val option4: String, val correctAnswer: Int, val dialogBox: Int?, val dialogBox2: Int?)

Shuffle choices

val ansorder = arrayOf(question.option1, question.option2, question.option3, question.option4)
        ansorder.shuffle()
        radio_button1.text = ansorder[0]
        radio_button2.text = ansorder[1]
        radio_button3.text = ansorder[2]
        radio_button4.text = ansorder[3]

Check answer choice

if (questions3!!.correctAnswer != mSelectedOptionPosition) {
//do x
}

Edit (Since correct answer is a string and the index changes after shuffling, answerView(questions3.correctAnswer, R.drawable.correct_option_border.

class QuestionsActivityAnalysis : AppCompatActivity(), View.OnClickListener {

    private var mCurrentPosition:Int = 1
    private var mQuestionsList:ArrayList<Questions3>? = null
    private var mSelectedOptionPosition:Int = 0
    private var mCorrectAnswers: Int = 0
    private var mSelectedOptionText: String? = null

private fun shuffle() {
        val question = mQuestionsList!![mCurrentPosition - 1]
        val ansorder = arrayOf(question.option1, question.option2, question.option3, question.option4)
        ansorder.shuffle()
        radio_button1.text = ansorder[0]
        radio_button2.text = ansorder[1]
        radio_button3.text = ansorder[2]
        radio_button4.text = ansorder[3]
    }

override fun onClick(v: View?) {
        when(v?.id){
            R.id.radio_button1 -> { selectedOptionView(radio_button1, 1)
                mSelectedOptionText = radio_button1.text as String?
            }
            R.id.radio_button2 -> { selectedOptionView(radio_button2, 2)
                mSelectedOptionText = radio_button2.text as String?
            }
            R.id.radio_button3 -> { selectedOptionView(radio_button3, 3)
                mSelectedOptionText = radio_button3.text as String?
            }
            R.id.radio_button4 -> { selectedOptionView(radio_button4, 4)
                mSelectedOptionText = radio_button4.text as String?
            }

R.id.btn_submit -> {
val questions3 = mQuestionsList?.get(mCurrentPosition - 1)
                    if (questions3!!.correctAnswer != mSelectedOptionText) {
} else {
                        mCorrectAnswers++
                    }
                    answerView(questions3.correctAnswer, R.drawable.correct_option_border)

private fun answerView(answer: Int, drawableView: Int) {
        when(answer){
            1 -> {
                radio_button1.background = ContextCompat.getDrawable(this, drawableView)
            }
            2 -> {
                radio_button2.background = ContextCompat.getDrawable(this, drawableView)
            }
            3 -> {
                radio_button3.background = ContextCompat.getDrawable(this, drawableView)
            }
            4 -> {
                radio_button4.background = ContextCompat.getDrawable(this, drawableView)
            }
        }
    }
1 Answers

I would really recommend just creating a data class like this:

data class QuestionOption(val question:String, val isCorrect = false)

Afterwards you can shuffle any way you like and just check if the selected QuestionOption has isCorrect set to true. You get a bunch of benefits and the logic gets simpler.

Edit:

To make it easier to declare questions this way:

In general if you add questions in your code you want only as much necessary code as required. For this you can either declare a good constructor or a function that basically maps your values to a constructor. In your case I'd say

data class Questions3(
    val id: Int, val question: String, val option1: String, val option2: String,
    val option3: String, val correctOption: String, val image: Int?=null,val dialogBox1: Int?=null,val dialogBox2: Int?=null)

(notice how the optional parameters are last, you don't need to specify them as well thanks to them beeing null by default)

Makes sense, in theory you could also (not too clean but easy) just shuffle option 1-3 & correctOption and then just compare if the correctOption String matches the selected String.

Otherwise as I said, you can always create logic for mapping stuff. Here you can either map from Constructor to another Constructor, same with Functions that return a finished Object.

Related