Programmeermethoden 2010
Derde programmeeropgave: Life-menu

De derde programmeeropgave van het vak Programmeermethoden in het najaar van 2010 heet Life-menu; zie ook het achtste werkcollege, en lees geregeld deze pagina op WWW.

Spreekuur in zalen 302 ... 309: dinsdag 26, woensdag 27, donderdag 28 oktober, dinsdag 2, woensdag 3, donderdag 4, dinsdag 9, woensdag 10, donderdag 11, dinsdag 16. woensdag 17, donderdag 18 en vrijdag 19 november 2010, van circa 15.30 tot 17.00 uur.

De opgave

Het is de bedoeling om een C++-programma te maken dat de gebruiker in staat stelt Life te spelen via een menu-systeem. Dat betekent dat de gebruiker van het programma kan kiezen uit een aantal mogelijkheden, de zogeheten opties. Er is één submenu, waarin ook weer opties zijn.
De opties worden gekozen door de eerste letter van de betreffende optie in te toetsen (gevolgd door Enter), bijvoorbeeld een s of S om te stoppen. Uiteraard wordt een en ander duidelijk en ondubbelzinnig aan de gebruiker meegedeeld. Gebruik geen recursie!

Van Wiki Alle door de gebruiker ingetoetste symbolen moeten gecontroleerd worden, dat wil zeggen dat er binnen redelijke grenzen geen foute invoer geaccepteerd wordt. Zo zal het intoetsen van bijvoorbeeld q of & in het hoofdmenu genegeerd worden. Verder moet bij getalleninvoer karakter voor karakter ingelezen worden (met cin.get ( ); als je elders ook nog cin >> ... gebruikt krijg je overigens soms problemen met "hangende Enter's"; gebruik dus overal cin.get ( )). Er moet ook op gelet worden dat er geen te grote getallen worden ingevoerd. Schrijf dus een geschikte functie leesgetal die de gelezen karakters (cijfers) omzet in een getal (tip: negeer alle "voorloop-Enter's"; verwerk alles tot en met de eerstvolgende enter, en maak hiervan zo goed mogelijk een getal, van een maximale grootte; zo wordt abc123defg999h, als je een getal kleiner dan 10000 wilt, bijvoorbeeld verwerkt tot 1239), en een functie leesoptie die netjes één karakter inleest en Enter's afhandelt! Aan de gebruiker mogen "redelijke" beperkingen worden gevraagd, bijvoorbeeld dat de in te voeren getallen maximaal vier cijfers hebben. Het programma moet dan echter wel bestand zijn tegen pogingen meer dan vier cijfers in te voeren. Ook het invoeren van letters in plaats van cijfers moet geen problemen opleveren. Houd het simpel!

Life is een cellulaire automaat, in 1970 bedacht door John Horton Conway. Zie verder het college, Wikipedia of hier, en deze implementatie. In een 2-dimensionaal (zeg) 1000 bij 1000 rooster, de wereld, beginnen we met een eindig aantal levende vakjes oftewel cellen. Een levend vakje met minder dan 2 of meer dan 3 buren van de 8 gaat dood (uit eenzaamheid of juist overbevolking), met precies 2 of 3 levende buren overleeft het. In een dood vakje met precies 3 levende buren ontstaat leven. Dit leidt tot de volgende generatie. Let erop dat dit voor alle vakjes tegelijk gebeurt.
Eigenlijk moet het geheel zich afspelen op een oneindig rooster, maar we kiezen voor de eindige variant. Om moeilijkheden te voorkomen, spreken we af dat de rand van onze wereld altijd uit dode cellen blijft bestaan.
De gebruiker ziet altijd een klein gedeelte van de wereld, de view geheten.

In het hoofdmenu zijn de volgende opties aanwezig:

  1. Stoppen.
  2. Schoon. Maak de view leeg (alle cellen gaan dood).
  3. Parameters. Dit leidt tot een submenu om de parameters in te stellen.
  4. File. Hier wordt een Life-configuratie uit een file ingelezen, en ingevoegd.
  5. Random. Vul de view met random dode en levende cellen. De rest van de wereld blijft onveranderd.
  6. Een. Er wordt één generatie gedaan.
  7. Gaan. Er worden een hele serie generaties gedaan — en allemaal getoond (zonder Enter's).
Steeds wordt de view getoond. Voor de optie Random moet een zelfgemaakte random-generator gebruikt worden, zie Hoofdstuk 3.9.3 uit het dictaat, gedeelte "aantekeningen bij de hoorcolleges". Iemand kan de hele wereld wijzigen door eerst de view heel groot te maken.

Er zijn verschillende parameters, in te stellen via het gelijknamige submenu:

  1. De hoogte en breedte van de view. Deze parameters, en met name de eerste, kunnen goed gebruikt worden om de view aan te passen aan de hoogte van het gebruikte window. Bij de optie Gaan kan dan een "vloeiend" beeld worden gemaakt.
  2. De coordinaten xlibo en ylibo van het meest linksboven gelegen punt van de view.
  3. Het aantal generaties dat bij Gaan gegenereerd moet worden.
  4. De vertraging geeft aan hoeveel tijd verloopt tussen het tonen van twee opeenvolgende generaties bij de optie Gaan. Maak een grote "zinloze" for-loop, die bijvoorbeeld double's met elkaar vermenigvuldigt, om tijd te rekken.
  5. Het percentage cellen dat levend moet zijn bij de optie Random (bij benadering).
  6. De twee karakters die op het scherm gebruikt worden voor levende en dode cellen.
Kies zelf redelijke grenswaarden voor al deze parameters, bijvoorbeeld om te voorkomen dat de view over de rand van de wereld uitsteekt.
En dan nog twee opties:
  1. Terug naar het hoofdmenu.
  2. Toggelen. In dit submenutje kan de gebruiker een zelfgekozen cel in de view omklappen ("toggelen"), tussen levend en dood; lees hiertoe diens twee coördinaten in.

Bij de optie File kan de gebruiker een file inlezen (controleer of deze bestaat!). Deze file wordt dan in de view gezet, vanaf het punt linksboven (of vanuit het punt hier direct rechtsonder), waarbij spaties als dode cellen worden opgevat. Regelovergangen ('\n') markeren overgangen naar de volgende rij in de view; "carriage returns" ('\r') worden genegeerd. Alle andere karakters representeren levende cellen. Deze file stelt een glider gun voor.
Overige cellen blijven onveranderd. De ingelezen cellen mogen eventueel buiten de view uitsteken (naar rechts en naar onder), om hele grote configuraties binnen te halen. Ze mogen natuurlijk niet buiten de wereld komen, en dergelijke grote files mogen naar believen worden afgehandeld.

De bedoeling is een klasse (class) Wereld te maken, met daarin onder meer functies die ieder voor zich een menuoptie afhandelen. De parameters zijn typisch membervariabelen. Gebruik nog geen eigen headerfiles, alles moet deze keer in één file staan.

Opmerkingen
Gebruik geschikte (member)functies. Bij deze opgave mogen bij elke functie (zelfs main) tussen begin-{ en eind-} hooguit circa 20 niet al te volle regels staan! Elke functie dient van commentaar voorzien te zijn. Let op goed parametergebruik: alle parameters, met uitzondering van membervariabelen, in de heading doorgeven, en de variabele-declaraties zowel bij main als bij de andere functies aan het begin. De enige te gebruiken headerfiles zijn in principe iostream, fstream, cstdlib en string. Zeer ruwe indicatie voor de lengte van het C++-programma: 400 regels. Denk aan het infoblokje.

Uiterste inleverdatum: vrijdag 19 november 2010, 17.00 uur.
BinnenhofHaagse studenten: maandagochtend 22 november 2010, 11.00 uur.
 

Manier van inleveren:

  1. Digitaal de C++-code inleveren: stuur een email naar pm@liacs.nl.
    Stuur geen executable's, lever alleen de C++-file digitaal in! Noem deze bij voorkeur zoiets als jansentilanus3.cc, dit voor de derde opdracht van het duo Jansen-Tilanus. De laatst voor de deadline ingeleverde versie wordt nagekeken.
  2. En ook een papieren versie van het verslag (inclusief de C++-code) deponeren in de speciaal daarvoor bestemde doos "Programmeermethoden" in de postkamer van Informatica, kamer 156 van het Snellius-gebouw.
    BinnenhofHaagse studenten: bij de docent.
     

    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 verslag (uiteraard weer in LaTeX, zie de eerdere opgaven) moet het volgende bevatten: een zeer korte beschrijving van het programma, een kort eigen onderzoekje waarin zelfgemaakte Life-configuraties worden bestudeerd (inclusief een plaatje; als voorbeeld: twee evenwijdige "lijnen" van m en n cellen, op afstand k), een beschrijving van punten waarop het programma faalt (indien van toepassing), en een tabel met gewerkte uren, uitgesplitst per week en per persoon. Geef ook minstens één nette referentie, bijvoorbeeld naar werk van Conway. Zie hier hoe je een plaatje verwerkt, en hoe een referentie gemaakt wordt (en zo ziet dat eruit).

Te gebruiken compiler: als hij maar C++ vertaalt; het programma moet in principe zowel op een Linux-machine (met g++) als onder Visual C++ of Dev-C++ draaien. Test dus in principe op beide systemen! Het programma wordt doorgaans nagekeken met behulp van de compiler die (uiteraard) in het commentaar bovenin het programma vermeld staat. Normering: layout 1; commentaar 2; modulariteit (OOP, functies) 3; werking 4. Eventuele aanvullingen en verbeteringen: lees deze WWW-bladzijde: www.liacs.nl/home/kosters/pm/op3pm.php.