O Programu / Teorijska podloga
Tok izvršavanja programa možemo podeliti na sledeće logičke celine:
- Generisanje vrednosti
- Unos podataka
- Obrada i prikaz rezultata
Generisanje vrednosti
Ono na šta posebno treba obratiti pažnju je samo generisanje podataka, tačnije sčučajnih brojeva.Obzirom da su kompjuteri deterministički uređaji, svaki pokušaj kreiranja generator slučajnih brojeva je teorijski nemoguć.
Svaka situacija gde nam se traži slučajni broj predstavlja problem.
Problem potrebe slučajnih brojeva rešavamo uvođenjem funkcija generatora pseudo-slučajnih brojeva, koji generišu nizove ovakvh brojeva.
Iako se zna da se ovi brojevi posle izvesnog vremena ponavljaju, ovo nam ne predstavlja prevelik problem, obzirom da su periode njihovih ponavljanja poprilično velike, kod novijih generatora.
Na primer, generator u jeziku PHP, u kome je najvećim delom i napisan ovaj program, perioda ponavljanja je 2219937.
Algoritam koji stoji iza ovog generatora se zove Mersenov tvister.
Kako bi izbegli slučajno ponavljanje pitanja u kvizu, koje bi remetilo realnost ocene, brojeve ne generišemo nasumično.
Brojevi su generisani kao niz od 1 do 20, koliko pitanja i imamo, a zatim ih "mešamo".
Mešanje niza vrši funkcija shuffle() koja se oslanja na Mersenov tvister.
Obzirom da u nizu imamo 20 pitanja, iz njega "odsecamo" poslednjih 10, kako bi smo ga sveli na 10 traženih nasumično odabranih pitanja.
Nasumičnost mogućih odgovora za svako pitanje se postiže mešanjem odgovora u samom SQL upitu ključnim rečima
ODRED BY RANDOM()
.Iza funkcije RANDOM(), koja je ugrađena u MYSQL server na koji se program oslanja, takođe stoji Mersenov tvister.
Nakon što je niz brojeva generisan, pretvaramo ga u String, i kao takav zapisujemo u COOKIE na računaru korisnika.
Mersenov tvister
Na osnovu metoda koji koriste, softveri za generisanje pseudoslučajnih brojeva se mogu podeliti na:- Linearni kongruentni generator- linearni generator slučajnih brojeva
- Fibonačijevog generator- dobili su ime zbog sličnosti formule koju koriste sa formulom koja se koristi za dobijanje Fibonačijevog niza
- Generator linearno pomerajućeg registra - brojevi se ne dobijaju aritmetičkim već logičkim operacijama
On spada pod generatore linearno pomerajućeg registra Frobeniusove (racionalne) normalne forme. Karakterizuje ga:
- w – dužina reči
- n – nivo rekurzije
- m – srednja reč 1≤m≤n
- r – mesto razdvajanja reči – broj bitova u donjoj bitmasci 0≤r≤w-1
- a – koeficijent Frobeniusove (racionalne) normalne forme matrice
- b,c – bitmaske za algoritme ovog tipa
- s,t – pomaci bitova
- u,l – dodatni Mersen tvister pomaci bitova
Ono što je najvažnije kod ovog algoritma da za reč dužine k generiše brojeve sa skoro uniformnom raspodelom u opsegu [0,(2k− 1)].
Implementacija algoritma:
// Create a length 624 array to store the state of the generator
int[0..623] MT
int index = 0
// Initialize the generator from a seed
function initializeGenerator(int seed) {
MT[0] := seed
for i from 1 to 623 { // loop over each other element
MT[i] := last 32 bits of(1812433253 * (MT[i-1] xor (right shift by 30
bits(MT[i-1]))) + i) // 0x6c078965
}
}
// Extract a tempered pseudorandom number based on the index-th value,
// calling generateNumbers() every 624 numbers
function extractNumber() {
if index == 0 {
generateNumbers()
}
int y := MT[index]
y := y xor (right shift by 11 bits(y))
y := y xor (left shift by 7 bits(y) and (2636928640)) // 0x9d2c5680
y := y xor (left shift by 15 bits(y) and (4022730752)) // 0xefc60000
y := y xor (right shift by 18 bits(y))
index := (index + 1) mod 624
return y
}
// Generate an array of 624 untempered numbers
function generateNumbers() {
for i from 0 to 623 {
int y := 32nd bit of(MT[i]) + last 31 bits of(MT[(i+1) mod 624])
MT[i] := MT[(i + 397) mod 624] xor (right shift by 1 bit(y))
if (y mod 2) == 1 { // y is odd
MT[i] := MT[i] xor (2567483615) // 0x9908b0df
}
}
}
Unos podataka
Sam unos podataka se vrši jednostavnim klikom na ispravan odgovor.Pitanja se korisniku postavljaju onim redom kojim su zapisana u kolaču na korisnikovom kompjuteru.
Klikom na tačan odgovor se pokreće JavaScript koji zapisuje korisnikove odgovore u novi kolač, koji će kasnije php obraditi prilikom računanja ocene.
Nakon toga se to pitanje izbacuje iz niza postavljenih pitanja, kako ga ne bi smo ponovo postavili.
Obrada i prikaz podataka
Nakon što je korisnik odgovorio na sva pitanja koja su mu postavljena, poziva se PHP skript koji iz kolača čita korisnikove odgovore, i poredi ih sa odgovorima koji su u bazi naznačeni kao tačni.Skripta korisniku ispisuje da li je odgovor tačan ili ne, i nudi mogućnost prikaza tačnog odgovora sa detaljnim objašnjenjem.
Nakon obrada svih postavljenih pitanja, i dobijenih odgovora, korisniku se prikazuje i ocena koju je zaslužio, kao i mogućnost da pokrene novi test.