Nim is een strategisch spelletje voor twee spelers. De speler die als eerste aan de beurt is, mag bepalen hoeveel stapels lucifers ($$n \geq 2$$) er gemaakt worden en hoeveel lucifers er in elke stapel liggen. Het aantal lucifers mag verschillen per stapel en stapels mogen ook leeg zijn. Om naar de stapels te kunnen verwijzen, worden ze oplopend genummerd van 1 tot en met $$n$$. Hieronder zie je bijvoorbeeld een startconfiguratie met vijf stapels, waarvan de vierde leeg is.

nim
Mogelijke startconfiguratie van het spelletje Nim.

Daarna doen de spelers om de beurt een zet, die erin bestaat dat ze minimaal één en maximaal alle lucifers van één stapel wegnemen. De speler die de laatste lucifer wegneemt, wint het spel.

Opgave

Definieer een klasse Nim die toelaat om het verloop van een spelletje Nim te simuleren. Bij het aanmaken van een nieuw spelletje (Nim) moeten er twee of meer natuurlijke getallen (Number) doorgegeven worden. Deze getallen beschrijven de startconfiguratie van het spelletje: het aantal getallen correspondeert met het aantal stapels en de getallen zelf geven aan hoeveel lucifers er bij aanvang van het spelletje in elke stapel liggen. Als er niet twee of meer natuurlijke getallen doorgegeven worden, dan moet er een Error opgeworpen worden met de boodschap ongeldige stapels.

Voorts moet je op een spelletje $$s$$ (Nim) minstens de volgende methoden kunnen aanroepen:

Voorbeeld

> const nim = new Nim(3, 4, 2, 0, 7);
> console.log(nim.toString())
1: |||
2: ||||
3: ||
4: 
5: |||||||
> console.log(nim.wegnemen(2, 3).toString())
1: |||
2: |
3: ||
4: 
5: |||||||
> console.log(nim.wegnemen(5, 2).wegnemen(5, 1).toString())
1: |||
2: |
3: ||
4: 
5: ||||
> nim.wegnemen(1, 4)            // te weinig lucifers in stapel
Error: ongeldige zet
> nim.wegnemen(7, 1)            // onbestaande stapel
Error: ongeldige zet
> nim.wegnemen(3, 0)            // er moet minstens één lucifer weggenomen worden
Error: ongeldige zet
> console.log(nim.toString())
1: |||
2: |
3: ||
4: 
5: ||||
> nim.isAfgelopen()
false
> console.log(nim.wegnemen(1, 3).wegnemen(2, 1).wegnemen(3, 2).wegnemen(5, 4).toString())
1: 
2: 
3: 
4: 
5: 
> nim.isAfgelopen()
true

> const nim1 = new Nim(4, 3, 0, 5);
> const nim2 = new Nim(3, 0, 2, 1, 6, 2);
> console.log(nim1.samenvoegen(nim2).toString())
1: |||||||
2: |||
3: ||
4: ||||||
5: ||||||
6: ||

> new Nim(0.1, 2.3, 4.5, 6.7, 8.9)     // alle argumenten moeten integers zijn
Error: ongeldige stapels
> new Nim("drie", "zeven", "twee")     // alle argumenten moeten integers zijn
Error: ongeldige stapels
> new Nim(7)                           // er moeten minstens twee argumenten zijn
Error: ongeldige stapels