Programmeermethoden 2009
Vierde programmeeropgave
Vier-op-een-rij

De vierde programmeeropgave van het vak Programmeermethoden in het najaar van 2009 heet Vier-op-een-rij. Voor meer informatie over dit spel: Connect_four(wiki).
Zie ook de hints bij Werkcollege 10 en 11; Werkcollege 12 gaat over Qt, de omgeving nodig voor de grafische versie.
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 9 tot en met vrijdag 13 november, dinsdag 17 november, dinsdag 24 november, dinsdag 1 december en dinsdag 8 december, van circa 15.30 tot 17.00 uur. En verder op afspraak ...
De werkcolleges van dinsdag 10, dinsdag 17 / donderdag 19 en dinsdag 24 / donderdag 26 november (Qt) zijn speciaal bestemd voor deze opgave. Het werkcollege van donderdag 12 november (en deels dat van dinsdag 10 november) is nog voornamelijk voor de derde programmeeropgave bedoeld.
Let op: het college van dinsdag 24 november (Java en Qt) vindt plaats in het Snellius, zaal 412; de colleges van dinsdagen 1 en 8 december worden als werkcollege / vragenuur in de computerzalen gegeven. Het werkcollege van dinsdag 1 (zalen 403 en 413) en donderdag 3 (zalen 401, 403 en 405) december is voor iedereen, en gaat over oude tentamens.

4-op-een-rij De bedoeling van de opdracht is om het tweepersoons spel Vier-op-een-rij te programmeren. Deze opdracht kent twee onderdelen:

  1. Het spel Vier-op-een-rij programmeren op een m bij n bord (m rijen en n kolommen, beide minstens 1), en een eenvoudige intelligente computertegenstander ontwerpen. Het spel wordt in eerste instantie op een eenvoudige manier afgebeeld.
  2. Het spelen van het spel (vaste grootte: 6 hoog en 7 breed) grafisch weergeven met behulp van Qt.

Het spel gaat als volgt. Op een m bij n bord spelen de twee spelers om de beurt een schijfje van hun eigen kleur. Het schijfje wordt in een kolom gespeeld en valt daar naar de laagste nog lege plek. In een volle kolom kan niet meer gespeeld worden. Het spel stopt zodra één van de spelers vier (of meer) van zijn eigen schijfjes direct naast elkaar heeft, en wel horizontaal, verticaal of diagonaal: "vier-op-een-rij"; deze speler wint. Het spel stopt natuurlijk ook als het hele bord vol is. Als geen van beide spelers "vier-op-een-rij" hebben, is de uitslag remise.

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).
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 eenvoudige strategie (optie 2). De gebruiker kan tijdens spel steeds opgeven op welk van de twee manieren de computer speelt.
Het is ook mogelijk dat de computer tegen zichzelf speelt. In dat geval kiest de gebruiker voor beide computerspelers een strategie.
Tot slot kan de speler ook telkens het aantal vervolgpartijen opvragen, wat alleen zal werken als dit aantal redelijk beperkt is. Dat is dus overigens niet het aantal vervolgzetten. NB Als deze optie geheel ontbreekt, kost dat 1 punt.

Voor de eenvoudige strategie geldt dat het niet de bedoeling is een boomstructuur met vervolgpartijen op te zetten. Wel moeten alle mogelijk vervolgzetten bekeken worden. Daaruit moet verstandig gekozen worden. Het programma moet in ieder geval winnen als het direct kan winnen, en als dat niet kan zo mogelijk direct verlies voorkomen. Gebruik een eenvoudige evaluatiefunctie om dit tot stand te brengen. De bedoeling is dat de gebruiker ook nog minstens één parameter kan instellen. Zo kan bijvoorbeeld gekeken worden hoeveel nieuwe "drie-op-een-rij"'s ontstaan na een potentiële zet, en of er kansen voor de tegenstander verdwijnen; de parameter kan dan een gewicht zijn voor dit soort maten.

In eerste instantie wordt de stand steeds na elke beurt in een eenvoudig formaat op het scherm getoond. Later wordt Qt gebruikt om een en ander te verfraaien. Een tip is om vroegtijdig met het "niet-grafische programma" rekening te houden bij het ontwerp. Bij de grafische versie moet een speler zijn zetten natuurlijk doorgeven door te klikken met de muis.

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) twee-dimensionaal 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). Idem voor stapel.
De bedoeling is dat het programma in eerste instantie (zonder grafisch interface) onder Linux 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 27 november 2009, 17.00 uur: alle niet-grafische files en de UNIX makefile
  2. dinsdag 8 december 2009: demonstratie van de interface; maak een afspraak met de docenten
Manier van inleveren deel 1:
  1. Digitaal de C++-code inleveren: stuur een email naar pm@liacs.nl. Doe dit als "tarball": zet alle .cc- en .h-files bij elkaar, en ook de makefile. Geef dan (in Linux) het commando tar cvfz achternamen.tgz *cc *h makefile en stuur achternamen.tgz op.
  2. En ook een papieren versie van het voorlopige verslag 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.
    Het voorlopige verslag moet alle C++-code en de makefile bevatten. Bij de demo moet het definitieve verslag worden ingeleverd, nu aangevuld met een korte uitleg van het programma; een duidelijke uitleg van de gebruikte strategie; en een tabel met gewerkte uren.
Te gebruiken compiler: g++ op een Linux-machine. En Qt.
Normering: layout 1; commentaar 1,5; modulariteit 1,5; werking niet-grafisch 4; werking grafisch 2. Eventuele aanvullingen en verbeteringen: lees deze WWW-bladzijde.


Vragen en/of opmerkingen kunnen worden gestuurd naar: kosters@liacs.nl.
9 november 2009 — http://www.liacs.nl/home/kosters/pm/op4pm09.html