Game of dots is een spel voor twee spelers dat met potlood en papier kan gespeeld worden. Het werd in de negentiende eeuw bedacht door de Franse wiskundige Édouard Lucas, die het la pipopipette noemde. Het spel wordt gespeeld op een rechthoekig raster van stippen, dat bij aanvang nog leeg is. Om de beurt trekken de spelers een lijn tussen twee aangrenzende stippen die nog niet met elkaar verbonden waren. Een speler die de vierde lijn van een $$1 \times 1$$-vakje aanvult, scoort één punt en blijft aan de beurt. Het spel eindigt als er geen lijnen meer kunnen getrokken worden. De winnaar is de speler die het meeste punten gescoord heeft.

game of dots
Voorbeeld van het verloop van een spelletje game of dots dat gespeeld wordt op een vierkant raster van $$3 \times 3$$ stippen.

Bovenstaand schema toont het verloop van een spelletje game of dots dat gespeeld wordt op een raster met $$3 \times 3$$ stippen. De tweede speler (B) speelt een geroteerd spiegelbeeld van de lijnen die door de eerste speler (A) getrokken worden, in de hoop het raster in twee stukken te verdelen en zo een gelijkspel uit de wacht te slepen. In stap 7 lijkt speler A zich op te offeren. Speler B aanvaardt het offer en scoort daarmee een punt. Maar nu moet speler B nog een lijn trekken en dus verbindt hij de middenstip met de stip midden rechts. Dit zorgt er echter voor dat de overblijvende $$1 \times 1$$-vakjes een soort ketting vormen, zoals te zien is op het einde van stap 8. In de volgende beurt verovert speler A de drie overblijvende vakjes, waardoor het spel eindigt en speler A wint met 3–1.

Opgave

Een spelletje game of dots wordt gespeeld op een $$m \times n$$ raster waarin de stippen gerangschikt worden in $$m$$ rijen en $$n$$ kolommen. De horizontale lijnen die tussen twee aangrenzende stippen kunnen getrokken worden, vormen zelf een $$m \times (n - 1)$$ raster. Als we de rijen van dat raster van boven naar onder nummeren vanaf 0 en de kolommen op dezelfde manier nummeren van links naar rechts, dan kunnen we de positie van een horizontale lijn aanduiden met een string Hr,k. Daarbij stelt $$r \in \mathbb{N}$$ het rijnummer en $$k \in \mathbb{N}$$ het kolomnummer voor. Analoog vormen de verticale lijnen een $$(m - 1) \times n$$ raster en kunnen we de positie van een verticale lijn aanduiden met een string Vr,k.

coördinaten
Stringvoorstelling waarmee de posities van de horizontale en verticale lijnen aangeduid worden.

Ook de vakjes die moeten veroverd worden, vormen een $$(m - 1) \times (n - 1)$$ raster. Als we de rijen van dat raster van boven naar onder nummeren vanaf 0, en de kolommen van links naar rechts, dan gelden de volgende eigenschappen:

Je kunt deze eigenschappen controleren op onderstaande figuur.

coördinaten
Verband tussen de coördinaten van de vakjes die kunnen veroverd worden en de coördinaten van de lijnen die aangrenzende stippen met elkaar verbinden.

Definieer een klasse Pipopipette waarmee een spelletje game of dots kan gespeeld worden tussen twee spelers. Bij het aanmaken van nieuw spelletje (Pipopipette) moeten twee getallen $$m, n \in \mathbb{N}$$ ($$m, n \geq 2$$; Number) doorgegeven worden, die aangeven dat het spelletje op een $$m \times n $$ raster van stippen gespeeld wordt. Als er bij het aanmaken van een spelletje (Pipopipette) slechts één getal $$m$$ wordt doorgegeven, dan wordt het spelletje op een vierkant $$m \times m$$ raster gespeeld.

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

Voorbeeld

> const game = new Pipopipette(3)
> game.score()
[0, 0]
> console.log(game.toString())
+.+.+
.?.?.
+.+.+
.?.?.
+.+.+
> game.player()
"A"
> console.log(game.claim("H0,0").toString())
+-+.+
.?.?.
+.+.+
.?.?.
+.+.+
> game.player()
"B"
> console.log(game.claim("H2,1").toString())
+-+.+
.?.?.
+.+.+
.?.?.
+.+-+
> console.log(game.claim("H0,1").claim("H2,0").toString())
+-+-+
.?.?.
+.+.+
.?.?.
+-+-+
> console.log(game.claim("V0,0").claim("V1,2").claim("H1,0").toString())
+-+-+
|?.?.
+-+.+
.?.?|
+-+-+
> game.player()
"B"
> console.log(game.claim("V0,1").claim("H1,1").toString())
+-+-+
|B|?.
+-+-+
.?.?|
+-+-+
> game.score()
[0, 1]
> game.player()
"A"
> console.log(game.claim("V0,2").claim("V1,1").claim("V1,0").toString())
+-+-+
|B|A|
+-+-+
|A|A|
+-+-+
> game.score()
[3, 1]
> game.claim("ABCD")
Error: invalid position
> game.claim("H10,10")
Error: invalid position
> game.claim("H0,0")
Error: dots already connected