-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();
}
6
  • 3
    Please ask specific questions (multiple questions if necessary), not one of the "this doesn't work, please fix" type. Also please remove this goto. Commented Jan 29, 2013 at 17:17
  • 4
    OMG please don't use GOTO. That's the Devil himself Commented Jan 29, 2013 at 17:20
  • @ken2k .. I have update the question and do this ! :) Commented Jan 29, 2013 at 17:30
  • @HighCore .. what I can use instead of ?! Commented Jan 29, 2013 at 17:30
  • 1
    @user2022523 Flow Control Commented Jan 29, 2013 at 17:38

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

11 Comments

There are more efficient algorithm to shuffle a list. However, this solution can be quilcly implemented.
Less efficient, but more readable. Still don't understand why downvoted. Somebody don't know LINQ I suppose. Also I don't think 0.001 ms is a big deal here. Is it?
In this case, absolutely not. And I'm quite interested too to know why you've been downvoted.
@lazyberezovsky - Haha! I couldn't agree with you more! And, you are welcome.
@lazyberezovsky .. sure I will but I cant do this before "7 - hours" so sure I will :)
|
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;
    }
}

Comments

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];
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.