Quixo is een bordspel dat gespeeld wordt met een vierkant $$n \times n$$ rooster van dobbelstenen. Elke dobbelsteen heeft minstens één zijde die blanco is, één zijde die gemarkeerd is met een kruis en één zijde die gemarkeerd is met een cirkel. Initieel liggen alle dobbelstenen met een blanco zijde naar boven. In het spel nemen twee spelers het tegen elkaar op, waarbij één speler speelt met de kruisen en de andere met de cirkels.

Om beurt neemt een speler een dobbelsteen uit de buitenste rand van het rooster waarvan de bovenzijde blanco is of gemarkeerd is met zijn symbool. Indien de bovenzijde blanco was, dan draait hij de dobbelsteen zodat de bovenzijde gemarkeerd is met zijn symbool. Daarna duwt hij de dobbelsteen terug in het rooster aan het uiteinde van de rij of kolom waarop de dobbelsteen werd verwijderd, maar niet op dezelfde plaats waar de dobbelsteen werd verwijderd. Op die manier verwisselen per beurt telkens een paar dobbelstenen van plaats, en worden blanco dobbelstenen geleidelijk aan vervangen door kruisen en cirkels.

Het spel gaat verder totdat een speler erin slaagt om horizontaal, verticaal of diagonaal $$n$$ dobbelstenen op één lijn te krijgen waarvan de bovenzijde telkens gemarkeerd is met zijn symbool. Die speler wint het spel. Als op hetzelfde moment lijnen gevormd worden met de symbolen van beide spelers, dan eindigt het spel op een gelijkspel. Onderstaande instructievideo zet de spelregels nog eens op een rijtje:

Als je een dobbelsteen wegneemt in één van de hoeken van het rooster, dan zijn er dus twee mogelijkheden:

hoekpunt
Twee mogelijke zetten als je een dobbelsteen wegneemt in één van de hoeken van het rooster.

Als je een dobbelsteen aan de rand wegneemt die niet in een hoek van het rooster ligt, dan zijn er drie mogelijkheden:

rand
Drie mogelijke zetten als je een dobbelsteen aan de rand van het rooster wegneemt, die niet in een hoekpunt ligt.

Opgave

In deze opgave stellen we dobbelstenen met een blanco bovenzijde voor door een koppelteken (-), dobbelstenen waarvan de bovenzijde gemarkeerd is met een kruis door de letter X, en dobbelstenen waarvan de bovenzijde gemarkeerd is met een cirkel door de letter O.

Elke kolom in het rooster wordt van links naar rechts gemarkeerd met een volgende hoofdletter uit het alfabet (we veronderstellen dat er niet meer dan 26 kolommen zijn). Elke rij wordt van boven naar onder gemarkeerd met een getal, te beginnen vanaf 1. Op die manier kan elke positie in het rooster omschreven worden door een string die bestaat uit een hoofdletter (die de kolom aanduidt) en een getal (die de rij aanduidt).

Gevraagd wordt om een klasse Quixo te definiëren, waarmee het spelbord van een spelletje Quixo kan voorgesteld worden. Bij het instantiëren van objecten van de klasse Quixo moet een getal $$n \in  \mathbb{N}_0$$ doorgegeven worden, dat aangeeft hoeveel rijen en kolommen van dobbelstenen er zijn in het spelbord. Na initialisatie liggen alle dobbelstenen standaard met een blanco zijde naar boven, maar optioneel kan er bij het instantiëren ook nog een string opgegeven worden die bestaat uit $$n^2$$ karakters -, X of O. Deze string omschrijft de bovenzijde van de dobbelstenen bij initialisatie als het rooster van links naar rechts en van boven naar onder wordt overlopen. Als er geen geldige argumenten doorgegeven worden bij het instantiëren van objecten van de klasse Quixo, dan moet een AssertionError opgeworpen worden met de boodschap ongeldig rooster. Voorts moet de klasse Quixo minimaal de volgende methoden ondersteunen:

Voorbeeld

>>> const quixo01 = new Quixo(5, "X-XXX-XO-OO-OOOOXOX-OOOO-");
>>> quixo01.toString();
"X-XXX\n-XO-O\nO-OOO\nOXOX-\nOOOO-"
>>> quixo01.positie('B1');
[0, 1]
>>> quixo01.beurt('X', 'B1', 'B5').toString();
"XXXXX\n--O-O\nOXOOO\nOOOX-\nOXOO-"

>>> const quixo02 = new Quixo(5, "X-XXX-XO-OO-OOOOXOX-OOOO-");
>>> quixo02.toString();
"X-XXX\n-XO-O\nO-OOO\nOXOX-\nOOOO-"
>>> quixo02.beurt('X', 'B1', 'A1').toString();
"XXXXX\n-XO-O\nO-OOO\nOXOX-\nOOOO-"

>>> const quixo03 = new Quixo(5, "X-XXX-XO-OO-OOOOXOX-OOOO-");
>>> quixo03.toString();
"X-XXX\n-XO-O\nO-OOO\nOXOX-\nOOOO-"
>>> quixo03.beurt('X', 'B1', 'E1').toString();
"XXXXX\n-XO-O\nO-OOO\nOXOX-\nOOOO-"

De simulatie van de drie beurten uit bovenstaande voorbeeldsessie worden hieronder grafisch voorgesteld.

rand
Grafische voorstelling van de simulatie van de drie beurten uit de interactieve sessie die als voorbeeld gebruikt werd.