Fezten

onsdag 10 november 2010

Om EonGen, och faran med att hamna på sidospår

Som jag nämnde tidigare idag, har jag arbetat på min Eon-generator. Efter att ha börjat fnula på en OB-tärningsfunktion, så började jag glatt att inleda mitt arbete med att göra en tärnings-modul.
 
Man kan ju undra vad nyttan skulle vara att göra en sådan modul, om jag nu egentligen vill göra en karaktärs-generator. Men tanken är att den ska innehålla flera vettiga funktioner som jag kan återinvända flera gånger, i flera olika program. På så sätt tänker jag att jag ska spara en hel del tid och besvär genom att inte återuppfinna hjulet hela tiden..

Nå, världen är inte så enkel. För när jag satte igång med arbetet med modulen, la jag först in den funktion jag gjort tidigare som slog 1T6. Sedan la jag till funktionen jag gjort tidigare som slog 3T6. Tanken var att den senare skulle kunna slå ett godtyckligt antal T6, beroende på vad användaren behöver.

Nå, en sak jag började fundera på var följande:

Jag har hittills använt funktionen randint(x,y), från modulen random. random.randint(x,y) returnerar nämligen x antal y-sidiga tärningar. Men hur random är egentligen random? Jag vet sedan tidigare att  om det något som är krångligt att göra på en dator så är det att fixa bra slumptal och liknande. Den enda gången jag själv tidigare har hittat ett interface för slumpgenerator som jag kunnat använda själv till något, var på den tiden jag fortfarande sysslande med mIRC-script (tidigt 00-tal). Där fanns en funktion som läste en slumpmässigt utvald rad ur en textfil, och jag använde den till att skicka slumpmässiga förolämpningar till folk. Jag vet inte ens hur tillförlitlig den funktionen var som slumpgenerator, men jag kunde i alla fall använda den.

Så jag bestämde mig för att testa hur bra random.randint är på att faktiskt slumpa. Jag kom fram till att det bästa sättet jag kunde komma på att göra detta, var att lista ut hur stor chansen är att tre tärningsslag resulterar i tre sexor. Sedan slår man tärningen en ohygglig massa gånger, och räknar ut hur ofta random.randint ger mig tre sexor av tre möjliga, i genomsnitt. Sedan jämför jag kollar jag hur nära de två olika sakerna ligger varandra. Det behövs en massa slag för att testet ska vara värt någonting.

Sagt och gjort, jag bestämde mig för att skriva ett program som slår 3T6 gång på gång tills det får resultatet 6-6-6. Då noterar programmet hur många gånger det behövde slå för nå dit, och sedan började det om att slå. Ända tills det fått resultatet 6-6-6 hela 10,000 gånger! Då har programmet alltså en lista på 10,000 värden. Därefter räknar den ut hur många gånger den behövde slå i snitt för att få
nämnda resultat.

BTW, sannolikheten för att få tre sexor av tre möjliga med en sex-siffrig tärning är 1/216.

Hursomhelst var det hela inte så enkelt som jag hade trott. Efter några timmar hade jag slängt ihop ett monster till program som omfattade 57 rader kod, indelat i fem fula funktioner, som alla hade ganska intetsägande namn, och vara ingen hette main(). Bränn kättaren... Därefter körde jag fast.

Det var problemet med att försöka lista ut genomsnittet ur en lista om 10,000 enheter jag inte kundelista ut. Så jag gick in på irc (#nochicktrix på Chatspike, btw), för att konsultera min yoda, _stink_. Han var tyvärr inte tillgänglig, men annan alfa-geek som jag brukar ställa mer generiska programmerings-frågor till, Unforgiven, var närvarande. Han beslöt sig för att ta sig an problemet.

Och efter en kvarts knepande och knåpande löste han mitt problem. Med två funktioner - inklusive main() - som sträckte sig över 30 rader kod! Argh! Det visade sig att jag inte tänkte på metoden sum(). Grattis till mig.

Hursomhelst konstaterar jag att random.randint är riktigt bra. Efter att ha rullat 6-6-6 2*10,000 gånger kunde konstateras att det tagit 217 respektive 216 försök i snitt för att uppnå detta resultat.

Epilog: Jag har bestämt mig för att fortsätta göra klart mina tester för egen maskin, för att lära mignågot, det är trots allt därför jag börjat med Eon-generatorn till att börja med. Ett stort tack till Unforgiven, som alltid tar sig tid att förklara saker för en nybörjare. Han och _stink_ har uppmuntrat mig att försöka själv, och alltid funnits till hands med hjälp, tips och förklaringar, trots att det säkerligen varit enerverande ibland. Det var också de som uppmuntrade mig att gå tillbaka till Linux igen.

Ett stort tack också till Axel Winkler, som ger mig perspektiv högre än en grodas när det gäller att få saker gjort, och som dessutom visar att jag faktiskt kan göra rätt tuffa saker på egen hand.

Slutligen har jag också en hälsning från Unforgiven, till alla svenska läsare:

"Bork, bork."

Inga kommentarer:

Skicka en kommentar