1

I am working on a quiz project which also allows user to add new questions.

I have an array list in which questions are stored and retrieved for displaying. Each object saved in the array list contains 5 strings.

  • Question
  • Right answer
  • Wrong answer 1
  • Wrong answer 2
  • Wrong answer 3

How can I randomly select objects from the array list to be displayed on the screen? And how can I shuffle the 4 answers (as radio buttons) so that the right answer appears at different positions each time?

    namespace quiz
{
    public partial class Quiz : Form
    {
        private ArrayList Questionslist;

        public Quiz(ArrayList list)
        {
            InitializeComponent();
            Questionslist = list;
        }

        int index = 0;
        private void Quiz_Load(object sender, EventArgs e)
        {
            //creating an object of class Question and copying the object at index1 from arraylist into it  
            Question q = (Question)Questionslist[index];
            //to display the contents
            lblQs.Text = q.Quest;
            radioButtonA1.Text = q.RightAnswer;
            radioButtonA2.Text = q.WrongAnswer1;
            radioButtonA3.Text = q.WrongAnswer2;
            radioButtonA4.Text = q.WrongAnswer3;            
        }

        private int Score = 0;

        private void radioButtonA1_CheckedChanged(object sender, EventArgs e)
        {
            //if checkbox is checked
            //displaying text in separate two lines on messagebox
            if (radioButtonA1.Checked == true)
            {
                MessageBox.Show("Well Done" + Environment.NewLine + "You Are Right");
                Score++;
                index++;

                if (index < Questionslist.Count)
                {
                    radioButtonA1.Checked = false;
                    radioButtonA2.Checked = false;
                    radioButtonA3.Checked = false;
                    radioButtonA4.Checked = false;
                    Quiz_Load(sender, e);
                }
                else
                {
                    index--;
                    MessageBox.Show("Quiz Finished" + Environment.NewLine + "your Score is" + Score);
                    Close();
                }
            }
        }

        private void radioButtonA2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonA2.Checked == true)
            {
                MessageBox.Show("Sorry" + Environment.NewLine + "You Are Wrong");
                Close();
            }
        }

        private void radioButtonA3_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonA3.Checked == true)
            {
                MessageBox.Show("Sorry" + Environment.NewLine + "You Are Wrong");
                Close();
            }
        }

        private void radioButtonA4_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonA4.Checked == true)
            {
                MessageBox.Show("Sorry" + Environment.NewLine + "You Are Wrong");
                Close();
            }
        }
    }
}

this is the code for class question

namespace quiz
{
    [Serializable()]
    public class Question : ISerializable
    {
        public String Quest;
        public String RightAnswer;
        public String WrongAnswer1;
        public String WrongAnswer2;
        public String WrongAnswer3;

        public Question()
        {
           Quest = null;
           RightAnswer=null;
           WrongAnswer1=null;
           WrongAnswer2=null;
           WrongAnswer3=null;
        }

        //serialization function
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Question", Quest);
            info.AddValue("Right Answer", RightAnswer);
            info.AddValue("WrongAnswer1",WrongAnswer1);
            info.AddValue("WrongAnswer2",WrongAnswer2);
            info.AddValue("WrongAnswer3",WrongAnswer3);
        }

        //deserializaton constructor
        public Question(SerializationInfo info, StreamingContext context)
        {
            Quest = (String)info.GetValue("Question", typeof(String));
            RightAnswer=(String)info.GetValue("Right Answer",typeof(String));
            WrongAnswer1=(String)info.GetValue("WrongAnswer1",typeof(String));
            WrongAnswer2=(String)info.GetValue("WrongAnswer2",typeof(String));
            WrongAnswer3=(String)info.GetValue("WrongAnswer3",typeof(String));
        }     
    }
}
Mrs. Haris
  • 13
  • 1
  • 5

7 Answers7

1

Pick a random string from ArrayList:

string randomPick(ArrayList strings)
{
    return strings[random.Next(strings.Length)];
}

You might consider having a Question class. That would contain a string Text member for the question (because I think Question.Question is silly, Question.Text makes more sense when read). Since you mentioned an ArrayList (not because I think it's the best solution), you can have one of those as a member as well which would contain all the potential answers.

When you create a question, you can display Question.Text, then use the function above to randomly pick an answer. Then use RemoveAt(index) on the answers to ensure you don't duplicate answers.

tnw
  • 13,521
  • 15
  • 70
  • 111
1

I'd make a Question class containing the question, the right answer and a list of possible answers, and have methods that return the possible answers in randomized order and compares a guess to the correct answer. It could look something like this:

class Question
{
    String question;
    String rightAnswer;
    List<String> possibleAnswers = new ArrayList<String>();

    public Question(String question, String answer, List<String> possibleAnswers)
    {
      this.question = question;
      this.rightAnswer = answer;
      this.possibleAnswers.addAll(possibleAnswers);
      this.possibleAnswers.add(this.rightAnswer);
    }

    public List<String> getAnswers()
    {
        Collections.shuffle(possibleAnswers);
        return possibleAnswers;
    }

    public boolean isCorrect(String answer)
    {
      return answer.equals(correctAnswer);
    }
}
AcId
  • 458
  • 2
  • 12
1

You know which one is the 'right' answer based on the Text property. One approach would be to store the answers in an array and shuffle the array before assigning it to the radio buttons:

// You're going to make questionList a List<Question> because if you like
// Right answers you know that ArrayList is Wrong.
Question q = questionList[index];

// You should move this next bit to the Question class
string[] answers = new string[]
    {
        q.RightAnswer,
        q.WrongAnswer1,
        q.WrongAnswer2,
        q.WrongAnswer3
    };

// Using the Fisher-Yates shuffle from:
// http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp
Shuffle(answers);

// Ideally: question.GetShuffledAnswers()

radioButtonA1.Text = answers[0];
radioButtonA2.Text = answers[1];
radioButtonA3.Text = answers[2];
radioButtonA4.Text = answers[3];

Then later, all you need is a single radio button event handler that they all share:

private void radioButton_CheckedChanged(object sender, EventArgs e)
{
    RadioButton rb = (RadioButton)sender;
    Question q = questionList[index];

    //if checkbox is checked
    //displaying text in separate two lines on messagebox
    if (rb.Checked && q.RightAnswer == rb.Text)
    {
        // Move your code to another method
        // MessageBox.Show("Well Done" + Environment.NewLine + "You Are Right");
        UserSelectedCorrectAnswer();
    }
    else if (rb.Checked)
    {
        // They checked the radio button, but were wrong!
        // MessageBox.Show("Sorry" + Environment.NewLine + "You Are Wrong");
        UserSelectedWrongAnswer();
    }
}
user7116
  • 63,008
  • 17
  • 141
  • 172
0

You should encapsulate all the questions in a class. For example, create a class named Question. This class can contain 5 variables: String question, String answer1, String answer2, String answer3 and String answer4.

Save all your questions in a database or read them from a file and load them on the start of the program.

Use the Random class to randomly select a question and to 'shuffle' the 4 questions.

Joetjah
  • 6,292
  • 8
  • 55
  • 90
0

Here's a method that will work:

public List<string> Randomize(string[] numbers)
{
    List<string> randomized = new List<string>();
    List<string> original = new List<string>(numbers);
    Random r = new Random();
    while (original.Count > 0) {
        int index = r.Next(original.Count);
        randomized.Add(original[index]);
        original.RemoveAt(index);
    }

return randomized;
}

just adapt it to string array instead of int array

AAlferez
  • 1,480
  • 1
  • 22
  • 48
0

The shuffle is probably a standard question, but I guess this will work:

// Warning: Not a thread-safe type.
// Will be corrupted if application is multi-threaded.
static readonly Random randomNumberGenerator = new Random();


// Returns a new sequence whose elements are
// the elements of 'inputListOrArray' in random order
public static IEnumerable<T> Shuffle<T>(IReadOnlyList<T> inputListOrArray)
{
  return GetPermutation(inputListOrArray.Count).Select(x => inputListOrArray[x]);
}
static IEnumerable<int> GetPermutation(int n)
{
  var list = Enumerable.Range(0, n).ToArray();
  for (int idx = 0; idx < n; ++idx)
  {
    int swapWith = randomNumberGenerator.Next(idx, n);
    yield return list[swapWith];
    list[swapWith] = list[idx];
  }
}

If you don't have IReadOnlyList<T> (.NET 4.5), just use IList<T>. The incoming object is not mutated.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
0

thanks to all of u who answered my question.i did it this way.

 private void Quiz_Load(object sender, EventArgs e)
    {
        displayQs();
    }

    private void displayQs()
    {
            Random _random = new Random();
            int z = _random.Next(Questions.Count);
            Question q = (Question)Questions[z];
            Qslbl.Text = q.Quest;
            DisplayAns(q, _random);
    }

    private void DisplayAns(Question q, Random _random)
    {
        int j = 0;
        int[] array = new int[4];
        for (int i = 0; j <= 3; i++)
        {
            int x = _random.Next(4);
            x++;
            if (array.Contains(x))
            {
                continue;
            }
            else
            {
                array[j] = x;
                j++;
                string answer = null;
                if (j == 1)
                    answer = q.RightAnswer;
                else if (j == 2)
                    answer = q.WrongAnswer1;
                else if (j == 3)
                    answer = q.WrongAnswer2;
                else if (j == 4)
                    answer = q.WrongAnswer3;

                if (x == 1)
                    radioButton1.Text = answer;
                else if (x == 2)
                    radioButton2.Text = answer;
                else if (x == 3)
                    radioButton3.Text = answer;
                else if (x == 4)
                    radioButton4.Text = answer;
            }
        }
    }
Mrs. Haris
  • 13
  • 1
  • 5