Nim, een strategisch spelletje Bert Wikkerink b.wikkerink@csgliudger.nl
Wat gaan we doen: Spelletje onderzoeken Oplossingsstrategie zoeken Hoe zit dat met de wiskunde? Programmeren Maar eerst …
Het spel Begin met een willekeurig aantal stenen Twee spelers pakken om de beurt stenen weg De speler die de laatste steen (stenen) pakt wint het spel Het spel Twee extra regels: De speler die begint mag niet alle stenen pakken in zijn eerste beurt Een speler mag niet meer dan het dubbele van het aantal pakken dat de speler voor hem pakte
Zoeken naar een strategie A begint en de winnaar is … 3 4 5 6 7 8 9 10 11 12 13 14 Winnaar (A or B) B A B A A B A A A A B A
Het lijkt erop dat speler A verliest als hij/zij moet beginnen met een van de volgende aantallen: 1 1 2 3 5 8 13 21 34 … De rij van Fibonacci Leonardo van Pisa (Fibonacci) c. 1175 – c. 1250
We weten dat de beginspeler verliest als hij/zij moet beginnen met een van de Fibonacci getallen 2, 3, 5, 8. Maar hoe zit dat met 13? 8 5
We weten dat de beginspeler verliest als hij/zij moet beginnen met een van de Fibonacci getallen 2, 3, 5, 8. Maar hoe zit dat met 13? en met 21? 13 8
En wat als het een niet-Fibonacci getal is?
En wat als het een niet-Fibonacci getal is? 7
En wat als het een niet-Fibonacci getal is? 7 = 5 + 2
En wat als het een niet-Fibonacci getal is? 12
En wat als het een niet-Fibonacci getal is? 12 = 8 + 4
En wat als het een niet-Fibonacci getal is? 12 = 8 + 3 + 1
En wat als het een niet-Fibonacci getal is? 20
En wat als het een niet-Fibonacci getal is? 20 = 13 + 7
En wat als het een niet-Fibonacci getal is? 20 = 13 + 5 + 2
Stelling van Zeckendorf: Elk positief geheel getal is te schrijven als de som van niet opeenvolgende Fibonacci getallen. Gevolg: Als je mag beginnen met een niet-Fibonacci getal is er altijd een zet die tot winst leidt. Je pakt gewoon het kleinste getal uit de Fibonacci-representatie.
Programmeren van de TI-Nspire Het programma functies factoriseer(n) fib(a) Schrijf n als som van Fibonacci getallen Bereken het grootste Fibonacci getal ≤ a
Twee functies: 1 fib(a): grootste Fibonacci getal ≤ a Voorbeelden: fib(11) = 8 fib(19) = 13 fib(30) = 21
Twee functies: 2 factorize(n): Fibonacci representatie van n Voorbeelden: factoriseer(11) = { 8, 3 } factoriseer(19) = { 13, 5, 2 } factoriseer(30) = { 21, 8, 1 }
{1,1} 1 > 6 ? {1,2} 2 > 6 ? {2,3} 3 > 6 ? {3,5} 5 > 6 ? 1 Hoe vind je het grootste Fibonacci getal ≤ 6 {1,1} 1 > 6 ? {1,2} 2 > 6 ? {2,3} 3 > 6 ? {3,5} 5 > 6 ? {5,8} 8 > 6 ? Return 5
lijst:={lijst[2],lijst[1]+lijst[2]} EndLoop Define fib(a)= Func © Bereken het grootste Fibonacci getal ≤ a Local lijst © Variabele alleen binnen deze functie lijst:={1,1} © Eerste twee Fibonacci getallen Loop If lijst[2]>a: Exit lijst:={lijst[2],lijst[1]+lijst[2]} EndLoop © Bereken het volgende Fibonacci getal totdat > a Return lijst[1] © list[1] is het gezochte getal EndFunc
Define factoriseer(a)= Func © Geef de Fibonacci representatie van a Local n,lijst © Variabelen binnen deze functioe lijst:={} © Start met een lege lijst While a>0 n:=fib(a) lijst:=augment({n},lijst) a:=a-n EndWhile © Zoek het grootste Fibonacci getal ≤ a en doe hetzelfde met de rest etc Return lijst © klaar EndFunc
Define start()= Prgm Local n,mx,zet,a,f,nspire n:=0 While n<3 Request "Starting number",n,0 If n=0: Stop If n<3: Text "Minimum 3",0 EndWhile . . . EndPrgm
Define start()= Prgm . . . nspire:=false a:=0 While a<1 or a>2 Request "1=Nspire begins, 2=You begin",a,0 If a=0: Stop EndWhile If a=1: nspire:=true . . . EndPrgm
mx:=n-1 Loop If nspire Then f:=factoriseer(n) zet:=f[1] If zet>mx: move:=1 Text "There are "&string(n)&". I take "&string(zet) Else zet:=0 While zet<1 or zet>mx Request "There are “&string(n)&". You take? (max "&string(mx)&")",zet If zet=0: Stop EndWhile EndIf n:=n-zet If n≤0: Exit nspire:=not nspire mx:=2*zet EndLoop
mx:=n-1 Loop If nspire Then f:=factorize(n) zet:=f[1] If zet>mx: zet:=1 Text "There are "&string(n)&". I take "&string(zet) Else zet:=0 While zet<1 or zet>mx Request "There are “&string(n)&". You take? (max "&string(mx)&")", zet If zet=0: Stop EndWhile EndIf n:=n-zet If n≤0: Exit nspire:=not nspire mx:=2*zet EndLoop
mx:=n-1 Loop If nspire Then f:=factorize(n) zet:=f[1] If zet>mx: zet:=1 Text "There are "&string(n)&". I take "&string(zet) Else zet:=0 While zet<1 or zet>mx Request "There are “&string(n)&". You take? (max "&string(mx)&")",zet If zet=0: Stop EndWhile EndIf n:=n-zet If n≤0: Exit nspire:=not nspire mx:=2*zet EndLoop
mx:=n-1 Loop If nspire Then f:=factorize(n) zet:=f[1] If zet>mx: zet:=1 Text "There are "&string(n)&". I take "&string(zet) Else zet:=0 While zet<1 or zet>mx Request "There are “&string(n)&". You take? (max "&string(mx)&")",zet If zet=0: Stop EndWhile EndIf n:=n-zet If n≤0: Exit nspire:=not nspire mx:=2*zet EndLoop
Define start()= Prgm . . . If nspire Then Text " Ik heb gewonnen ",0 Else Text ”Jij hebt gewonnen",0 EndIf EndPrgm
Extra
Einde b.wikkerink@csgliudger.nl
3 1 2 4 5 6 7 8
Programming a strategy game Bert Wikkerink b.wikkerink@csgliudger.nl