2013-11-25 57 views
0

我们一直负责设计C#应用琐事的文件I/O活动。到目前为止,我已经有了一个好的开始,但是演示步骤有点让我困惑。设计一个简单的控制台应用程序琐事

我开始了分隔的文件特色的以下数据:

Question;CorrectAnswerA;AnswerB;AnswerC;AnswerD;AnswerExplanation 

例如,

What color is the sky?;Blue;White;Green;Yellow;The sky is blue. 

游戏会显示问题和四个答案来自用户可以选择。

What Color is the Sky? 
A. Blue 
B. White 
C. Green 
D. Yellow 

Select A, B, C, or D: 

不幸的是,为便于填充数据集,A总是正确的答案。我想随机其中四个答案的显示顺序,但该程序仍需要知道哪个是正确答案。我还需要将用户输入AB,CD与回答的特定实例绑定以将selectedAnswerStringcorrectAnswerString进行比较。

我一直在玩与随机填充四个答案的数组,但我不能换我周围的头怎么标志的东西是正确的根据用户的选择;我的逻辑做或分配总是似乎超出范围或在数组中的所有四个记录重复。

我已经说过了

其他学生说,他们创建了数据集与答案加扰的预(这样他们可以打印出来的顺序读取)与正确答案第五答案场。虽然绝对是一种简单的方法来实现它,但我认为它不如我的策略那么优雅。

如果我只是改变输入数据集?有没有人有任何想法来追求我的随机化想法?使用一个单独的变量正确答案的

回答

0

跟踪。然后使用Fisher-Yates洗牌您的数组:用户响应

Random random = new Random(); 

void Shuffle(string[] answers) { 
    for (int i = 0; i < answers.Length - 1; i++) { 
     int j = random.Next(i, answers.Length); 
     string temp = answers[j]; 
     answers[j] = answers[i]; 
     answers[i] = temp; 
    } 
} 

后,只需比较其与选择您已经保存了正确的答案。

+0

我如何跟踪用户的选择和答案? 'switch'是管理'A'的最好方式是'answers [1]',''B''''''等等。还是有更好的策略? – dwwilson66

+0

@ dwwilson66这很好,但您需要记住数组从零开始索引。你可以使用'answers [selectedChar - 'A']',这会给你'A = 0,B = 1,...'。 – Zong

+0

它早...没有咖啡。 :) 我知道。 – dwwilson66

1

创建一个名为Question与属性的类:int Idstring QuestionTextList<string> Answersstring CorrectAnswer

或者,如向前迈出一步,也创造了AnswerIdValue和引用。

public class Question 
    { 
     public int Id; 
     public string QuestionText; 
     public List<Answer> Answers; 
     public Answer CorrectAnswer; 
    } 

    public class Answer 
    { 
     public int Id; 
     public string Value; 
    } 

然后填充这个结构,随机打印

0

尝试定义你的数据结构的问题,在这样的时候:

public class Question 
{ 
    public string Question; 
    public string[] Answers; 
    public int CorrectAnswer; 
    public string CorrectAnswerExplanation 
} 

这样你可以打乱字符串数组Answers中,同时仍在跟踪CorrectAnswer中正确答案的索引。或者,如果你不能使用单独的类来模拟问题(这是一个家庭作业问题,所以你可能还没有学到这个),你可以使用数组中的预定位置(第1个或第5个元素)保存正确答案的索引。因此,您的答案阵列如下所示:

"Blue", "White", "Green", "Yellow", "0" 
+0

我们已经学会了如何使用单独的课程......但是我所说的其他所有学生都在他们的数据集中使用了一个字段来保存正确的答案标记。就我个人而言,我认为这打破了可重用性的目的,并且我试图避免对可以以编程方式确定的任何东西进行硬编码。我的导师和我在整个学期都在关于对象或数据结构需要或应该如何通用的问题。但这是人际关系--overflow.com的主题。 ;) – dwwilson66

0

第1步:定义数据结构。其他人已经给你一个结构以便使用它。

步骤2:填充您的数据结构。你可以System.IO.File.ReadLines和解析每一行 - 我假设你已经处理了这一点。

第3步:随机化您的答案的顺序。对于这一点,假设你有你的结构:

public static void RandomiseAnswers(IEnumerable<Question> questions) 
{ 
    var rand = new Random((int)DateTime.Now.Ticks); 
    foreach (var question in questions) 
    { 
     question.Answers = question.Answers.OrderBy(x => rand.Next()).ToArray(); 
    } 
} 

第4步:收到金星从老师为你出色的工作

+0

我希望。她是为我们提供的UML添加方法的码头。但我喜欢这个......只是为了惹她。我有一个关于这一行的问题:'var rand = new Random((int)DateTime.Now.Ticks);'它是使用当前时间作为种子随机化的吗?我不熟悉它的'.Ticks'部分,现在就来看看MSDN吧。 :) – dwwilson66

+0

@ dwwilson66:是的,你是正确的 – Ben

0

个人而言,我会把一个布尔值在应答类默认为false。这样,当答案被选中时,你可以阅读它是否正确。

public class AskQuestion 
{ 
    public int Id; 
    public string Question; 
    public string Explanation; 
    public List<Answer> Answers = new List<Answer>(); 
} 

public class Answer 
{ 
    public bool Correct = false; 
    public string Value; 
} 

现在当你随机列表中选择正确答案自动识别使用这些类会是这样

方式一:

static void Main(string[] args) 
    { 
     StreamReader sr = new StreamReader("text.txt"); 
     List<AskQuestion> Questions = new List<AskQuestion>(); 
     Random rnd = new Random(DateTime.Now.Millisecond); 
     //Loop through the file building a list of questions 
     while(!sr.EndOfStream) 
     { 
      AskQuestion NewQuestion = new AskQuestion(); 
      string[] input = sr.ReadLine().Split(';'); 
      NewQuestion.Question = input[0]; 
      NewQuestion.Explanation = input[5]; 
      for(int i = 1; i < 5; i++) 
      { 
       Answer NewAnswer = new Answer(); 
       NewAnswer.Value = input[i]; 
       NewQuestion.Answers.Add(NewAnswer); 
      } 
      //The first question is always correct so set its boolean value to true; 
      NewQuestion.Answers[0].Correct = true; 
      //Now ranmdomize the order of the answers 
      NewQuestion.Answers = NewQuestion.Answers.OrderBy(x => rnd.Next()).ToList(); 
      Questions.Add(NewQuestion); 
     } 
     //Generate menu and get response for each question 
     foreach(AskQuestion q in Questions) 
     { 
      Console.WriteLine(q.Question + ":\n\tA - " + q.Answers[0].Value + "\n\tB - " + q.Answers[1].Value + "\n\tC - " + q.Answers[2].Value + "\n\tD - " + q.Answers[3].Value + "\n"); 
      char input = '0'; 
      while(input < 'A' || input > 'D') 
      { 
       input = char.ToUpper(Console.ReadKey().KeyChar); 
       if(input >= 'A' && input <= 'D') 
       { 
        //Use the boolean value in the answer to test for correctness. 
        if(q.Answers[input - 'A'].Correct) 
        { 
         Console.WriteLine("\nCorrect\n"); 
        } 
        else 
         Console.WriteLine("\nWrong\n"); 

        Console.WriteLine(q.Explanation); 
       } 
      } 
     } 
     Console.ReadLine(); 
    } 
+0

那么这样的答案不能在不同的问题中重复使用。 – Nogard

+0

每个问题都有自己的答案列表。重新使用不同问题的答案没有多大意义。该类的每个实例都有自己的字符串和布尔值。 – tinstaafl

+0

“它自己的答案列表” - 真,但是“唯一答案列表” - 不是必须的,因为可能存在“真/假”问题或诸如“2^3 =”或“字节中有多少位”等问题。这不是必然性,而是一种可能性,在这种情况下,重用已经存在的答案比创建新的重复项更明智 – Nogard

相关问题