Question

I'm trying to create a random multiple choice quiz for android. I want to display a random question from a stringarray, with the corresponding answer from another string array showing up in one of the four options. The other three options will come from another string array, which will be used provide the "wrong" answers for all the questions, randomly.

Two questions: Is there a better way to make a multiple choice quiz like this? -and- When the player selects an answer, how do I identify which array the answer came from?

This is the code I'm using to randomize:

String[] question = { //questions here// };  
ArrayList<String> questionList = new ArrayList(Arrays.asList(question));  

String[] answer = { //answers here// };  
ArrayList<String> answerList = new ArrayList(Arrays.asList(answer));

String[] distractor = { //distractors here// };  
ArrayList<String> distractorList = new ArrayList(Arrays.asList(distractor));  

int i = 0;  
Random r = new Random();  
public void randomize() {

        TextView word = (TextView) findViewById(R.id.textView1);
        TextView choice1 = (TextView) findViewById(R.id.textView2);
        TextView choice2 = (TextView) findViewById(R.id.textView3);
        TextView choice3 = (TextView) findViewById(R.id.textView4);
        TextView choice4 = (TextView) findViewById(R.id.textView5);
        if (i < question.length) {
            int remaining = r.nextInt(questionList.size());
            String q = questionList.get(remaining);
            word.setText(q);
            questionList.remove(remaining);
            String a = answerList.get(remaining);
            int slot = r.nextInt(4);
            TextView[] tvArray = { choice1, choice2, choice3, choice4 };
            tvArray[slot].setText(a);
            answerList.remove(remaining);
          //an if/else statement here to fill the remaining slots with distractors
Was it helpful?

Solution

I suggest creating a new class called QuestionAndAnswer. The class should hold the question and the correct answer, it could also hold any customized wrong answers and the user's choice. The exact implementation is entirely up to you.

In your Activity have an Array of this QuestionAndAnswer class to cycle through the list asking the questions and tally up the points when done.

(I could be more specific if you include the relevant code of what you have tried.)


Addition

This is what I would start with:
(From your code I'm guessing the distractorList contains the false answers that you want to display.)

public class QuestionAndAnswer {
    public List<String> allAnswers; // distractors plus real answer
    public String answer;
    public String question;
    public String selectedAnswer;
    public int selectedId = -1;

    public QuestionAndAnswer(String question, String answer, List<String> distractors) {
        this.question = question;
        this.answer = answer;
        allAnswers = new ArrayList<String> (distractors);

        // Add real answer to false answers and shuffle them around 
        allAnswers.add(answer);
        Collections.shuffle(allAnswers);
    }

    public boolean isCorrect() {
        return answer.equals(selectedAnswer);
    }
}

For the Activity I changed your four answer TextViews into a RadioGroup, this way the user can intuitively select an answer. I also assume that there will be prev and next buttons, they will adjust int currentQuestion and call fillInQuestion().

public class Example extends Activity {
    RadioGroup answerRadioGroup;
    int currentQuestion = 0;
    TextView questionTextView;
    List<QuestionAndAnswer> quiz = new ArrayList<QuestionAndAnswer>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        questionTextView = (TextView) findViewById(R.id.question);
        answerRadioGroup = (RadioGroup) findViewById(R.id.answers);

        // Setup a listener to save chosen answer
        answerRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if(checkedId > -1) {
                    QuestionAndAnswer qna = quiz.get(currentQuestion);
                    qna.selectedAnswer = ((RadioButton) group.findViewById(checkedId)).getText().toString();
                    qna.selectedId = checkedId;
                }
            }
        });

        String[] question = { //questions here// };  
        String[] answer = { //answers here// };  
        String[] distractor = { //distractors here// };  
        ArrayList<String> distractorList = Arrays.asList(distractor);  

        /* I assumed that there are 3 distractors per question and that they are organized in distractorList like so:
         *   "q1 distractor 1", "q1 distractor 2", "q1 distractor 3", 
         *   "q2 distractor 1", "q2 distractor 2", "q2 distractor 3",
         *   etc
         *   
         * If the question is: "The color of the sky", you'd see distractors:
         *   "red", "green", "violet"
         */   
        int length = question.length;
        for(int i = 0; i < length; i++)
            quiz.add(new QuestionAndAnswer(question[i], answer[i], distractorList.subList(i * 3, (i + 1) * 3)));
        Collections.shuffle(quiz);

        fillInQuestion();
    }

    public void fillInQuestion() {
        QuestionAndAnswer qna = quiz.get(currentQuestion);
        questionTextView.setText(qna.question);

        // Set all of the answers in the RadioButtons 
        int count = answerRadioGroup.getChildCount();
        for(int i = 0; i < count; i++)
            ((RadioButton) answerRadioGroup.getChildAt(i)).setText(qna.allAnswers.get(i));

        // Restore selected answer if exists otherwise clear previous question's choice
        if(qna.selectedId > -1)
            answerRadioGroup.check(qna.selectedId);
        else 
            answerRadioGroup.clearCheck();
    }
}

You may have noticed that QuestionAndAnswer has an isCorrect() method, when it is time to grade the quiz you can count the correct answers like this:

int correct = 0;
for(QuestionAndAnswer question : quiz)
    if(question.isCorrect())
        correct++;

This is my general idea. The code is a complete thought, so it will compile. Of course, you'll want to add a "next" Button to see the different questions. But this is enough for you to see one way to randomize your questions and answers while keeping them organized.

OTHER TIPS

Here a sample, you can try. This is the data-model like to hold stuffs for the Question-Answer thing.

<data-map>
    <question id="1">
        <ask>How many questions are asked on Android category daily? </ask>
        <answer-map>
            <option id="1">100 </option>
            <option id="2">111 </option>
            <option id="3">148 </option>
            <option id="4">217 </option>
        </answer-map>
        <correct id="3" />
    </question>


    <question id="2">
        <ask>Which band does John Lenon belong to? </ask>
        <answer-map>
            <option id="1">The Carpenters </option>
            <option id="2">The Beatles </option>
            <option id="3">Take That </option>
            <option id="4">Queen </option>
        </answer-map>
        <correct id="2" />
    </question>

</data-map>

Ok, so you everytime you display a question, you got all options to answer, and the correct answer of each question. Just create a proper data structure to hold them. Anyway, just a sample, not a perfect one, but give it a try if you're new on this stuffs ^^!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top