Programmeermethoden 2007
Vierde programmeeropgave
Checkers

De vierde programmeeropgave van het vak Programmeermethoden in het najaar van 2007 heet Checkers. Zie ook de hints bij Werkcollege 10 en 12; Werkcollege 11 gaat over Qt. Deze opgave is verplicht voor studenten Informatica. Anderen mogen de opgave maken, en krijgen dan uiteindelijk één ECTS (studiepunt) meer voor het vak Programmeermethoden: zeven in plaats van zes ECTS.

Spreekuur in zalen 302 ... 309: maandag 12 tot en met vrijdag 16 november, maandag 19 en dinsdag 20 november, maandag 26 en dinsdag 27 november, en maandag 3 en dinsdag 4 december, van circa 15.30 tot 17.00 uur. En verder op afspraak ... De werkcolleges van dinsdag 13, dinsdag 20 / donderdag 22 (Qt), dinsdag 27 / donderdag 29 november zijn speciaal bedoeld voor deze opgave. Het werkcollege van donderdag 15 november is nog voornamelijk voor de derde programmeeropgave bedoeld.
Let op: de colleges van 27 november en 4 december worden niet in het Gorlaeus, maar als werkcollege / vragenuur in de computerzalen gegeven. Het werkcollege van dinsdag 4 en donderdag 6 december is voor iedereen, en gaat over oude tentamens.

Deze opdracht kent twee onderdelen:

  1. Het spel Checkers programmeren op een m bij n bord, en een (redelijk) intelligente computertegenstander ontwerpen. Het spel wordt in eerste instantie op een eenvoudige manier afgebeeld.
  2. Het spelen van het spel (8 bij 8) grafisch weergeven met behulp van Qt.

Checkers

Het spel Checkers, of draughts, in het Nederlands Dammen op een schaakbord, is deze zomer opgelost: bij perfect spel van beide partijen is het remise.

Op een 8 bij 8 bord wordt Checkers gespeeld met 12 rode (of zwarte) en 12 witte damschijven, zie het plaatje met de beginopstelling. Alleen de donkere velden worden gebruikt. Zwart begint. Als je niet kunt zetten (omdat je geen schijven meer hebt, of omdat je vast staat), heb je verloren. Het spel lijkt sterk op gewoon dammen. Belangrijkste verschillen zijn dat een schijf niet achteruit mag slaan, en dat een dam (hier meestal "king" genoemd) niet over grotere stukken mag springen.

Er zijn twee soorten zetten: schuifzetten en slagzetten. Slaan is verplicht. Stukken mogen (schuin) vooruitgeschoven worden naar een leeg veld, of een vijandig stuk slaan door naar het lege veld erachter (als dat er is, natuurlijk) te springen. Gewone schijven mogen alleen vooruit slaan. Als een schijf de overkant bereikt wordt het een dam. Een dam mag in alle vier richtingen slaan en zetten (schuiven). Een damslag gaan niet voor.
Er bestaat ook meerslag. Sterker nog, er moet geslagen worden als dat kan. De speler mag in zo'n geval zelf kiezen welke slagzet gedaan wordt; meerslag gaat niet voor. Elke schijf mag maximaal één keer geslagen worden. Als een schijf tijdens een meerslag een dam wordt, blijft hij op dat moment meteen stil staan (er mag nog niet meteen achteruit geslagen worden). Let op: als meerslag niet geimplementeerd is, kost dat 1 punt. Doe dit dus pas als het meeste goed werkt!

Wij zullen het spel wat algemener spelen, namelijk op een m bij n bord (met m en n groter dan 2), waarbij beide spelers r rijen bezetten in de beginstand (bij het normale Checkers op een 8 bij 8 bord is r gelijk aan 3). Het veld linksonder is zwart.
Het spel, zoals we het in eerste instantie gaan ontwerpen, moet een aantal keren achter elkaar gespeeld kunnen worden. Bij het begin van elk spel geeft de gebruiker de grootte van het bord op (m bij n, met m hoogstens const int maxrij en n hoogstens const int maxkolom; en r, maximaal m/2).
Als de gebruiker aan zet is, kan deze een toegestane zet doen, of juist de laatste eigen zet (en meteen de tussenliggende computerzet) terugnemen.
De computer doet gedurende een spel ofwel steeds random (toegestane) zetten (optie 1), ofwel steeds zetten volgens een of andere strategie (optie 2). De gebruiker moet voor het spel begint opgeven op welk van de twee manieren de computer speelt.
Tot slot kan de speler ook steeds het aantal vervolgpartijen opvragen, wat alleen zal werken als dit aantal redelijk beperkt is. Let op: hierbij mag je geen meerslag gebruiken, dus slagzetten blijven beperkt tot het slaan van één schijf. Verder spreken we hier een extra stop-conditie af (om oneindige loops te voorkomen): een partij stopt als beide spelers een dam hebben. Dit geldt dus niet voor het gewone spel, alleen voor de berekening van het aantal vervolgpartijen.

In eerste instantie wordt de stand steeds (na de beurt van beide spelers) in een eenvoudig formaat op het scherm getoond. Later wordt Qt gebruikt om een en ander te verfraaien. (Een tip is om alvast met het "niet-grafisch programma" rekening te houden met hoe stukken verplaatst worden (via bron en doel coordinaten of via selecteren van vakjes (welke gebruik je straks bij het grafische gedeelte?)). In beide versies wordt bij elke stand tevens aangegeven hoeveel stukken van beide partijen er op dat moment op het bord staan. Bij de grafische versie moet een speler zijn zetten natuurlijk doorgeven door te klikken met de muis; zorg ervoor dat na het selecteren van het beginvakje van een zet dit vakje duidelijk herkenbaar is. Meerslag moet ook netjes ingevoerd en uitgevoerd worden — als het geimplementeerd is, natuurlijk.

Eisen aan de programmatuur

Lees invoer van de gebruiker netjes met cin.get ( ) of de functie leesgetal (...) uit de derde programmeeropdracht in en handel foutieve invoer af.
Schrijf een klasse bord waarin de huidige spelsituatie is opgeslagen. Dit kan bijvoorbeeld met een (groot genoeg) tweedimensionaal array. Bovendien moeten objecten van de klasse bord de speler die aan de beurt is bevatten, alsmede de actuele grootte van het bord. De klasse bord bevat verder methoden/memberfuncties (eventuele parameters en returnwaarden moet je zelf invullen) als: De menselijke speler moet zetten terug kunnen nemen. Dat betekent dus dat alle voorgaande standen (dus niet de zetten) waarin de gebruiker aan de beurt is moeten worden onthouden. Dit kan mooi vanuit een klasse spel. Zodra de speler zet, wordt steeds de oude stand boven op een stapel (een member-variabele uit spel; de stapel is dus geen member-variabele van bord) gezet. Schrijf hiervoor een geschikte klasse stapel, met in elk geval memberfuncties: Vanwege modulariteit en dus ook om zometeen handig het spel aan de grafische interface te koppelen, moet de functionaliteit gesplitst worden over meerdere files. Splits het programma daartoe op in een bestand waarin main ( ) staat, een bestand waarin de implementatie van klasse bord staat, en een headerfile met daarin de definitie van deze klasse (zonder implementatie). Hetzelfde voor de klasse stapel.
De bedoeling is dat het programma in eerste instantie (zonder grafisch interface) onder UNIX werkt. Schrijf daartoe een makefile voor deze files zodanig dat de .cc bestanden apart worden gecompileerd en uiteindelijk worden samengevoegd ("gelinkt") tot een executeerbaar programma.

Uiterste inleverdatum:

  1. vrijdag 30 november 2007, 17.00 uur: alle niet grafische files en de UNIX makefile
  2. vrijdag 7 december 2007: demonstratie van de interface; maak een afspraak met de docenten
Manier van inleveren deel 1:
  1. Digitaal de C++-code opsturen, en wel als "tarball": zet alle .cc- en .h-files bij elkaar, en ook de makefile. Geef dan (in Linux) het commando tar cvfz achternaam.tgz *cc *h makefile en stuur achternaam.tgz op.
  2. En ook een listing/afdruk van al deze files op papier deponeren in de speciaal daarvoor bestemde witte doos "Programmeermethoden" in de postkamer van Informatica, kamer 156. Overal duidelijk datum en namen van de (maximaal twee) makers vermelden, in het bijzonder als commentaar in de eerste regels van de C++-code. Zijn spaties/tabs goed "afgedrukt" (voor een nette linker kantlijn)!?
Te gebruiken compiler: g++ op een Linux-machine. En Qt.

Normering: layout 1; commentaar 1,5; modulariteit 1,5; werking niet-grafisch 4 (-1 als meerslag helemaal niet geimplementeerd is); werking grafisch 2. Eventuele aanvullingen en verbeteringen: lees deze WWW-bladzijde.


Vragen en/of opmerkingen kunnen worden gestuurd naar: kosters@liacs.nl.
19 november 2007 — http://www.liacs.nl/home/kosters/pm/op4pm07.html