Leren uit duizend spellen
Na één spel heeft elke zet een score van 1 of -1. Dat zegt nog weinig. Nu
speelt de computer tweeduizend spellen, en werkt hij na elk spel de score
bij. Nieuw is dat score buiten de loop staat: hij onthoudt alles, over alle
spellen heen.
Voorspel
score = {}
for spel in range(3):
zet = (10, 1)
if zet not in score:
score[zet] = 0
score[zet] = score[zet] + 1
print(score)
Wat print dit programma? En wat print het als score = {} de eerste regel
ín de loop is?
Antwoord
{(10, 1): 3}. Staat score = {} in de loop, dan begint elke ronde met een
lege score, en print hij {(10, 1): 1}: de computer vergeet dan na elk spel
wat hij leerde.
Zo werkt het
Het leren in de editor is het bijwerken uit
een spel onthouden,
in een loop van 2000 spellen. Omdat beide spelers dezelfde score gebruiken,
speelt de computer elk spel tegen zichzelf, en wordt hij steeds iets beter.
Onderaan print de code wat hij geleerd heeft: voor elke stapel de zet die
beste_zet kiest.
Onderzoek
- Draai de code. Vergelijk wat hij geleerd heeft met
slimuit het vorige project. Bij welke stapels doet hij hetzelfde? - Bij 9 lucifers pakt hij 2, en
slimpakt 1. Is dat erg? - Print onderaan
score[(10, 1)]enscore[(10, 3)]. Wat betekenen die getallen?
Wat zie je?
2 lucifers: pak 1
3 lucifers: pak 2
4 lucifers: pak 3
5 lucifers: pak 1
6 lucifers: pak 1
7 lucifers: pak 2
8 lucifers: pak 3
9 lucifers: pak 2
10 lucifers: pak 1
Antwoorden
- Bij elke stapel behalve 9 pakt hij precies wat
slimpakt. Waar je kunt winnen, pakt hij genoeg om een viervoud plus 1 over te laten. Niemand heeft hem dat verteld. Hij heeft het gevonden door te spelen. - Nee. Bij 5 en 9 verlies je van een goede tegenstander, wat je ook doet.
Alle drie de zetten hebben daar een negatieve score, en welke het hoogst
uitkomt, is toeval. Dat hij bij 5 net als
slim1 pakt, is ook toeval: de scores zijn daar -459, -460 en -459, en bij een gelijke stand houdtbeste_zetde eerste. score[(10, 1)]is 971 enscore[(10, 3)]is -76. Pak 1 bij 10 leidde meestal tot winst, pak 3 vaker tot verlies. De computer heeft pak 1 veel vaker gespeeld, omdat het de beste zet leek; daarom is het getal zo groot.
Opdracht: waar verlies je altijd?
Zoek uit bij welke stapels de computer geen enkele zet heeft gevonden die wint: elke zet die daar mag, heeft een score van 0 of lager.
bij 5 verlies je altijd
bij 9 verlies je altijd
Begin klein, en breid de code stap voor stap uit:
- Draai de code: hij leert, en print de score van pak 1 bij 9 lucifers.
- Print de score van elke zet uit
mogelijk(9): de zetten die bij 9 lucifers mogen. - Tel bij 9 lucifers hoeveel zetten een score boven 0 hebben.
- Doe dat voor elke stapel van 2 tot en met 10, en print alleen de stapels waar die telling 0 is.
In de verborgen code staan mogelijk(stapel), de zetten die bij een stapel
mogen, en waarde(score, stapel, pak), de score van een zet, of 0 als hij er
nog niet in staat.
Tip
Bij stap 4 begint de telling bij elke stapel opnieuw bij 0. Waar staat die regel dan: binnen of buiten de loop over de stapels?
Antwoord
Dit komt onder de code van de editor:
for stapel in range(2, 11):
goed = 0
for pak in mogelijk(stapel):
if waarde(score, stapel, pak) > 0:
goed = goed + 1
if goed == 0:
print("bij", stapel, "verlies je altijd")
bij 5 verlies je altijd
bij 9 verlies je altijd
Dat zijn precies de viervouden plus 1 uit de truc. De computer heeft ze
gevonden zonder %, alleen door te spelen.
Door naar ontdekken.