Programmeermethoden 2000
Vierde programmeeropgave - Othello

De vierde programmeeropgave van het vak Programmeermethoden in het najaar van 2000 heet Othello; zie ook de WWW-bladzijde van het tiende werkcollege (met hints!), lees geregeld deze pagina op WWW, en bezoek de speciaal hiervoor bestemde colleges.
Spreekuur in zalen 301 en 302/304: van 27 november tot en met 8 december (niet op 5 december), iedere werkdag van 16.00 tot 17.00 uur.
Let op: de werkcolleges van donderdag 23 en vrijdag 24 november zijn speciaal voor deze programmeeropgave bestemd. Tevens aanbevolen: het pointerpracticum tijdens de werkcolleges van donderdag 16 en vrijdag 17 november.

Voor deze programmeeropgave gaan we het spel Othello programmeren, of zoals het ook wel genoemd wordt: Reversi. Het is de bedoeling een klasse OthelloBord te maken, die onder meer memberfuncties heeft als afdrukken, spelerzet en computerzet. Uiteraard heeft deze klasse ook een constructor en een destructor. Verder moeten gedane zetten met behulp van een stapel ongedaan gemaakt kunnen worden, en kan het aantal vervolgpartijen worden uitgerekend.
Het "normale" spel Othello gaat als volgt. Op een 8 bij 8 bord wordt gespeeld met schijfjes die aan de ene kant wit en aan de andere kant zwart zijn. Om de beurt leggen de spelers -wit W en zwart Z geheten- een schijfje met hun eigen kleur naar boven op een nog leeg vakje. Dit mag alleen op een plek waar stenen van de tegenstander geslagen worden. Stenen van de tegenstander die ingesloten raken, hetzij horizontaal, of verticaal, of diagonaal, tussen eigen stenen, worden geslagen: ze worden omgekeerd, en krijgen dus de eigen kleur. Zwart begint. Als een speler niet kan zetten, moet hij/zij passen. Het spel is afgelopen als geen van de spelers meer kan zetten, bijvoorbeeld als het bord vol is. Winnaar is degene met de meeste stenen in zijn of haar kleur; gelijk spel is mogelijk. Kijk eens op http://www.litefaden.com/marvin/ voor een mooie werkende Othello (voor de vierde programmeeropgave hoeft het niet grafisch, en het programma hoeft niet zo goed te spelen!). De beginconfiguratie voor Othello staat links hieronder (voor Reversi is deze overigens iets anders), gevolgd door enkele voorbeeldzetten:
   . . . . . . . .   . . . . . . . .   . . . . . . . .
   . . . . . . . .   . . . . . . . .   . . . . . . . .
   . . . . . . . .   . . . . . . . .   . . . . . . . .
   . . . W Z . . .   . . . W Z . . .   . . . W Z . . .
   . . . Z W . . .   . . . Z Z Z . .   . . . Z W Z . .
   . . . . . . . .   . . . . . . . .   . . . . . W . .
   . . . . . . . .   . . . . . . . .   . . . . . . . .
   . . . . . . . .   . . . . . . . .   . . . . . . . .
In één zet kunnen stenen uit verschillende richtingen tegelijk geslagen worden. De stenen moeten echt aan beide zijden ingesloten raken om geslagen te worden. In een richting kunnen meerdere stenen tegelijk geslagen worden.
We spelen het spel met aangepaste regels. Allereerst mag de speler zijn/haar kleur kiezen; de computer speelt dan voor de andere kleur. Daarna mag ook de grootte van het bord gekozen worden: het aantal rijen m en het aantal kolommen n, beide minstens 2. Normaal geldt dus dat m=8 en n=8. De vier beginschijven staan op vakje (m/2,n/2), en de vakjes daar rechts/onder. Als de speler aan zet is, wordt de stand -in eenvoudig formaat- op het scherm getoond, en kan de speler zijn/haar zet doen, of juist de laatste eigen zet (en meteen de tussenliggende computerzet) terugnemen, of het aantal mogelijke vervolgpartijen voor de huidige stand laten uitrekenen. De mogelijke zetten worden opgesomd (bijvoorbeeld als 1: C2, 2: F5, 3: A8) zodat de speler eenvoudig kan kiezen. De door de speler uitgekozen zet wordt gedaan, waarna de computer een willekeurige, maar uiteraard wel toegestane, zet doet. Denk aan het verplichte "passen". Liefhebbers mogen natuurlijk hun eigen creativiteit inzetten, door bijvoorbeeld de computerzet waarbij de meeste stenen geslagen worden te kiezen.
Schrijf een constructor voor de klasse OthelloBord die een pointerstructuur aanlegt, waarbij ieder vakje, naast bijvoorbeeld een char als inhoud, tevens een array met 8 pointers naar de onmiddellijke buren heeft: linksboven, middenboven, rechtsboven, rechts, rechtsonder, middenonder, linksonder en links. De vakjes aan de randen bevatten uiteraard diverse NULL-pointers. Het bord is dus niet een m bij n array, maar een zeer ingewikkelde pointerstructuur.
Alle tussenstanden moeten op een stapel worden bijgehouden, en spelerzetten kunnen daarmee zelfs herhaald teruggenomen worden. Hiertoe moeten dus alle standen (en niet de zetten) worden onthouden, of liever gezegd: zodra de speler zet, wordt de oude stand (het complete bord) opgeslagen. Er moet dus een memberfunctie kopieer gemaakt worden, die de gehele pointerstructuur kopieert!
Verder dient er een recursieve memberfunctie vervolg geschreven te worden die gegeven een zekere stand het totale aantal mogelijke vervolgpartijen, dat overigens erg groot kan zijn, uitrekent. Hiervoor moeten alle mogelijke zetten van beide spelers doorgerekend worden. Dit onderdeel is zeker niet eenvoudig; mocht het ontbreken, dan kost dat een halve punt.

Enkele algemene opmerkingen:

Uiterste inleverdatum: maandag 11 december 2000, 17.00 uur. In te leveren: schijfje met de C++-files en de makefile, of deze files per email aan de hoofdnakijker kosters@liacs.nl sturen, vanaf een UNIX-systeem bij voorkeur met zoiets als
      tar cvfz spel.tgz file1.cc file2.cc file2.h file3.cc file3.h makefile
      uuencode spel.tgz spel.tgz | elm -s "Op 4 van A en B" kosters@liacs.nl
Verder ook een afdruk op papier in het postvak van W.A. Kosters in de postkamer (156). Als er een diskette bij is: alles samen graag in een envelop. Overal datum en namen van de makers vermelden. Te gebruiken compiler: als het maar C++ is; het programma moet in principe met g++ op een Linux-machine draaien. Normering: layout 1; commentaar 2; modulariteit en OOP 3; werking 4.

Vragen en/of opmerkingen kunnen worden gestuurd naar: kosters@liacs.nl.
6 november 2000 - http://www.liacs.nl/home/kosters/pm/op4pm00.html