2

I'd like to start by stating that I am very, very new to programming and to stack overflow. I've tried to find an answer to my question, but none of them made since to me (or they didn't work for me). I am currently learning c#, and am testing what I've learned thus far by creating a "quiz" program. I got it to working, but then noticed a very large flaw, each question could sometimes have two "accurate" answers (note - this is not supposed to be). I found that my problem was that when my program checked the selected answer, it would pick a new random question and check if the selected radio button was the correct answer. Hope that made sense. :) I've been trying to figure this out, and decided it was time to come here. (I realize it is probably a duplicate, but the "duplicates" didn't help me at all) What am I doing wrong?

Here is the code I've created thus far:

namespace The_Q_and_A_Program
{
    public partial class QuestionForm : Form
    {
        public QuestionForm()
        {
            InitializeComponent();
            InitializeQuestions();
            GetQuestion();
            AssignValues();
            GetAnswer();
        }

        int NumQuestionList;
        public static Random RandomNum = new Random();
        public List<question> QuestionList = new List<question>();
        public string CurrentAnswer;
        public bool Op1IsTrue = false;
        public bool Op2IsTrue = false;
        public bool Op3IsTrue = false;
        public bool Op1Checked = false;
        public bool Op2Checked = false;
        public bool Op3Checked = false;
        public question RandomQuestion;

        public void InitializeQuestions()
        {
            question Q1 = new question("What was the only NFL team in history to play a 'Perfect Season', ending in a Superbowl win?", "Miami Dolphins", "New England Patriots", "Green Bay Packers", "Miami Dolphins");
            QuestionList.Add(Q1);
            question Q2 = new question("What NFL team won both Super Bowl I and Superbowl II?", "Denver Broncos", "Green Bay Packers", "New England Patriots", "Green Bay Packers");
            QuestionList.Add(Q2);
        }

        public void GetQuestion()
        {
            NumQuestionList = QuestionList.Count;
            RandomQuestion = QuestionList[RandomNum.Next(0, NumQuestionList)];
        }

        public void GetAnswer()
        {
            CurrentAnswer = RandomQuestion.Answer;

            if (CurrentAnswer == RandomQuestion.Op1)
            {
                Op1IsTrue = true;
            }

            else if (CurrentAnswer == RandomQuestion.Op2)
            {
                Op2IsTrue = true;
            }

            else if (CurrentAnswer == RandomQuestion.Op3)
            {
                Op3IsTrue = true;
            }
        }

        public void AssignValues()
        {
            QuestionLabel.Text = RandomQuestion.Question;
            Op1RadButton.Text = RandomQuestion.Op1;
            Op2RadButton.Text = RandomQuestion.Op2;
            Op3RadButton.Text = RandomQuestion.Op3;
        }

        public void CheckAnswer()
        {
            Op1Checked = Op1RadButton.Checked;
            Op2Checked = Op2RadButton.Checked;
            Op3Checked = Op3RadButton.Checked;

            if (Op1Checked == true & Op1IsTrue == true)
            {
                MessageBox.Show("Congratulations! You are correct!");
            }

            else if (Op2Checked == true & Op2IsTrue == true)
            {
                MessageBox.Show("Congratulations! You are correct!");
            }

            else if (Op3Checked == true & Op3IsTrue == true)
            {
                MessageBox.Show("Congratulations! You are correct!");
            }

            else
            {
                MessageBox.Show("Sorry, But that is incorrect.");
            }
        }

        private void CheckButton_Click(object sender, EventArgs e)
        {
            CheckAnswer();
        }

        private void NextButton_Click(object sender, EventArgs e)
        {
            GetQuestion();
            AssignValues();
            GetAnswer();
        }  
    }
}

Here is the "question" class code:

public class question
{
    public string Question;
    public string Op1;
    public string Op2;
    public string Op3;
    public string Answer;

    public question(string questionString, string op1, string op2, string op3, string answer)
    {
        Question = questionString;
        Op1 = op1;
        Op2 = op2;
        Op3 = op3;
        Answer = answer;
    }
}

I guess another way to put this question is: How can I use the RandomQuestion without picking a new random question every time?

Edit: The way I stated my question to begin with was incorrect (refer to my comments with Jason Faulkner for more info).

Edit 2: The difference between this question and others is: I was stupid and they weren't :)

Ethan
  • 249
  • 1
  • 2
  • 10

1 Answers1

3

How can I use the RandomQuestion without picking a new random question every time?

Since you already have your questions defined when you initialize the program, you just need to remove the selected/already displayed questions from the queue as you move along:

public void GetQuestion()
{
    NumQuestionList = QuestionList.Count;
    RandomQuestion = QuestionList[RandomNum.Next(0, NumQuestionList)];

    // Once question has been selected, remove it from the list.
    // This way it will not be selected again.
    QuestionList.Remove(RandomQuestion)
}

You will then need to make sure there are questions still available in the queue:

private void NextButton_Click(object sender, EventArgs e)
{
    if (QuestionList.Count == 0)
    {
        MessageBox.Show("No more questions.");
    }
    else
    {
        // Get next question.
        GetQuestion();
        AssignValues();
        GetAnswer();
    }
} 

Note there is a logic error in that Op[x]IsTrue variables are global but you never reset them. So essentially once set to true, it will always be true (which will cause incorrect answers to show as correct). You can correct this here:

public void GetAnswer()
{
    // Reset answer flags.
    Op1IsTrue = false;
    Op2IsTrue = false;
    Op3IsTrue = false;

    CurrentAnswer = RandomQuestion.Answer;

    // Checks below will set the correct option.
    ...
Jason Faulkner
  • 6,378
  • 2
  • 28
  • 33
  • @Ethan - Not sure what you mean here... Once you have pulled the question out of the list, it is then removed from the list so it cannot possibly be selected again. – Jason Faulkner Jan 10 '15 at 19:17
  • Not sure how to explain this. I'm not having a problem with selecting the same question twice (in fact I want that to happen). My problem comes when checking the user's answer. The question displayed on the screen may or may not be the question the CheckAnswer is using to check the user's answer (quite confusing I know). – Ethan Jan 10 '15 at 19:23
  • For example : Q1 is selected. The user selects Op2RadButton (New England Patriots), which is incorrect. He clicks the check button. As the program checks the answer it randomly selects Q2 and gets its answer. It is Op2RadButton. Thus the user's selection is incorrect, but the program sees it as correct. – Ethan Jan 10 '15 at 19:27
  • @Ethan - I see (BTW, that is not what your question was asking). I think what you are needing to do is in `GetAnswer`, to reset the `Op[x]IsTrue` variables to false (so only the current question is considered). `Op1IsTrue = false; Op2IsTrue = false; Op3IsTrue = false;`. Otherwise once you set one to true, it never is reset to false. – Jason Faulkner Jan 10 '15 at 19:29
  • Sorry for the miscommunication on what I was asking (I wasn't for sure how to ask). Give me a minute to try that. :) – Ethan Jan 10 '15 at 19:30
  • @Ethan - I updated the answer with this information. – Jason Faulkner Jan 10 '15 at 19:32
  • Finally got it! Thank you for your help! :) I can finally move on – Ethan Jan 10 '15 at 19:36
  • @Ethan - Glad to help. Good luck with your project. – Jason Faulkner Jan 10 '15 at 19:40
  • Using System.Random for selecting Random data, this is a Pseudo Random number which doesn't work most of the time, functionality will break under stress, here the seed is not truly random. You can use System.Cryptography APIs for true randomness, check link below, it explains the concept in details. http://csharpindepth.com/Articles/Chapter12/Random.aspx – Mrinal Kamboj Jan 10 '15 at 20:07
  • @JasonFaulkner - Looks like I need to work on my debugging skills :) – Ethan Jan 12 '15 at 20:37