Programmeermethoden 2006
Vierde programmeeropgave » Virus
De vierde programmeeropgave van het vak Programmeermethoden in het
najaar van 2006 heet Virus. Zie ook de hints bij Werkcollege 10 en 12, en lees de
hoofdstukken 6, 7 en 8 van het dictaat. Vragenuren: werkcolleges van dinsdag 14
en 28 november. Let op: de colleges vanaf woensdag 22 november worden
niet in het Gorlaeus, maar als werkcollege in de computerzalen gegeven; op de
woensdagen is aansluitend een vragenuur.
Deze opdracht kent vier onderdelen:
- De regels van het spel Virus programmeren op een m bij n
bord
- Het spel in eerste instantie op een eenvoudige manier afbeelden.
- Een (redelijk) intelligente computertegenstander ontwerpen.
- Uiteindelijk het spelen van het spel grafisch weergeven met behulp van
Visual C++ (of met behulp Qt designer of ...).
Het spel Virus, bekend van "The 7th Guest" (het microscoop-spel) en
algemeen bekend onder de naam Ataxx, wordt normaliter
gespeeld op een 7 bij 7 bord. Wij zullen het spel wat algemener spelen, namelijk
op een m bij n bord (met m en n groter dan
dan 3 en oneven). Twee verschillende typen "virussen" nemen het hierbij tegen
elkaar op en proberen uiteindelijk het grootste deel van het veld te
veroveren.
Bij aanvang van het spel staat in de rechterbovenhoek het
beginvirus van de speler en in de linkeronderhoek het virus van de computer, zie
het plaatje.
De spelregels zijn eenvoudig. Er zijn twee spelers, in dit geval de
menselijke speler = gebruiker en de computer. De gebruiker speelt met de Ridders
(wit) en de computer met de Doodshoofdjes (zwart). Ze doen om de beurt een zet
waarbij ze een virus van het eigen type cloneren of verschuiven. Dit gaat als
volgt:
- De speler aan zet cloneert het gewenste virus 1 vakje (ook diagonaal) naar
een voorheen leeg vakje: Het virus wordt vermenigvuldigd en blijft dus ook op
de oude plek staan.
- De speler aan zet verplaatst het gewenste virus 2 vakjes (ook diagonaal)
naar een voorheen leeg vakje: Het virus verplaatst en verdwijnt dus op de oude
plek.
Virussen kunnen "over elkaar heen springen". Als een virus naar
een vakje gaat met op de aangrenzende vakjes (ook diagonaal) een of meer
virussen van de tegenstander, dan worden al die aangrenzende virussen van de
tegenstander ook van het type van het virus dat net verzet werd.
Zetten is
verplicht. Indien een speler geen enkele geldige zet kan doen als het zijn beurt
is, krijgt de andere speler nog een kans. Dit gebeurt net zo lang tot het spel
eindigt of de speler die eigenlijk aan zet is weer een zet kan doen. De
gebruiker van het programma bepaalt wie van beide spelers moet beginnen.
Het
spel kan eindigen op twee verschillende manieren:
- Een van de spelers heeft geen virussen meer op het bord. Deze speler
verliest het spel.
- Het bord staat helemaal vol met virussen. De speler die dan de meeste
virussen op het bord heeft wint het spel.
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 beide oneven).
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.
In eerste instantie wordt de stand
steeds (na de beurt van beide spelers) in een eenvoudig formaat op het scherm
getoond. Later wordt Visual C++ 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 van beide virussen er op dat
moment op het bord staan.
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) zoals:
- bord (...): de constructor (initialiseert de membervariabelen).
- beginstand (...): voert de door de gebruiker in te voeren grootte
van het bord in en zet de stenen op de juiste beginposities.
- toegestanezet (...): controleert of een gegeven zet is
toegestaan.
- drukaf (...): drukt de huidige stand af op het scherm.
- randomzet (...): berekent een random zet voor de computer.
- strategiezet (...): bepaalt een zet voor de computer op grond van
een of andere strategie.
- doezet (...): voert een gegeven toegestane zet uit.
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) gezet. Schrijf hiervoor een geschikte
klasse stapel, met in elk geval memberfuncties:
- zetopstapel (...)
- haalvanstapel (...)
- isstapelleeg (...)
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) ook 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:
- vrijdag 1 december 2006, 17.00 uur: alle niet grafische files en de
Unix makefile
- vrijdag 8 december 2006: demonstratie Interface; maak afspraak met
de docenten
Manier van inleveren deel 1: Email aan de hoofdnakijker
pm@liacs.nl sturen. Zorg er voor dat je alleen de programma-code
inlevert en niet de executables. Je kunt ofwel alle bestanden apart "attachen",
of er een zip of tarfile van maken. Vergeet niet ook een listing op
papier te deponeren in de daarvoor bestemde doos "Programmeermethoden" in de
postkamer, kamer 156. Overal duidelijk datum en namen van de makers vermelden,
in het bijzonder in de eerste regels van de C++-code. Te gebruiken compiler:
Visual-C++, maar het programma zonder grafische interface moet ook op een
Linux-machine (met g++) draaien.
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.
1 november 2006 —
http://www.liacs.nl/home/kosters/pm/op4pm.html