ZaiFrost ZaiFrost - 24 days ago 10
C# Question

How do I not print the same option again?

I just learnt the basics of C# and now I'm trying to create a console MCQ that prints the questions in a random order and prints the options different every time the user takes the MCQ again. But the same options sometimes get printed together sometimes... Here is my code...

class Program
{
static void Wait(int sec)
{
Task.Delay(TimeSpan.FromSeconds(sec)).Wait();
}
static void printQn()
{
Questions mcq = new Questions();
Random gen = new Random();
//prints question 1
int optionCount = 1;
int x = gen.Next(5);
Console.WriteLine(mcq.questions[x]);
Wait(2);
mcq.questionsBool[x] = true;
//prints options
while (optionCount < 5)
{
int y = gen.Next(4);
if (mcq.optionsBool[x, y] == true)
{
int z = gen.Next(4);
Console.WriteLine("[" + optionCount + "]" + mcq.options[x, z]);
mcq.optionsBool[x, z] = true;
Wait(1);
optionCount++;
}
else if (mcq.optionsBool[x,y] == false)
{
Console.WriteLine("[" + optionCount + "]" + mcq.options[x, y]);
mcq.optionsBool[x, y] = true;
Wait(1);
optionCount++;
}
}
}

static void Main(string[] args)
{
printQn();
Console.ReadKey();
}

class Questions
{
public string[] questions =
{"Who was the first Queen of England?",
"What is the biggest island on Earth?",
"How many Grand Slam singles titles has Roger Federer won? ",
"When was the Euro introduced as legal currency on the world market? ",
"What year was the first Harry Potter movie released?"
};
public bool[] questionsBool = {false,false,false,false,false};
public string[,] options =
{ { "Queen Elizabeth I","Queen Mary I","Queen Anne" ,"Queen Matilda", },
{ "Hawaii" ,"Singapore" ,"Greenland" ,"Luzon ", },
{ "19" ,"17" ,"14" ,"15" , },
{ "Jan 1 1999" ,"Feb 1 1999" ,"Feb 13 1999","Feb 7 1998" , },
{ "2002" ,"1999" ,"2001" ,"2003" }};
public bool[,] optionsBool = { {false, false, false, false },
{false, false, false, false },
{false, false, false, false },
{false, false, false, false },
{false, false, false, false } };
}
}
}

Answer

I suggest you use this method for generating a list of integers in a randomized order (I have already implemented it in an extract of your code)

//create an enumerable containing the numbers 0,1,2,3 and randomize it
Random r = new Random();
int[] options = Enumerable.Range(0, 4).OrderBy(o => r.Next()).ToArray(); 

//prints options
foreach (int option in options)
{
     if (mcq.optionsBool[x, option] == true)  //replaced 'y' with 'option'
     {
          int z = gen.Next(4);
          Console.WriteLine("[" + optionCount + "]" + mcq.options[x, z]);
          mcq.optionsBool[x, z] = true;
     }
     else //there are only two possible outcomes(TRUE/FALSE) so use Else instead of ElseIf
     {
         Console.WriteLine("[" + optionCount + "]" + mcq.options[x, option]);
         mcq.optionsBool[x, option] = true;  
     }
     Wait(1);         //These two lines were present on
     optionCount++;   //both if and else, so I placed them outside
}

There are many things that can be improved /simplified on your code, I suggest you display your code in CodeReview, they will show you how to improve your code

EDIT: I couldn't help not improving your code, so here's how I'd do it:

    static void printQn()
    {
        Questions mcq = new Questions();
        Random r = new Random();

        //Randomize question indexes and grab first
        int[] questions = Enumerable.Range(0, mcq.questions.Length).OrderBy(q => r.Next()).ToArray();
        int question = questions.First();

        //Print first question
        Console.WriteLine(mcq.questions[question]);
        Wait(2);

        //Randomize option indexes (GetLength(1) will return the size of the 'y' dimension of the options array, so 4)
        int[] options = Enumerable.Range(0, mcq.options.GetLength(1)).OrderBy(o => r.Next()).ToArray(); 

        //prints options
        int optionCount = 1;
        foreach (int option in options)
        {
            Console.WriteLine("[{0}] {1}", optionCount, mcq.options[question, option]);
            Wait(1);
            optionCount++;
        }
    }

You still have to implement the part where you manage the response written by the user and contrast it with the optionsBool array to match if its the correct answer, but I'll leave that to you ;)