【问题标题】:How do I not print the same option again?如何不再打印相同的选项?
【发布时间】:2016-11-16 10:38:48
【问题描述】:

我刚刚学习了 C# 的基础知识,现在我正在尝试创建一个控制台 MCQ,它以随机顺序打印问题,并在每次用户再次使用 MCQ 时打印不同的选项。但有时相同的选项有时会打印在一起......这是我的代码......

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

【问题讨论】:

  • 你正在生成一个随机数,下一次迭代,可以再次生成相同的数字。你尝试过什么来规避它?有两个选项:记住您已经使用过哪些选项,如果再次出现使用过的选项,则生成另一个数字,这可能会证明很麻烦和/或显示,或者改为将选项列表随机化一次。
  • @CodeCaster 你是对的......我想到了,但是如果当我生成另一个数字时,又会生成相同的数字怎么办?我该如何解决这个问题?如果没有,我如何将选项列表随机化一次?

标签: c# console-application options


【解决方案1】:

我建议您使用此方法以随机顺序生成整数列表(我已经在您的代码摘录中实现了它)

//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
}

你的代码有很多可以改进/简化的地方,我建议你在 CodeReview 中展示你的代码,他们会告诉你如何改进你的代码

编辑:我忍不住不改进你的代码,所以我会这样做:

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

您仍然必须实现管理用户编写的响应的部分,并将其与 optionsBool 数组进行对比,以匹配其正确答案,但我将把它留给您 ;)

【讨论】:

  • 感谢您的帮助和提示!
  • 再次感谢!我只是想问一下(我是C#新手,这是我学的第一门编程语言),.First()函数什么时候使用?
  • @ZaiFrost 当您想要检索集合的第一个元素时,您可以通过索引(例如 myarray[0])或自定义 来实现。 First() 属性(输出相同)。此属性还有一个类似的扩展名为 .FirstOrDefault(),如果数组为空,它将避免生成异常(类似地,myarray[0] 将在以下情况下生成索引错误该数组不包含任何元素)。使用一个或另一个,取决于你,我只是觉得它在视觉上更干净
  • 另请注意,使用这个(非常好的)解决方案,您不需要 questionsBooloptionsBool 数组(为什么 Questions 类应该具有此属性?)。此外,如果您将 Questions 类替换为结构更好的类(我正在考虑包含问题和可用答案列表的类 Question),代码可能会进一步改进
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多