C#: quiz cu amestecare reproductibilă și identități stabile
Amestecă întrebările unui quiz C# fără să pierzi răspunsurile corecte. Folosește Fisher–Yates și o sămânță fixă pentru teste care pot fi reproduse.
În acest material
Amestecarea întrebărilor nu trebuie să rupă asocierea cu răspunsurile. Fiecare Question păstrează ID-ul, textul și răspunsul corect în același obiect. Algoritmul schimbă pozițiile obiectelor, fără să amestece separat textele și cheile. Pentru teste folosim aceeași sămânță a generatorului pseudoaleator.
Cum lucrezi cu exemplul
Programul complet folosește C# 7.3 și API-uri disponibile în .NET Framework 4.8. Deschide Lesson.csproj din arhivă sau creează un proiect Console App (.NET Framework 4.8) și înlocuiește Program.cs. Datele de demonstrație sunt incluse în cod.
Descarcă sursele și instrucțiunile.
Ideea și pașii de implementare
Fisher–Yates parcurge lista de la sfârșit spre început. La pasul i alege j între zero și i inclusiv și schimbă cele două elemente. Random.Next(i+1) are capătul din dreapta exclus, deci produce exact intervalul dorit. Lista este copiată înainte de amestecare pentru a păstra ordinea originală.
O sămânță fixă ajută reproducerea în același mediu de execuție. Nu promitem aceeași secvență Random pentru orice versiune de runtime. Testul robust verifică proprietățile: toate ID-urile apar o singură dată, perechile întrebare-răspuns rămân intacte și două rulări în același mediu, cu aceeași sămânță, coincid.
Exemplu și rezultat așteptat
Setul are întrebările cu ID-urile 10, 20 și 30. După amestecare, sortarea ID-urilor trebuie să dea tot 10, 20, 30. Pentru ID 20, răspunsul rămâne 3 indiferent de poziția nouă. Programul nu fixează o permutare particulară în rezultatul așteptat; afișează trei confirmări de proprietăți.
Question: ID + text + cheie → Fisher–Yates: schimbă obiecte → ID 20 își păstrează cheia 3 → Permutare, fără pierderi.Mărește schema ↗
Codul complet
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Globalization;
using System.Xml.Linq;
using System.Data;
class Question {public int Id;public string Text;public int Answer;}
class Program {
static List<Question> Shuffle(List<Question> source,int seed) {
var result=new List<Question>(source);var random=new Random(seed);
for(int i=result.Count-1;i>0;i--) {int j=random.Next(i+1);var temp=result[i];result[i]=result[j];result[j]=temp;}
return result;
}
static void Main() {
var source=new List<Question> {new Question {Id=10,Text="2+3",Answer=5},
new Question {Id=20,Text="Length [4,7,9]",Answer=3},new Question {Id=30,Text="4*2",Answer=8}};
var a=Shuffle(source,42);var b=Shuffle(source,42);
Console.WriteLine(a.Select(x=>x.Id).OrderBy(x=>x).SequenceEqual(new[]{10,20,30}));
Console.WriteLine(a.Single(x=>x.Id==20).Answer==3);
Console.WriteLine(a.Select(x=>x.Id).SequenceEqual(b.Select(x=>x.Id)));
}
}
Rezultatul programului:
True
True
True
Greșeli și limite
Nu sorta cu un comparator aleator: comparatorul nu mai respectă un contract coerent. Nu construi un Random nou pentru fiecare schimb. Nu amesteca lista în timpul răspunsului utilizatorului. Salvează ordinea sesiunii dacă vrei să poți reconstrui ulterior parcursul exact.
Exersează
Testează lista goală, un singur element și zece întrebări. Verifică unicitatea ID-urilor înainte de începerea sesiunii. Integrează funcția în miniaplicația quiz și păstrează obiectul curent, nu o cheie dintr-un vector neamestecat. Explică de ce schimbarea poziției nu trebuie să schimbe corectitudinea răspunsului.
Continuă parcursul
Parcursul complet de 50 de lecții
Lecția precedentă: C#: proiect catalog cu note și raport calculat
Lecția următoare: C#: proiect labirint cu BFS și drum desenat.
Referință: documentația Microsoft.
Întrebări frecvente
De ce amestec obiecte complete?
Pentru a păstra împreună identitatea, textul și răspunsul corect.
Next(i+1) poate întoarce i?
Da. Limita superioară este exclusă, deci valorile sunt de la zero la i.
Sămânța fixă garantează aceeași ordine pe orice runtime?
Nu este o promisiune universală. Testează proprietățile și fixează mediul când ai nevoie de reproducere exactă.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.