2012-02-13 2 views
-1

Je suis assez nouveau à la programmation C# si nue avec moi. J'ai lu de nombreuses questions déjà postées sur le site mais je n'arrive pas à en voir une qui pose le même problème et je crois qu'il pourrait y avoir une approche plus simple.Créer un ordre aléatoire pour mes questions de quiz

J'ai créé une application de test et utilisais une instruction switch pour trouver les réponses aux questions. c'est-à-dire aller de 1 à 2 à 3 à 4 et ainsi de suite. Cependant, une fois que l'utilisateur a terminé le questionnaire une fois et a voulu recommencer, il devra recommencer toutes les mêmes questions. (La conception est que si elles se trompent, l'application se termine). Par conséquent, je voulais voir s'il y avait un moyen de randomiser le nombre pour le QuestionCount (mais seulement avoir ce nombre généré une fois) ou d'une autre façon que je pouvais le faire. Je peux voir qu'il y a des suggestions dans l'utilisation d'une liste mais celles-ci semblent se concentrer sur les grands nombres contenus dans la liste alors que la mienne ne comportera actuellement que 20 questions.

J'ai copié le code que j'utilise actuellement.

private void Verify(int Question) 
{ 
    switch (Question) 
    { 
     case 1: 
      if (checkBox1.Checked && !checkBox2.Checked && !checkBox3.Checked && !checkBox4.Checked) 
      { 
       MessageBox.Show("Correct - Well Done"); 
       //This was a test to see if I could assign a random number which works but the number could then appear again meaning the user gets the same question 
       Random random = new Random(); 
       QuestionCount = random.Next(0, 21); 
       QuestionSelection(QuestionCount); 
       //SelectLabel(QuestionCount); 
       ClearcheckBox(); 
      } 
      else 
      { 
       MessageBox.Show("No - It was Sunguard"); 
       Application.Exit(); 
      } 
      break; 
     case 2: 
      if (checkBox3.Checked && !checkBox2.Checked && !checkBox1.Checked && !checkBox4.Checked) 
      { 
       //this method was the original where it just adds 1 to QuestionCount and works it way through the switch statement for the questions. 
       MessageBox.Show("Correct - Well Done"); 
       QuestionCount++; 
       QuestionSelection(QuestionCount); 
       //SelectLabel(QuestionCount); 
       ClearcheckBox(); 
      } 
      else 
      { 
       MessageBox.Show("No - It's to look at a students details"); 
       Application.Exit(); 
      } 
    } 
} 
+0

Le mot clé que vous recherchez est "aléatoire". Autrement dit, pour réorganiser au hasard une liste sans remplacement. Vous voulez mélanger une liste de questions (dans votre code, les questions semblent juste être identifiées par 'int's, donc une liste de' int's). – perelman

Répondre

1

Pourquoi ne pas mettre toutes les questions dans une liste, et mélangez-le:

public List<T> RandomPermutation<T>(List<T> array) 
{ 
    Random random = new Random(); 
    List<T> retArray = new List<T>(array); 

    int maxIndex = array.Count - 1; 

    for (int i = 0; i <= maxIndex; i++) 
    { 
     int swapIndex = random.Next(i, maxIndex); 
     if (swapIndex != i) 
     { 
      T temp = retArray[i]; 
      retArray[i] = retArray[swapIndex]; 
      retArray[swapIndex] = temp; 
     } 
    } 
    return retArray; 
} 
1

Pour vous assurer que chaque question est seulement demandé une fois j'utiliser deux listes: AnsweredQuestions et UnansweredQuestions.

Au début AnsweredQuestions est vide, UnansweredQuestions contient toutes les questions à poser. Maintenant vous pouvez vous le randomizer comme vous l'avez déjà dans votre code ci-dessus. Comme le vlaue max pour le random.Next() vous prenez l'article actuel Count de la liste UnansweredQuestions.

Après avoir répondu correctement à la question, vous pouvez la supprimer de la liste UnansweredQuestions et la placer dans la liste AnsweredQuestions. De cette façon, votre randomizer utilise uniquement les questions qui sont vraiment sans réponse.

+0

Merci pour les suggestions. Est-ce que cela fonctionnera toujours avec mes questions étant également dans une déclaration de commutateur. QuestionSelection private void (int intQuestionNo) { interrupteur (intQuestionNo) { Cas 1: labelQuestion.Text = "Qui a fait Bannière"; checkBox1.Texte = "Sungard"; checkBox2.Text = "McDonalds"; checkBox3.Text = "Asda"; checkBox4.Text = "Apple"; pause; Essayer de mettre ces questions dans une liste avec les réponses checkbox.text pourrait s'avérer une bonne tâche? – jamesc100

+0

Désolé, obtenir le code dans la boîte de commentaire n'est pas génial et comme je suis un nouvel utilisateur, je ne peux pas créer un nouveau poste pour un autre 8 heures – jamesc100

+0

@ user1206484: Je ne prendrais pas cette approche du tout parce que c'est très non flexible. Que feriez-vous si vous deviez changer le nombre de questions à, disons, 50 ou 1000? Que diriez-vous de ceci: Le nombre aléatoire est l'index de votre question dans la liste 'UnansweredQuestions'. La question que fournit chaque réponse et la bonne solution en tant que propriétés. Vous pouvez ensuite fournir la question à une méthode qui affecte ces propriétés aux CheckBoxes appropriées. En faisant cela, vous obtenez une approche flexible qui ne se soucie jamais du nombre de questions que vous avez. –

0

Si vous avez seulement un petit nombre de valeurs possibles, vous pouvez encoder les choix comme des drapeaux de bit dans un Uint64. J'ai ajouté un exemple ci-dessous qui le fait. J'utilise un BitArray pour plus de commodité. Il serait préférable d'utiliser bits-sage & et | les opérateurs. Le résultat est empaqueté dans un UInt64, mais il aurait aussi bien pu être deux Uint32 séparés pour les drapeaux et la valeur.

private static UInt64 Next(UInt64 current, int questions) 
{ 
    // Convert the current value to an array of bytes. 
    // Remove the least significant 4 bytes. 
    // and then create a flag array. 
    var bytes = BitConverter.GetBytes(current); 
    bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0; 
    var flags = new BitArray(bytes); 

    // If all questions has been answered then exit with 0. 
    var all = Enumerable.Range(32, questions).All(flags.Get); 
    if (all) 
     return 0UL; 

    // Make a random next value, if the value has been used then repeat. 
    var random = new Random(DateTime.Now.Millisecond); 
    var next = random.Next(questions); 
    while (flags.Get(next + 32)) 
     next = random.Next(questions); 

    // set the flag value for the guess. 
    flags.Set(next + 32, true); 

    // convert the flags back to Uint64 and add the next value. 
    flags.CopyTo(bytes, 0); 
    return BitConverter.ToUInt64(bytes, 0) + Convert.ToUInt64(next); 
} 

Test avec:

var first = Next(0UL, 20); 
while (first != 0UL) 
{ 
    var v = first & 0xFFFFFFFF; 
    Console.Out.WriteLine(v); 
    first = Next(first, 20); 
} 
Questions connexes