1

I have a quiz that I'm writing and I'm using 4 buttons text attributes to display the multiple choice answers. 1 is correct, the other 3 are wrong.

The answers are from my dataset and then randomly assigning the answers to the buttons text attributes, when the user selects an answer then it moves along to the next question and doing the same thing, as it should.

But what I can't seem to figure out is, since I'm assigning the answers randomly, how do I keep track of answer that was selected? Here is the code...

Label1.Text = ds.Tables[0].Rows[myNum]["Question"].ToString();
string[] array = new string[4] {
    ds.Tables[0].Rows[myNum]["CorrectAnswer"].ToString(),
    ds.Tables[0].Rows[myNum]["WrongAnswer1"].ToString(),
    ds.Tables[0].Rows[myNum]["WrongAnswer2"].ToString(), 
    ds.Tables[0].Rows[myNum]["WrongAnswer3"].ToString(),
};



// randomize the ordering of the items
System.Random rnd = new System.Random();
array = array.OrderBy(x => rnd.Next()).ToArray();

// each time you run this, the correct answer will be in a different place:
btn1.Text = array[0];
btn2.Text = array[1];
btn3.Text = array[2];
btn4.Text = array[3];


myNum = myNum + 1;

if (myNum == numOfRows)
   Response.Redirect("~/Results.aspx");

I have tried this...

ds.Tables[0].Rows[myNum]["CorrectAnswer"].ToString() + "1",
ds.Tables[0].Rows[myNum]["WrongAnswer1"].ToString() + "0",
ds.Tables[0].Rows[myNum]["WrongAnswer2"].ToString() + "0", 
ds.Tables[0].Rows[myNum]["WrongAnswer3"].ToString() + "0",

and as expected it didn't work at all, but I tried it any ways.

Any ideas?

Thanks

Ken Herbert
  • 5,205
  • 5
  • 28
  • 37
Chris
  • 2,953
  • 10
  • 48
  • 118

1 Answers1

1

When you shuffle your array you lose track of the correct solution. This is not what you want. You should always be able to tell from your code which button will be assigned the correct answer. This does not mean you should know which id this button has, but how it gets assigned.

One thing you could do for example is shuffle an array of your button objects, and always assign your correct answer to the first index in that array.

So you create an array of your button objects, shuffle it. You assign the correctAnswerClick handler and the answer string to the first index (0) in that array. You assign the falseClick and wrong answers to index 1, 2 and 3. This way you always know that the correct button has the proper event handler.

The code below is what you want to achieve in Winforms (I don't have ASP installed in VS.Net atm) but it should be easily translated to ASP.Net I think.

button1 to button4 are named btn1 to btn4 in your case.

public partial class Form1 : Form
{

    private void Form1_Load(object sender, EventArgs e)
    {
        var btnns = new List<Button>();
        btnns.Add(button1);
        btnns.Add(button2);
        btnns.Add(button3);
        btnns.Add(button4);

        //Shuffle the list
        Shuffle<Button>(ref btnns);

        //Add an event handler for success to your first button
        btnns[0].Click += successClick;
        btnns[0].Text = "Correct";

        for (int i = 1; i < btnns.Count; i++)
        {
            btnns[i].Click += failedClick;
            btnns[i].Text = "Wrong " + i;
        }


    }
    private void failedClick(object sender, EventArgs e)
    {
        //Add a true value to the viewstate list
            AddAnswer(true);
    } 
    private void successClick(object sender, EventArgs e)
    {
        //Yay, it's correct
        AddAnswer(false);
    }
    public void AddAnswer(bool correctornot)
    {
           //I am not 100% sure about the code below (not tested), but it should give you an idea
           if (Session["listOfAnswers"] != null)
           {
                var currentList = (List<bool>) Session["listOfAnswers"];
                currentList.Add(correctornot);
                Session["listOfAnswers"] = currentlist;
           }
           else
           {
               var currentlist = new List<bool>();
               currentlist.Add(correctornot);
               Session["listOfAnswers"] = currentlist;
            }
    }
    public void Shuffle<T>(ref List<T> list)
    {
        Random rng = new Random();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }
}

Answer taken from here: Randomize a List<T>

Community
  • 1
  • 1
Christophe De Troyer
  • 2,852
  • 3
  • 30
  • 47
  • I think I understand what you are saying, is it... just assign the answer to whichever button, say the first button, then the other answers to the remaining 3, put them to an array then randomize the array of buttons? If I'm wrong then I'm already lost. Do you have an example? I know this may sound weird but I've rarely used arrays. – Chris Jan 17 '14 at 00:48
  • 1
    Well it's really not that hard. You have your btn1, btn2, btn3 and btn4. You add them to an array or a list. var btnList = new List – Christophe De Troyer Jan 17 '14 at 00:59
  • I'm going to try this out and I'll postback with how it worked out for me. Thanks – Chris Jan 17 '14 at 01:07
  • Yea, I'm lost. I'm with you to the point of creating the List – Chris Jan 17 '14 at 01:44
  • See my answer on how to shuffle your list. – Christophe De Troyer Jan 17 '14 at 01:55
  • I came across that thread, it was where I started to get confused. I'm going to look over the code throughout the night and get it working. – Chris Jan 17 '14 at 02:12
  • See my answer for a working versoin. I'm sorry I can't do it in ASp.net now though! – Christophe De Troyer Jan 17 '14 at 02:17
  • Thanks for hanging in there with me on this, it is greatly appreciated. I understand it better now that I see a working example of what I am needing to do. What I failed to mention is when the user selects their answer it goes directly to the next question and they don't see the result till after the quiz. So when they click on their answer, that's when I keep track of their answers, then it moves to the next question and set of 4 answers. But I see where I think I can manipulate the code. You've been a great help. No worries about not doing it in ASP.NET, its the same code :) – Chris Jan 17 '14 at 03:07
  • 1
    You can keep track of your questions in your ViewState. Suppose you have a list of 10 questions the user will fill in. You then create an array of length 10 (or a list) and save that in your ViewState. When the user clicks on a button (to answer a question) you can call a function in your event handlers (success and failure) which will pas a boolean to a function saveAnswer(bool correctornot). This will then add this value to the list in your viewstate. See answer for code. (Top of my head, so not sure if it will work) – Christophe De Troyer Jan 17 '14 at 03:47
  • Ok gotcha. I'm going to test this in the morning. This has helped me out a lot. I'm getting a good understanding of it. Thanks again. – Chris Jan 17 '14 at 04:16