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:
Als je een dobbelsteen aan de rand wegneemt die niet in een hoek van het rooster ligt, dan zijn er drie mogelijkheden:
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:
Een methode toString waaraan geen argumenten moeten doorgegeven worden. De methode moet een stringvoorstelling van het rooster teruggeven, waarbij elke rij van het rooster op een afzonderlijke regel staat, en elke rij wordt voorgesteld als een opeenvolging van de karakters die de bovenzijde van de dobbelstenen voorstellen (-, X en O).
Een methode positie waaraan de omschrijving van een positie aan de rand van het rooster moet doorgegeven worden. De methode moet een array met twee natuurlijke getallen teruggeven, die respectievelijk de rij- en kolomindex van de positie in het rooster aangeven als de rijen van boven naar onder en de kolommen van links naar rechts geïndexeerd worden vanaf nul. Indien de gegeven omschrijving geen geldige positie aan de rand van het rooster aanduidt, dan moet een AssertionError opgeworpen worden met de boodschap ongeldige positie.
>>> 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.