-5

Possible Duplicate:
Randomize a List<T> in C#

I want to make a program that ask the user 5 questions in random without duplicate the questions, and if the question is right go through the next question if wrong stop until he gave the right answer, and this is the code which I had written, but there are still some problems, like there are duplicate and when the user enter the wrong answer it only stop for one time, and then the program closed! now how can I prevent duplicate the same question, and if he enter wrong value don't proceed to the next question or the program closed?

static void Main()
{
    next:
    Random question = new Random();
    int x = question.Next(5);
    string[] array = new string[5];
    array[0] = "-What is the capital of France";
    array[1] = "-What is the capital of Spain";
    array[2] = "-What is the captial of Russia";
    array[3] = "-What is the capital of Ukraine";
    array[4] = "-What is the capital of Egypt";

    Console.WriteLine(array[x]);

    string[] answer = new string[5];
    answer[0] = "Paris";
    answer[1] = "Madrid";
    answer[2] = "Moscow";
    answer[3] = "Kiev";
    answer[4] = "Cairo";

    string a = Console.ReadLine();

    if (a == answer[x])
    {
        Console.WriteLine("It's True \n*Next Question is:");
        goto next;
    }
    else
        Console.WriteLine("It's False \n*Please Try Again.");

    Console.ReadLine();
}
Community
  • 1
  • 1
Bahinour
  • 11
  • 1
  • 1
  • 4

3 Answers3

3

You can shuffle indexes of asked question with LINQ

Random random = new Random();
var indexes = Enumerable.Range(0,array.Length).OrderBy(i => random.Next());

foreach(var index in indexes)
{
    Console.WriteLine(array[index]);
    do 
    {        
        string a = Console.ReadLine();

        if (a == answer[index]) {                
          Console.WriteLine("It's True\n");
          break;
        }

        Console.WriteLine("It's False \n*Please Try Again.");
    }
    while(true);
}

Explanation:

Enumerable.Range(0,array.Length) will return range of integer values starting from zero: 0, 1, 2, 3, 4. Next those numbers will be sorted by random number (i.e. shuffled). It could result in any combination of those numbers, e.g. 3, 0, 1, 4, 2.


BTW it's good to go OOP way and put related data (question text and answer) and logic (defining if answer is correct) into one place:

public class Question
{
    public string Text { get; set; }
    public string Answer { get; set; }

    public bool IsCorrect(string answer)
    {
        return String.Compare(answer, Answer, true) == 0;
    }
}

With this question class all your code will be more readable:

var questions = new List<Question>()
{
    new Question { Text = "What is the capital of France?", Answer = "Paris" },
    new Question { Text = "What is the capital of Spain?", Answer = "Madrid" },
    new Question { Text = "What is the capital of Russia?", Answer = "Moscow" },
    new Question { Text = "What is the capital of Ukraine?", Answer = "Kiev" },
    new Question { Text = "What is the capital of Egypt?", Answer = "Cairo" }
};

Random random = new Random();

// randomizing is very simple in this case
foreach (var question in questions.OrderBy(q => random.Next()))
{
    Console.WriteLine(question.Text);

    do
    {
        var answer = Console.ReadLine();
        if (question.IsCorrect(answer))
        {
            Console.WriteLine("It's True");
            break;
        }

        Console.WriteLine("It's False. Please try again.");
    }
    while (true);
}

Next step for you is implementing Survey class, which will hold question asking, reading answers and displaying summary.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
3

Do not use goto unless it is absolutely necessary.

public class Program
{
    private static List<KeyValuePair<string, string>> questions = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string,string>("-What is the capital of France", "Paris"),
        new KeyValuePair<string,string>("-What is the capital of Spain", "Madrid"),
        new KeyValuePair<string,string>("-What is the captial of Russia", "Moscow"),
        new KeyValuePair<string,string>("-What is the capital of Ukraine", "Kiev"),
        new KeyValuePair<string,string>("-What is the capital of Egypt", "Cairo"),
    };

    static void Main()
    {
        var questions = ShuffleQuestions();

        foreach(var question in questions)
        {
            bool done = false;
            while(!done)
            {
                Console.WriteLine(question.Key);
                string a = Console.ReadLine();

                if (a == question.Value)
                {
                    Console.WriteLine("It's True \n*Next Question is:");
                    done = true;
                }
                else
                    Console.WriteLine("It's False \n*Please Try Again.");
            }
        }

        Console.ReadLine();
    }

    private IEnumerable<KeyValuePair<string, string>> ShuffleQuestions()
    {
        var list = questions;
        var random = new Random();  
        int items = list.Count;  
        while (items > 1) {  
            items--;  
            int nextItem = random.Next(items + 1);  
            var value = list[nextItem];  
            list[nextItem] = list[items];  
            list[items] = value;  
        }

        return list;
    }
}
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
2

You could create a shuffled array of integers that represent the order to ask the questions in:

// Create question order
var order = Enumerable.Range(0, array.Length).ToArray();
for (int i = order.Length - 1; i > 1; --i)
{
    var randomIndex = rnd.Next(i);
    var temp = order[randomIndex];
    order[randomIndex] = order[i];
    order[i] = temp;
}

// Ask the questions in shuffled order
foreach(int questionIndex in order)
{
    Console.Write(array[questionIndex]);
    bool answeredCorrectly = Console.ReadLine() == answer[questionIndex];
}
itsme86
  • 19,266
  • 4
  • 41
  • 57