Opdracht 7: Dodo s Race Algoritmisch Denken en Gestructureerd Programmeren (in Greenfoot) c 2017 Renske Smetsers-Weeda & Sjaak Smetsers 1 Inhoudsopgave Inleiding 1 Leerdoelen 1 Instructies 1 Theorie 2 7.1 Klasseconstante............................................... 2 Uitdagingen 4 7.1 Willekeurige bewegingen......................................... 4 7.2 Dodo scoort................................................. 4 7.3 Zoek het dichtstbijzijnde ei........................................ 5 7.4 Alle eieren uitbroeden, dichtsbijzijnde eerst.............................. 6 7.5 Dodo s Race................................................. 6 Reflectie 9 Opslaan en inleveren 10 1 Licensed under the Creative Commons Attribution 4.0 license: https://creativecommons.org/licenses/by/4.0/
Inleiding Wie kan de slimste Dodo maken? In deze opdracht ga je de strijd aan met jouw klasgenoten. Het idee is om het beste algoritme te bedenken en implementeren. In de vorige opgaven heb je zelf al aardig wat code geschreven en uitgevoerd. Nu ga je de dingen die je geleerd hebt combineren om een complexer programma te schrijven. Het is de bedoeling dat je zelf tot een zo goed mogelijk algoritme komt en dit implementeert. Om je op weg te helpen gaan we eerst samen een paar eenvoudige algoritmes implementeren. Zo kan je ideeën opdoen voor verbeteringen. We geven je een aantal scenario s waar je jouw Dodo mee kan testen. Bij de uiteindelijke wedstrijd zal een nieuw scenario gebruikt worden. Het doel is dus om een algoritme te bedenken dat generiek genoeg is om in een onbekend scenario nog steeds de slimste te zijn. In de vorige opdrachten heb je vooral geoefend met nieuwe principes. De code die je aan de mydodo klasse hebt toegevoegd heeft het scenario mogelijk wat onoverzichtelijk gemaakt. Verder zal je niet al die code nodig hebben voor deze opdracht. Daarom beginnen we in deze opdracht met een nieuw opgeschoond scenario. Als je straks een methode wilt gebruiken die je in een vorige opdracht al geschreven en getest hebt, mag je die natuurlijk gewoon kopiëren! Doelen Het doel van deze opdracht is: Slimme en complexe algoritmes implementeren. Leerdoelen Na het voltooien van deze opdracht kun je: random (willekeurige) getallen gebruiken om onvoorspelbaarheid toe te voegen; klasseconstantes (globale variabelen waarvan de waarde niet kan veranderen) gebruiken; een complex algoritme op splitsen in deeltaken en daarna te implementeren. Instructies Voor deze opdracht heb je het DodoScenario7 scenario nodig. Dit moet je downloaden. Tijdens de opdracht zul je wat vragen moeten beantwoorden. Je moet het volgende inleveren: Alle stroomdiagrammen: gebruik potlood en papier, of maak gebruik van de software op https: //www.draw.io/; Jouw code: het bestand MyDodo.java bevat al jouw code en moet ingeleverd worden; Het reflectieblad: vul in en lever het in. Je moet al jouw antwoorden met een partner te bespreken. Noteer kort jullie antwoorden. Er zijn drie soorten opgaven: Aanbevolen. Leerlingen met weinig programmeer ervaring of leerlingen die wat meer oefening nodig hebben moeten deze taken allemaal afmaken. Verplicht. Iedereen moet deze taken afmaken. Uitdagend. Complexere opgaven, ontwikkeld voor leerlingen die 2-ster opdrachten voltooid hebben en klaar zijn voor een grotere en onderzoekende uitdaging. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 1
Leerlingen die 1-ster opgaven overslaan moeten alle 3-ster opgaven maken. Opmerking: In deze opdracht moet je een kleine aanpassing maken in Mauritius, daarnaast mag je alleen aanpassingen maken in MyDodo; Je mag methodes gebruiken uit de MyDodo of Dodo klasse, maar niet uit de Actor klasse; Teleporteren is niet toegestaan: als Mimi ergens moet zijn, dan moet ze daar zelf stap voor stap heenlopen (ze mag er niet in één keer naar toe springen). Theorie Theorie 7.1: Klasseconstante Een klasseconstante is een globale variabele waarvan de waarde tijdens het uitvoeren van het programma niet kan veranderen. Je herkent een constante in de code aan static final. Klasseconstantes kunnen public of private zijn. Voorbeeld Een voorbeeld van de declaratie van een constante (bovenaan de klasse Mauritius) is: private static final int MAXWIDTH = 12; Deze constante is private. Daardoor is deze alleen te gebruiken binnen de klasse Mauritius zelf. Door de toevoeging final: is het onmogelijk om de waarde ergens anders in het programma te veranderen; ben je verplicht om zo n klasseconstante meteen een waarde te geven, dus direct bij de declaratie. De klasseconstante MAXWIDTH geeft de (maximale) breedte van de wereld aan. Hij heeft de waarde 12 waarmee we aangeven de wereld 12 cellen breed is. Als je een wereld van 40 bij 40 wil hebben kun je deze waarde eenvoudig aanpassen door in de declaratie 12 te vervangen door 40. Als je overal in de code verwijst naar MAXWIDTH in plaats van direct gebruik te maken van 12, dan zal jouw programma nog steeds prima werken in de grotere wereld. Zonder deze constante zou je alle voorkomens van 12 moeten gaan vervangen door bijvoorbeeld 40. Dit is niet alleen meer werk maar ook nog foutgevoelig. Stel je immers voor dat ergens in je programma de waarde 12 wordt gebruikt, maar dat hier niet de wereldbreedte mee bedoeld wordt, maar iets totaal anders. Het gebruik van klasseconstantes maakt het dus makkelijker om onze programma aan te passen. Naamgevingsafspraken van een klasseconstante De naam van een constante: is betekenisvol: het komt overeen met waar de constante voor gebruikt wordt; bestaat uit één of meer zelfstandige naamwoorden; bestaat uit letters, cijfers en _ : bevat geen spaties, komma s of andere rare tekens; is geschreven in hoofdletters: woorden worden gescheiden door een _ ; bijvoorbeeld: WORLD_FILE. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 2
Publieke constantes gebruiken vanuit andere klassen Klasseconstantes waarvan je hebt aangegeven dat ze public zijn kun je vanuit andere klassen aanroepen. Bijvoorbeeld, om gebruik te maken van de klasseconstante MAXSTEPS uit Mauritius gebruik je: Mauritius.MAXSTEPS. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 3
Uitdagingen Lees eerst Theorie 7.1: Klasseconstante. Opgave 7.1: Willekeurige bewegingen In deze taak laten we Mimi als een duizelige Dodo door haar wereld lopen. Dat wil zeggen, elke keer voordat ze een stap zet kiest ze een willekeurige (random) richting om naar te draaien en zet dan een stap in die richting. a) Het bepalen van een willekeurige richting kan met de Dodo-methode: public int randomdirection( ) Open de klasse Dodo en zoek deze methode op. b) Deze methode maakt gebruik van een standaard methode uit de Greenfoot bibliotheek, namelijk getrandomnumber. Alle Greenfoot methodes staan beschreven in de Greenfoot Class Documentation. Zoek deze methode op in de Greenfoot bibliotheek. Tip: Ga bovenin Greenfoot naar Help en dan Greenfoot Class Documentation. Via Index kun je makkelijk zoeken. c) Klik met je rechtermuisknop op Mimi en kies de Dodo methode randomdirection. Roep de methode een aantal keren aan en noteer steeds het resultaat. Wat valt je op? Wat heeft dit te maken met de parameter 4 die aan de methode getrandomnumber meegegeven wordt? d) Teken een hoog-niveau stroomdiagram waarmee Mimi willekeurige bewegingen maakt: in totaal zet ze 40 stapjes, vóór elke stap kiest ze een nieuwe willekeurige bewegingsrichting om daarna een stap in die richting te zetten. Voorkom dat Mimi van de wereld valt of tegen een hek opbotst door eerst te controleren of ze die stap ook echt kan zetten. e) Schrijf in MyDodo de bijbehorende methode moverandomly( ). Voeg (JavaDoc) commentaar toe. f) Test jouw methode met de rechtermuisknop. g) Je hebt nu de waarde 40 in jouw code staan. Hierdoor is jouw programma moeilijker om aan te passen. Het maximum aantal stapjes staat gedefinieerd in de Mauritius klasse met de klasseconstante MAXSTEPS. Gebruik MAXSTEPS in plaats van 40. Theorie 7.1 legt uit dat je hiervoor Mauritius.MAXSTEPS moet gebruiken. h) Test jouw programma opnieuw. Opgave 7.2: Dodo scoort Het spel is afgelopen zodra er een maximaal aantal stappen gezet is. We gebruiken een scorebord om aan te geven hoeveel stappen er nog gezet mogen worden en wat het puntenaantal is. Punten worden behaald door eieren op te pakken. a) Loop rond en pak eieren op: Voeg code toe aan jouw moverandomly( ) methode (uit taak 7.1) zodat Mimi eieren oppakt en haar puntenaantal bijhoudt: i) Als Mimi een ei tegenkomt dan pakt ze het op. Gebruik hiervoor pickupegg( ). ii) Voeg een variabele eggscore toe om het puntenaantal bij te houden. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 4
iii) Zorg er voor dat eggscore wordt aangepast zodra Mimi een ei oppakt. Tips: Elke keer als de pickupegg( ) methode aangeroepen wordt moet je het opgepakte ei in een Egg variabele opslaan (bijvoorbeeld Egg currentegg). Dit is nodig om de waarde straks te bepalen. Bepaal de waarde van een ei met currentegg.getvalue( ). Pas Mimi s eggscore aan met de waarde van het ei. iv) Misschien kun je een betekenisvollere naam bedenken voor de methode. b) Houd het aantal gezette stappen bij: Voeg een variabele toe om het aantal gezette stappen bij te houden. Zorg er voor dat deze wordt aangepast zodra Mimi een stap zet. c) Voeg de scorebord toe: We voegen een scorebord toe aan het scenario. Dat doe je als volgt: i) Open de klasse Mauritius en zoek in de constructor de aanroep van de methode addscoreboard ( ). Deze staat in commentaar. ii) Verwijder het commentaar zodat een scorebord wordt toegevoegd als de wereld gecreëerd wordt. iii) Zoals je in het scenario ziet is er onderin een scorebord toegevoegd. Hoeveel waarden staan er op het scorebord? iv) Dodo heeft ook een updatescores methode waarmee Mimi het scorebord kan aanpassen. Klik met je rechtermuisknop op Mimi en selecteer void updatescores(int score1, int score2 ) (geërfd van Dodo). Vul nu twee getallen als parameters in. Wat zie je gebeuren op het scorebord? Tip: De methode zit in het menu misschien verscholen achter meer methodes. d) Scorebord aanpassen: Zodra Mimi een stap heeft gezet of een ei heeft opgepakt, moet de scorebord aangepast worden. Roep void updatescores aan om de juiste waarden op het scorebord weer te geven. Tips: Let erop dat de eerste waarde aangeeft hoeveel stappen Mimi nog mag zetten (en dus niet hoeveel ze er al gezet heeft). Het aanpassen van de score doe je direct nadat de waarden zijn veranderd, ook als maar één van de waarden gewijzigd is (dus het puntentotaal en/of het aantal stappen). e) Test het programma door de methode aan te roepen zodat Mimi willekeurig door de wereld beweegt. Maak jouw test compleet: test ook met gouden eieren (5 punten) of een surprise-egg (willekeurig aantal punten). f) Als Mimi het maximaal aantal stappen gezet heeft is het spel afgelopen. Toon dan een compliment met haar behaalde score. Opgave 7.3: Zoek het dichtstbijzijnde ei Mimi is behoorlijk lui. Ze wil met zo weinig mogelijk moeite een van haar eieren vinden. Het makkelijkst is om naar het dichtstbijzijnde ei te lopen. Help jij haar dat te vinden? Taak: Schrijf een methode waarmee Mimi naar het dichtstbijzijnde ei loopt en dit oppakt. a) Gegeven het (deels ingevulde) stroomdiagram. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 5
Figuur 1: Stroomdiagram voor Zoek het dichtstbijzijnde ei b) Schrijf een submethode voor elke taak. Tips: Taak 1: Maak een lijst met alle eieren die in de wereld liggen (Eggs, GEEN surprise-eieren). Gebruik hiervoor een bestaande methode. Taak 2: Schrijf een methode die het dichtstbijzijnde Egg oplevert: i) Bepaal de variabelen die je voor je oplossing nodig hebt. ii) Schrijf een submethode die bepaalt hoeveel stapjes Mimi moet zetten om bij het ei te komen. Tip: misschien kun je code opnieuw gebruiken uit taak 6.9. iii) Druk voor elk ei zijn coördinaten en afstand af. Dit maakt het makkelijker om te testen of jouw methode juist werkt. iv) Test deze methode met de rechtermuisknop. Taak 3: Loop naar dat dichtstbijzijnde ei. Maak gebruik van jouw code uit taak 4.4. Taak 4: Raap het gevonden ei op. Maak hiervoor gebruik van een bestaande (Dodo) methode. c) Bedenk een geschikte methodenaam voor jouw totaaloplossing, dus voor alle deeltaken samen. d) Test jouw programma als één geheel. Opgave 7.4: Alle eieren uitbroeden, dichtsbijzijnde eerst Taak: Schrijf een methode waarmee Mimi steeds naar het dichtstbijzijnde ei loopt en dit oppakt, net zolang totdat alle eieren in de wereld uitgebroed zijn. Tips: Schrijf een submethode void pickupandremovenearestegginlist( List<Egg> egglist ) (vergelijkbaar met taak 7.3). Deze methode krijgt een egglist als argument, zoekt hierin het dichtsbijzijnde ei en verwijdert dit uit de lijst. Daarna loopt Mimi naar het gevonden ei en pakt het op. Schrijf een methode void repeatedlypickupnearestegginlist( ) die een lijst van eieren in de wereld opvraagt en de submethode pickupandremovenearestegginlist aanroept totdat er geen eieren meer zijn. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 6
Opgave 7.5: Dodo s Race Wie kan de slimste Mimi maken en de wedstrijd winnen? Om te winnen zul je waarschijnlijk nog wat extra slimmigheden in moeten bouwen. Hoe kun je Mimi nog slimmer maken? In de wereld ligt één gouden ei (5 punten waard) en 15 blauwe eieren (ieder één punt waard). Het einddoel van deze opdracht is om Mimi zo te programmeren dat ze zo veel mogelijk punten verdient door de eieren te zoeken en deze op te pakken. Mimi mag in totaal maar 40 stappen zetten. Als proef op de som testen wij jouw programma in een nieuwe, geheime wereld. Je resultaat zal worden vergeleken met die van jouw klasgenoten. Wie kan het beste algoritme bedenken? Taak: Help Mimi om zo veel mogelijk punten te halen door zo min mogelijk stappen te zetten. Ga gestructureerd te werk! Bedenk eerst een simpel algoritme en teken een stroomdiagram op hoog-niveau. Werk deeltaken uit in code en test ze los van elkaar. Als je een werkend programma hebt, voeg dan slimme verbeteringen toe en test jouw programma opnieuw na elke kleine aanpassing. De wedstrijd Uitgangspunten: In de wereld staan geen hekken of andere objecten, alleen één MyDodo object en een aantal Eggobjecten. In de wereld liggen 15 blauwe eieren en één gouden ei. Een gouden ei is vijf punten waard. Een blauw ei is één punt waard. Mimi mag hooguit 40 stappen zetten. Tijdens de echte wedstrijd wordt een (nu nog) onbekende wereld gebruikt. Regels voor de Race: Om de wedstrijd zo eerlijk mogelijk te maken gelden er voor deze opdracht een aantal regels. Mimi kan alleen verplaatst worden door gebruik te maken van de void move() methode in MyDodo. Wie de hoogste score bereikt wint de wedstrijd. Mimi mag hooguit 40 stappen zetten. Zorg ervoor dat je in Mauritius de constante int MAXSTEPS op 40 hebt staan. Nieuwe onderdelen Om de wedstrijd mogelijk en ook eerlijk te maken moet ons programma uitgebreid worden: Mimi moet gaan bijhouden hoeveel stappen ze gezet heeft; Mimi moet bijhouden wat haar score is; er is een scorebord dat het aantal stappen en de behaalde score laat zien; het spel moet stoppen zodra het gegeven maximum aantal stappen gezet is; Mimi verzamelt liefst zo veel mogelijk punten door eieren op te pakken;... en Mimi moet véél slimmer worden! Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 7
Voorbeeld werelden: Je kunt jouw algoritme uitproberen op de volgende werelden: world dodorace1 world dodorace2 world dodorace3 world dodorace4 Het kan handig zijn om zelf werelden te maken om mee te testen. Afronding en evaluatie Als je klaar ben met het implementeren van jouw oplossing, zorg er voor dat de code er netjes uitziet en voorzien is van (JavaDoc) commentaar. Kijk even terug op hoe het gegaan is: a) Wat ging er goed en wat minder? Wat vond je lastig om te doen? b) Hoe tevreden ben je over jouw oplossing? c) In welke situaties zal jouw algoritme minder goed werken? Wat is voor jou het worst-case scenario? Oftewel: welke scenario hoop je echt niet te krijgen tijdens de wedstrijd? d) In welke situaties zal jouw algoritme goed werken? Wat is voor jou het best-case scenario? Hoeveel stappen moet Mimi dan zetten? e) Waarom is jouw algoritme beter dan de algoritmes die je aan het begin van deze opdracht uitgewerkt hebt? f) Wat heb je geleerd van deze opdracht? g) Wat zou je volgende keer anders doen? h) Neem een foto van jouw voorbereidingen. Dat kan zijn: pseudocode, stroomdiagrammen, schetsjes of plaatjes op (klad) papier. Lever deze samen met jouw code in. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 8
Reflectie In deze opdracht heb je zelf een complex algoritme bedacht en geïmplementeerd. Ook heb je geleerd hoe je klasseconstantes kunt gebruiken in een programma. Je hebt gereflecteerd over jouw oplossing en aanpak. Als je ergens echt goed in wilt worden, is een van de meest belangrijke stappen om even terug te blikken op wat je deed en hoe dat ging: Resultaat Ik weet dat mijn oplossing werkt omdat... Ik ben trots op mijn oplossing omdat... Ik kan mijn oplossing verbeteren door... Aanpak Mijn aanpak was goed omdat... Wat ik volgende keer beter anders kan doen is... Geef met een smiley aan hoe het ging. Ik kan het Het is me een beetje gelukt maar ik begreep het niet helemaal Ik snapte er helemaal niks van Ik kan een klasseconstante gebruiken voor een variabele waarvan de waarde niet hoeft te veranderen. Ik kan random getallen gebruiken. Ik kan een complex algoritme opsplitsen in deeltaken en deze implementeren. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 9
Opslaan en inleveren Sla je werk op. Je hebt het nodig voor de volgende opdrachten. Opslaan Selecteer Scenario in het Greenfoot menu, en dan Save. Alle bestanden die bij het scenario horen zitten nu in één map. Inleveren Lever het volgende in: Naam: van jou (en je partner); Jouw code: Het MyDodo.jav java bestand; Stroomdiagrammen: Als je ze op papier hebt gemaakt: plak (foto s van) jouw stroomdiagrammen in een (Word) bestand. Als je software gebruikt hebt: sla het bestand op als.pdf of.jpg. Algoritmisch denken en gestructureerd programmeren (in Greenfoot) 10