Verder met programmeren
Met deze activiteiten bouwen leerlingen die al enige programmeerervaring hebben hun kennis uit.
Raadspelletje
Schrijf een eenvoudig raadspelletje
Het raadspel bevat verschillende onderdelen:
- Variabele N en randInt(), gebruikt om een getal te kiezen om te raden.
- Een Repeat-lus die steeds weer vraagt om een gok totdat de speler correct raadt.
- De instructie Prompt, gebruikt om een gok van de speler te krijgen.
- Voorwaardelijke If-opdrachten en Disp, gebruikt om aan de speler door te geven of een gok te hoog is of te laag.
- Variabele M en Disp: gebruikt om bij te houden en te melden hoeveel pogingen de gebruiker heeft gedaan.
Stap 1
Probeer dit eenvoudige raadspel in elkaar te zetten. Je creëert een nieuw programma met de naam ‘Guess’ en dan typ je de programmacode in je rekenmachine. Bedenk dat je bijna alle programmeerinstructies die je nodig hebt, kunt vinden in het menu programma-instructies onder de toets [PRGM]. De enige uitzondering is randInt(, dit kun je vinden onder het tabblad Prob van het menu Math ( [MATH] ).
Stap 2
Hoe het raadspel werkt
Het diagram (in het Engels) hiernaast is een stroomdiagram waarin je kunt zien hoe het programma werkt. Als je nog niet eerder een stroomdiagram hebt gezien: je leest het door de pijlen te volgen die om het diagram staan, te beginnen bij START en te eindigen bij Stop. Als je een minuutje gebruikt om dit diagram te vergelijken met de programmacode van prgmGUESS, zal je zien dat elk blok correspondeert met 1-3 regels van het programma.
Stap 3
Dit is regel voor regel hoe het programma werkt:
:randInt(1,50)→N
Kies een willekeurig getal tussen 1 en 50 en sla dat op in de variabele N. Elke keer dat het programma een nieuwe gok krijgt van de speler, zal het deze met N vergelijken om na te gaan of deze coorrect is.
:0→M
Sla het aantal keer dat geraden is op in de variabele M. Elke ker dat de speler opnieuw raadt, zal het programma 1 optellen bij M en dan M wergeven helemaal aan het eind van het programma.
Stap 4
:Repeat G=N
Herhaalt de regels tussen deze intsructie Repeat en de bijbehorende End tot dat G=N. In dit programmma, is G de gok van de gebruiker en N het doelgetal, dus de lus einigdt wanner de gok gelijk is aan het getal dat de speler probeert te raden. Het doelgetal is is het getal dat de speler probeert te raden.. Een special spitsvondigeheidje vanf Repeat: het controleert alleen de voorwaarde (G=N) nadat het de lus volledig heeft doolopen. Daarom hoeven we G niet te initialiseren dooer er een waarde, zoals 0, in op te slaan voordat de lus start. Als we een While-lus zouden gebruiken, zouden we G wel hebben moeten initialiseren omdat While de voorwaarde controleert voodat het de lus uit gaat voeren.
:Prompt G
Vraag de speler om een waarde voor G, en sla vervolgens het getal dat de speler intypt op in de variabele G.
Stap 5
:If G>N
:Disp "TE HOOG"
Als de geraden waarde G groter is dan het te raden getal B, toon dan TE HOOG zodat de speler weet dat hij lager moet gokken. De instructie If zal de volgende regel van het programma uitvoeren als de voorwaarde (G>N) waar is; Anders zal het deze overslaan,
:If G<n
:Disp "TE LAAG"
Vergelijkbaar, als het geraden getal G lager is dan het te raden getal G, tooy TE LAAG. Als G=N, zal de lus nog niet afgesloten zijn, maar evenmin zal de instructie Disp uitgevoerd worden, omdat G niet groter is dan N en G ook niet kleiener is dan N.</n
Stap 6
:M+1→M
Tel 1 op bij het aantal keer dat er geraden is.
:End
Beeindig de lus en controleer de Repeat-voorwaarde. Als de voorwaarde G=N onwaar os, voer dan de lus opnieuw uit, te beginnen bij Repeat. Als de voorwaarde waar is, ga dan door met de volgende regel van het programma na de End.
:Disp "GOEDE ANTWOORD NA"
:Disp M
:Disp "POGINGEN"
Toont drie regels, met het aantal keer dat geraden is. Je kunt dit verbeteren tot een enkele Disp-regel met komma’s.
Stap 7
Verder gaan: breid je spel uit
- Laat de speler het laagst en/of het hoogst mogelijke getal kiezen dat geraden moet worden. Het spel in deze les koos voor een getal tussen 1 en 50.
- Toon het interval waarbinnen de speler zou moeten raden: hier is dat tussen 1 en 50.
- Houdt een ‘high score’ bij (het laagste aantal keer dat geraden is). Je kunt ook andere statistieken bijhouden, zoals het gemiddelde aantal keer dat geraden is of de slechtste score (het hoogste aantal keer). Om informatie op meer permanente plaatsen op de slaan dan in de numerieke variabelen A-Z, bekijk je de informatie over aangepaste lijsten.
- Gebruik Input in plaats van Prompt om te vragen om een gok.
- Bedenk een manier om het scherm leeg te maken voordat het spel begint.
Je kunt natuurlijk ook je eigen fantasie gebruiken om te bedenken wat je allemaal nog meer voor mogelijkheden wilt toevoegen Succes!
Loop - lus met gebeurtenissen
Een letter over het hoofdscherm bewegen
Het programma dat we in deze les zullen maken is tamelijk kort, maar het brengt een aantal belangrijke programmeerconcepten bij elkaar. We bouwen een programma rond een lus met gebeurtenissen (event loop): een gedeelte met programmaregels dat steeds opnieuw wordt uitgevoerd en dat wacht op en reageert op gebeurtenissen. In dit programma, zijn toetsaanslagen de gebeurtenissen die we zoeken en ons programma zal reageren op deze gebeurtenissen door een letter over het beginscherm van de rekenmachine te laten bewegen. Lussen met gebeurtenissen in een computerprogramma kunnen wachten op een tijdstip of datum, een muisklik een toets op het toetsenbord of zelfs op data via het netwerk.
Stap 1
Lussen met gebeurtenissen en getKey
Het schema hiernaast laat (in het Engels) de basisstructuur zien van een programma gebaseerd op een lus (loop) met gebeurtenissen (event). Het voert de programmacode uit om een lus in te stellen, zoals het initialiseren van variabelen, vervolgens herhaalt het voortdurend de lus met gebeurtenissen totdat er een ontsnappingsvoorwaarde optreedt.
Er zijn drie hoofdcomponenten in een lus met gebeurtenissen:
- Een ontsnappingsvoorwaarde (escape condition) die definieert wanneer de lus stop zich te herhalen. In een computerprogramma, kan een ontsnappingsvoorwaarde zoiets zijn als het verlaten van het programma of het drukken op [ESC]. In ons programma zullen we controleren of de toets [CLEAR] wordt ingedrukt en onze ontsnappings-voorwaarde kan als volgt worden uitgedrukt “beëindig de lus met gebeurtenissen als op [CLEAR] wordt gedrukt”.
- Non-event code. In dit programma hebben we geen non-event code. In andere programma’s, echter, is dit programmacode die wordt uitgevoerd ongeacht of er gebeurtenissen optreden.
- Controleren (en reageren) op gebeurtenissen (check). In dit programma zijn onze gebeurtenissen toetsen waarop wordt gedrukt (toetsaanslagen). Als we willen controleren en reageren op toetsaanslagen, dan moeten we echter wel in staat zijn om delen van het programma uit te voeren of over te slaan afhankelijk van of er op een toets wordt gedrukt.
Stap 2
Om onze lus met gebeurtenissen te construeren hebben we voorwaardelijk opdrachten en getKey nodig.
getKey is een TI-BASIC-instructie die jouw programma’s kunnen gebruiken om na te gaan of een toets is ingedrukt. Als de gebruiker op een toets drukt na de laatste keer dat de instructie getKey is aangeroepen, dan zal getKey een getal tussen 11 en 105 teruggeven, dat aangeeft op welke toets is gedrukt (zie het diagram hieronder). Als er geen toets was ingedrukt dan geeft het een 0 terug. Anders dan Input (invoer) en Output (uitvoer), laat de instructie getKey het programma niet pauzeren zodat je complexere programma’s en games kunt creeeren.
Voorwaardelijke opdrachten maken het mogelijk aan te sturen of delen van het programma worden uitgevoerd. Voorwaardelijke opdrachten bestaan uit een voorwaarde die waar of onwaar kan zijn en programmacode die wordt uitgevoerd als de voorwaarde waar is. Voorwaarden kunnen er op je rekenmachine uitzien als If A>1 of If K=24 of If K=25 en B>1. Gelukkig doen deze precies wat je verwacht: de eerste is waar als de variabele A >1 is, de tweede is waar als K=24, en de derde is waar als zowel K=25 als B>1 waar zijn. De eenvoudigste vorm van een voorwaardelijke opdracht op je rekenmachine bestaat uit de voorwaarde op één regel, direct gevolgd door een tweede regel met programmacode die wordt uitgevoerd als de voorwaarde waar was of overgeslagen als de voorwaarde onwaar was. Je kunt ook complexere voorwaardelijke opdrachten creëren met behulp van If/Then/End en If/Then/Else/End.
Stap 3
Een letter laten bewegen over het beginscherm
Laten we het programma MOVECHAR verkennen. Het programma MOVECHAR is een van de eenvoudigste voorbeelden van een programma gebaseerd op een lus van gebeurtenissen, dat steeds ‘luistert’ of er toetsaanslagen zijn en dan daarop reageert.
Het stroomdiagram stelt het programma MOVECHAR voor. De lus van gebeurtenissen zelf loopt vanaf “Redraw M” tot “Check for keypresses” en dan weer terug rond naar “Redraw M”. De ontsnappingsvoorwaarde die we eerder bespraken was de voorwaarde om de lus van gebeurtenissen te verlaten: hier is, zoals je kunt zien, drukken op [CLEAR] de enige manier om de lus te verlaten.
Merk op dat als je de TI-83 Plus of TI-84 Plus gebruikt, de enige verschillen zitten in de waarden die gebruikt worden voor de randen van het beginscherm en het startpunt, vanwege de verschillen in de grootte van het beginscherm van elk van de rekenmachines.
Stap 4
Dit is regel-voor-regel hoe het programma werkt:
:13→A
:5→B
initialiseren de x- en y-coördinaten van de letter die getekend zal worden. We gebruiken niet de variabelen X en Y, omdat het besturingssysteem van de rekenmachine de variabele Y soms aanpast als je instructies van het grafiekenscherm gebruikt. In dit programma is A de x-coördinaat en B de y-coördinaat. Kolom 13, rij 5 is ongeveer in het midden van het beginscherm van de rekenmachine met kleur.
:WisHome
Wist het beginscherm.
:Repeat K=45
Herhaalt alle programmacode tussen Repeat en End (de lus van gebeurtenissen) totdat de variabele K gelijk is aan 45 (de toetscode voor [CLEAR]).
:Output(B,A,"M”)
Tekent de letter M op rij B, kolom A op het beginscherm. Als er al een M op het scherm stond op dezelfde coördinaten, dat tekent het daar eenvoudigweg overheen, zodat het scherm niet verandert.
:getKey→K
Haalt de toetscode op voor elke ingedrukte toets sinds de laatste keer dat getKey werd aangeroepen en slaat deze op in de variabele K. Dit geeft onmiddellijk een resultaat in plaats van eerst te wachten totdat er een toets is ingedrukt: als er geen toets werd ingedrukt, wordt 0 opgeslagen in K.
Stap 5
: If K≠0M
Als er een toets is ingedrukt willen we de letter die al op het scherm staat wissen, omdat we die mogelijk gaan verplaatsen. Als we de letter niet hadden gewist, dan zouden we een spoor van M-en achterlaten op het beginscherm.
:Output(B,A,"_”)
Tekent een spatie over de M die op het beginscherm stond en wist deze zo effectief. Deze programmaregel wordt alleen uitgevoerd als K niet nul is.
:If K=24 and A>1
:A-1→A
Bedienen de toets ‘pijltje naar links’ [←] met tietscode 24. Als het pijltje naar links werd ingedrukt willen we 1 aftrekken van de x-coördinaat zo dat de M een spatie naar links beweegt. We willen echter niet dat de M over de rand van het scherm valt. Daarom trekken we alleen 1 af van A en slaan die waarde weer op in A als zowel K=24 (het pijltje naar links is ingedrukt) en A>1 (de M stond niet al op de linker rand van het scherm).
Stap 6
If K=26 and A<26
:A+1→A
:If K=25 and B>1
:B-1→B
:If K=34 and B<10
:B+1→B
bedienen de pijltjestoetsen naar rechts, boven, omhoog en omlaag. Elke voorwaardelijke opdracht gaat zowel na of een pijltjestoets is ingedrukt als of de letter niet al aan de corresponderende rand van het scherm staat.
:End
loopt terug omhoog naar de instructie Repeat (herhaal) tenzij K=45. Als K gelijk is aan 45, dan zal de lus stoppen en, omdat dit de laatste regel van het programma is, zal het programma ook eindigen.
Stap 7
Verder gaan: MOVECHAR uitbreiden
Met dit eenvoudige programma met een ‘lus van gebeurtenissen’, dat luistert naar en reageert op toetsen, kun je veel leuke programma’s bouwen, in het bijzonder games.
- Een makkelijke plek om te beginnen is om iets anders dan een M over het scherm te bewegen. Misschien een andere letter? Of een groep letters in een vorm?
- Gebruik diagonale bewegingen zodat de letter nu in 8 richtingen kan bewegen in plaats van slechts 4. Omdat getKey niet kan registeren dat verschillende pijltjestoetsen te gelijk ingedrukt worden, kun je de toetsen 1-9 in plaats daarvan als pijltjes gebruiken (waarbij [ 2 ] omlaag is, [ 7 ] links omhoog etcetera).
- Als je bekend bent met het tekenen van tekst op het grafiekenscherm, probeer dan dit programma te verplaatsen naar het grafiekenscherm. Welke instructies moet je aanpassen en welke blijven hetzelfde? Wat zijn de nieuwe grenzen die je moet gebruiken om te zorgen dat de tekst niet van het scherm af loopt?
- Probeer het programma MOVECHAR aan te passen zodat het een ruimteschietspelletje wordt: de M kan je ruimteschip worden, en je kunt proberen om asteroïden neer te schieten voor ze je bereiken. Hoe kun je een wapen maken en bijhouden waar de asteroïden zijn en wat de score is. Je kunt natuurlijk ook je eigen fantasie gebruiken om te bedenken wat je allemaal nog meer voor mogelijkheden wilt toevoegen Succes!
Snake-spel
Een “Snake”-spel schrijven
Maak het Snake-programma (slang) op je rekenmachine als prgmSNAKE. Als je een rekenmachine met een kleurenscherm hebt, zoals de TI-84 Plus CE of TI-84 Plus C Silver Edition, kun je het programma precies zo invoeren als je hier ziet. Voor de TI-84 Plus en TI-84 moet je er rekening mee houden dat het beginscherm kleiner is.
Stap 1
Hier staat regel voorregel hoe het programma werkt:
ClrHome
Maak het beginscherm leeg.
13→A
5→B
10→X
1→P
26→D
Initialiseer alle variabelen die gebruikt gaan worden:
- A is de x-coördinaat van de kop van de slang, B is de y coördinaat van de kop. Rij 5, kolom 13 is ongeveer midden op het beginscherm van de TI-84+CE/TI-84+CSE’s.
- X is de lengte van de slang, hier is dat 10 segmenten. Als je hier een echt ‘snake’-spel van zou willen maken, zou je moeten starten met een kleine X en deze toe laten nemen wanneer de slag eet.
- P wijst naar het element dat de staart van de slang bevat. L1(P) is de y-coördinaat van de staart van de slang en L2(P) is de x-coördinaat ervan. Als de slang beweegt, beweegt P ook zodat deze altijd wijst naar het eind van de slang (zonder de gegevens in L1 en L2 naar voren te hoeven verplaatsen).
- D is de richting waarin de slang beweegt. Om de programmacode die je eerder hebt gezien opnieuw te gebruiken, gebruiken we de toetscodes voor omhoog, omlaag, links en rechts (respectievelijk 25, 34, 24, en 26) om de richting waarin de slang beweegt aan te geven.
Stap 2
X→dim(L1)
X→dim(L2)
Creëer twee lijsten, die elk X elementen lang zijn voor onze ‘circulaire buffers’ met coördinaten van de segmenten van de slang.
Stap 3
Opvullen(B,L1)
Opvulle(A,L2)
Vul de twee lijsten met de begincoördinaten. Op deze manier, zullen alle 10 de segmenten van de slang starten vanuit één enkele plek op het beginscherm en als het spel begint zal het lijken alsof de slang uit deze plek groeit tot zijn volledige lengte. Het is veel ingewikkelder om te zorgen dat de slang al meteen bij het begin op zijn volle lengte wordt getekend
Repeat K=45
Net zoals in les 2, wordt de belangrijkste lus met gebeurtenissen herhaald totdat gedrukt wordt op [CLEAR].
Output(L1(P),L2(P),"_”)
“Gum’ de staart van de slang uit. Omdat we circulaire buffers gebruiken, veranderen we P zo dat deze altijd wijst naar de elementen van L1 en L2 die de actuele staart van de slang bevatten. L1(P) is de y-coördinaat (de rij) van het laatste segment van de staart en L2(P) is de x-coördinaat (de kolom) van het laatste segment.
Stap 4
Output(B,A,"0
Teken de nieuwe kop. A en B bevatten altijd de coordinaten van de kop van de slang, en "O" ziet er toevallig gewoon mooi uit als segment van de slang. Je kunt in plaats daarvan elk teken gebruiken dat je wilt.
B→L1(P)
A→L2(P)
Sla de actuele coördinaten van de kop op in de circulaire buffers. Omdat P+1 bij de volgende iteratie naar de start zal wijzen, zal P dan naar de kop wijzen, we slaan deze dus op over de oude coördinaten van de staart bij P heen.
Stap 5
P+1-X(P=X→P)
Vernieuw P zodat deze wijst naar het volgende element van de lijsten. Als P kleiner is dan X dan is P=X onwaar (0) en wordt dit vereenvoudigd tot P+1→P.
Als P al wijst naar het laatste element van de circulaire buffers, wat betekent dat P=X, dan is P=X waar (1) en wordt dit vereenvoudigd tot P+1-X→P, of X+1-X→P, of 1→P. Dus, wanneer P het eind van de lijsten bereikt dan zal het vandaar opnieuw teruggaan naar het begin..
getKey→K
If max(K={24,25,26,34})
K→D
Hanteer toetsaanslagen. Zoals altijd, slaan we de toetsaanslag op in K, zodat de Repeat-voorwaarde K=45 kan zien of [CLEAR] ingedrukt is. De voorwaardelijke opdracht is kort en staat voor: Als K=24 of K=25 of K=26 of K=34. K={24,25,26,34} produceert een lijst met 4 elementen, die de elementen {K=24,K=25,K=26,K=34} bevat: dat is een reeks van enen en nullen. De instructie max() geeft de grootste waarde van een lijst terug, dus als K gelijk is aan een van deze vier getallen, dan zal er een 1 staan in de resulterende lijst en zal het maximum 1 zijn. Als K niet gelijk is aan een van deze vier toetscodes, dan zal de lijst gevuld worden met nullen en zal het maximum van de lijst 0 zijn.
Daarom geldt dat de voorwaarde alleen waar zal zijn als K gelijks ia aan een van deze vier toetscodes. Verder zal, als K de toetscode van een pijltjestoets bevat, D vernieuwd worden en een nieuwe richting voor de slang bevatten.
Stap 6
A+(D=26)-(D=24→A
B+(D=34)-(D=25→B
Gebruik de variabele D voor richting om de coördinaten van de kop te vernieuwen. Als D=26 of D=24, dan beweegt de kop van de slang zicht horizontaal. Vernieuw de A (de x-coördinaat) op dezelfde manier. Probeer D=26 en D=24 op de eerste regel in te voeren om te zien hoe dat werkt. De tweede regel vernieuwt B, de y-coördinaat van de kop als D=34 of D=25, wat betekent dat de kop op en neer beweegt.
A+26((A=0)-(A=27→A
B+10((B=0)-(B=11→B
De vorige twee regels zouden de kop van de slang over de randen van het scherm kunnen laten verdwijnen. Als we proberen een letter (karakter) te tekenen buiten de randen van het scherm, dan eindigt het programma met een ERR:DOMEIN, dus moeten we dit repareren. Deze twee regels ‘vouwen’ de kop rond de randen van het scherm. Bijvoorbeeld: als de kop aan de bovenkant van het scherm bereikt, zal deze in plaats daarvan opnieuw verschijnen aan de onderkant.
End
Loopt terug omhoog naar de instructie Repeat, tenzij K=45. Als K gelijk is aan 45 zal de lus eindigen en omdat dit de laatste regel van het programma is, zal het programma ook eindigen.
Stap 7
Verder gaan: een volledig “Snake”–spel maken
Het SNAKE-spel zoals gepresenteerd, bevat alles wat je nodig hebt om te beginnen met het bouwen van een “Snake” game. De drie grootste missende delen zijn: (1) een groeiende slang (2) een score en (3) voedsel om te eten. Hieronder staat wat je kunt doen om een “Snake” spel te maken van deze basisversie:
- Allereerst heb je een tweede variabele nodig om de ‘pointer’ voor de kop te hanteren. In deze versie hebben we P gebruikt voor het aanwijzen van zowel de kop als de staart, omdat de circulaire buffer altijd helemaal vol was. ,
- Vervolgens heb je circulaire buffers nodig die groter zijn dan de startgrootte van de slang, omdat de slang moet kunnen groeien. Dit brengt je bij een aantal interessante ontwerpbeslissingen: Moet je beginnen met lijsten die zo groot zijn als de slang kan worden? Of moet je de lijsten uitbreiden wanneer de slang het risico loopt om uit de buffers te groeien?
- Daarna heb je voedsel nodig dat de slang kan eten. Hoe zorg je dat je geen voedsel bovenop de slang plaatst? Een van de mogelijkheden is om de inhoud van het beginscherm op te slaan in een matrix zodat je eenvoudig kunt testen welke plekken op het beginscherm bezet zijn.
- Je zult moeten bepalen of de slang gaat eten of net heeft gegeten, zodat je de score en de lengte van de slang kunt ophogen en nieuw stuk voedsel kunt plaatsen.
- Je kunt nog verder gaan en zaken toevoegen zoals muren en verschillend ingerichte levels. Als je dit doet zou je serieus de matrixaanpak kunnen overwegen om eenvoudig te kunnen bepalen wanneer de slang een muur raakt of zijn eigen staart.
Je kunt natuurlijk ook je fantasie gebruiken om te bedenken wat je allemaal nog meer wilt toevoegen. Succes!