Program Arcade Games
With Python And PygameChapter 4: Raadspelletjes met willekeurige getallen en lussen
De laatste stap voor we starten met graphics is het leren maken van lussen. De meeste spelletjes werken als een “lus.” Het programma herhaalt altijd maar de zelfde code opnieuw en opnieuw. Bevoorbeeld een spelletje waar je een getal moet raden vormt een lus voor elke keer de gebruiker een gokje waagt:
Hoi! Ik denk aan een getal tussen 1 en 100. --- Poging 1 Doe een gok naar aan welke getal ik denk: 50 Te hoog. --- Poging 2 Doe een gok naar aan welke getal ik denk: 25 Te hoog. --- Poging 3 Doe een gok naar aan welke getal ik denk: 17 Te hoog. --- Poging 4 Doe een gok naar aan welke getal ik denk: 9 Te laag. --- Poging 5 Doe een gok naar aan welke getal ik denk: 14 Te hoog. --- Poging 6 Doe een gok naar aan welke getal ik denk: 12 Te hoog. --- Poging 7 Doe een gok naar aan welke getal ik denk: 10 Te laag. Jammer, je aantal gokken zijn opgebruikt. Het getal was 11.
Wacht, wat heeft dit te maken met graphics en video games? Heel veel. Elk frame dat een spel toont gaat 1 keer door een lous. Je kent misschien frames-per-second (FPS) statistieken dat de spelletjes tonen. De FPS geven aan hoeveel keer dat de computer het scherm update per seconde. Hoe hoger het getal, hoe vlotter het spel werkt. (Alhoewel dat een FPS hoger dan 60 niet realistisch is omdat de meeste schermen deze snelheid niet aankunnen. Figuur 4.1 toont het spel Eve Online en een grafiek toont aan hoeveel frames per seconde de computer haalt.
De lus in deze spelletjes werken zoals een flowchart in Figuur 4.2. Ondanks de complexiteit in de moderne spelletjes is de lus eigenlijk dezelfde als die in de oefening met de rekenmachine van hoofdstuk 1. Vraag input van de gebruiker. Doe je bewerkingen en geef output. In videospelletjes herhalen we dit tot 60 keer per seconde.
Er kunnen zelfs lussen zijn in andere lussen. Een echte “lus in lus.” Kijk eens naar de “Draw Everything” box in Figure 4.2. Deze code is een reeks van lus dat elke keer opnieuw de objecten tekent in het spel. De lus is in een andere lus dat elke keer opnieuw het voledige frame tekent, zoals in Figuur 4.3.
Er zijn twee manieren om lussen te maken in Python, for lussen en while lussen. Wanneer je iets een aantal keer wil herhalen dan gebruik je een for lus. Wanneer je iets wil herhalen tot er iets gebeurt (vb user klikt op quit) gebruik je een while lus.
Bijvoorbeeld, een for lus kan gebruikt worden om alle studenten af te drukken wanneer je weet over hoeveel studenten het gaat. Een while lus zou je kunnen gebruiken om na te kijken wanneer de gebruiker op de muis klikt omdat de computer niet weet hoe lang hij moet wachten.
4.1 For Lussen
De for lus toont hieronder het print statement vijf keer. Het kan heel eenvoudig worden aangepast om 100 of 1,000,000 keer te lopen door het getal 5 te wijzigen in het gewenste aantal keer dat je de herhaling wil zien. Merk op dat er veel gelijkenis is tussen de manier waarop we een for lus schrijven met de manier van een if statement. Beide eindigen met een dubbele punt en beide gebruiken het inspringen om de lijnen aan te duiden die beivloed worden door het statement.
for i in range(5): print ("Ik zal niet snoepen in de klas.") |
Output:
Ik zal niet snoepen in de klas. Ik zal niet snoepen in de klas. Ik zal niet snoepen in de klas. Ik zal niet snoepen in de klas. Ik zal niet snoepen in de klas. |
De i van lijn 1 is een variabele dat bijhoudt hoeveel keer een stuk coding moet herhaald worden. Het is een nieuwe variabele en kan eender welke (correcte) naam krijgen. Programmeurs gebruiken meestal i als variabele omdat i de afkorting is van increment (verhoging).
De range functie heeft de controle van hoeveel keer de code moet herhaalt worden in de lus. In dit geval 5 keer.
Het volgende voorbeeld print “Asjeblief,” 5 keer en “Mag ik naar de kermis?” slechts 1 keer. “Mag ik naar de kermis?” werd niet ingesprongen, is geen deel van de for lus en zal pas geprint worden na de for lus is beindigd.
for i in range(5): print ("Asjeblief,") print ("Mag ik naar de kermis?") |
Output:
Asjeblief, Asjeblief, Asjeblief, Asjeblief, Asjeblief, Mag ik naar de kermis? |
Het volgende voorbeeld start van het vorige en voegt lijn 3 toe. Deze wijziging zal ervoor zorgen dat het programma zowel “Asjeblief," als "Mag ik naar de kermis?” vijf maal print. Omdat het statement “Mag ik naar de kermis?” ook inspringt is het een deel van de for lus en wordt het eveneens vijf keer geprint zoals de lijn “Asjeblief,".
for i in range(5): print ("Asjeblief,") print ("Mag ik naar de kermis?") |
Output:
Asjeblief, Mag ik naar de kermis? Asjeblief, Mag ik naar de kermis? Asjeblief, Mag ik naar de kermis? Asjeblief, Mag ik naar de kermis? Asjeblief, Mag ik naar de kermis? |
De code hieronder zal de getallen van 0 tot 9 printen. Merk op dat de lus start bij 0 en niet bij het getal 10. Het is normaal te veronderstellen dat range(10) ook het getal 10 bevat, maar het stopt er juist voor.
for i in range(10): print(i) |
Output:
0 1 2 3 4 5 6 7 8 9 |
Het programma moet de variabele i niet gebruiken, maar het kan eender welke naam gebruiken. Bijvoorbeeld kan een programmeur lijnnummer gebruiken als er een tekstbestand wordt afgelopen.
Als de programmeur wil dat er van 1 tot 10 wordt gegaan in plaats van 0 tot 9, dan heeft hij daarvoor een aantal manieren om dit te doen. De eerste manier is om 2 parameters mee te geven met de range functie. Het eerste getal is de startwaarde en het tweede getal is de eindwaarde.
Het vraagt wel enige oefening om te weten dat bij de for lus het eerste getal wel in de lus hoort en het tweede getal net niet. Het voorbeeld hieronder toont de range van (1,11), en de getallen 1 tot 10 worden geprint. De startwaarde 1 hoort erbij maar de eindwaarde 11 niet.
for i in range(1,11): print(i) |
Output:
1 2 3 4 5 6 7 8 9 10 |
Een andere manier om de getallen van 1 tot 10 te printen is toch met de range(10) en met de variabele i die gaat van 0 tot 9. Maar we gaan juist voor het printen van een optellen bij de variabelel i zodat er van 1 tot 10 wordt afgeprint. Beide manieren zijn correct.
# Print the numbers 1 to 10. for i in range(10): print(i + 1)
4.1.1 Optellen van getallen met meer dan 1
Als het programma nood heeft om per 2 op te tellen, dat is dit eigenlijk ook eenvoudig. Net zoals daarstraks zijn er 2 manieren om dit te doen. Het gemakkelijkste is om een derde parameter te voorzien in de range functie door te zeggen dat er per twee moet gesprongen worden. De tweede manier is door telkens de variabele te verhogen met 1 maar deze nadien te vermenigvuldigen met 2. De code hieronder toont de 2 manieren.
# twee manieren voor het printen van de even getallen van 2 tot 10 for i in range(2,12,2): print(i) for i in range(5): print ((i + 1) * 2) |
Output:
2 4 6 8 10 2 4 6 8 10 |
Het is ook mogelijk om de teller te laten verminderen naar nul door een in de range functie een negatieve waarde mee te geven. In het voorbeeld hieronder starten we bij 10 en tellen we af tot net voor 0 met stappen van -1. Het moeilijkste deel van deze lus is het verwisselen van de startwaarde en de eindwaarde. Het programma start met een hogere waarde naar een kleinere in plaats van omgekeerd.
for i in range(10,0,-1): print(i) |
Output:
10 9 8 7 6 5 4 3 2 1 |
Als de getallen dat een programma nodig heeft geen echt patroon vormen is het ook mogelijk om deze uit een lijst te halen.
for i in [2,6,4,2,4,6,7,4]: print(i)
Dit print:
2 6 4 2 4 6 7 4
4.1.2 Geneste Lussen
Probeer te voorspellen wat het resultaat van deze code zou kunnen zijn? Geef de code in en zie of ze correct is.
# Wat wordt hier geprint? Waarom? for i in range(3): print ("a") for j in range(3): print ("b")
De volgende codeblok is bijna dezelfde als die erboven. De tweede for lus is alleen ingesprongen vanaf de vorige insprong en dat betekend dat het over een geneste lus gaat binnen de eerste lus. Dit heeft wel een serieuze impact op hoe de code draait. Probeer maar eens.
# Wat wordt er nu geprint? Waarom? for i in range(3): print("a") for j in range(3): print("b") print("Einde")
Ik ga je niet vertellen wat er gebeurt. Voer het in een kijk.
4.1.3 Bijhouden van een totaal
Een veelvoorkomende operatie bij het werken met lussen is het bijhouden van een totaal. Het ”bijhouden van een totaal” wordt heel veel gebruikt. Het bijhouden van de score, Het bijhouden van het saldo van een rekening, gebruik het totaal om het gemiddelde te zoeken, enz. In de onderstaande code, geeft de gebruiker vijf getallen in en worden deze steeds bij het totaal geteld.
total = 0 for i in range(5): newNumber = int(input("Geef een getal: " )) total += newNumber print("Het totaal is: ",total)
Merk op dat lijn 1 de variabele total creert en de initiele waard op nul zet. Het is gemakkelijk om het creeren en initialiseren van een variabele te vergeten. Indien je dit niet doet zal de computer protesteren wanneer hij aan lijn 4 komt. Hij weet namelijk niet hoe hij newNumber bij total moet bijtellen want total heeft nog geen waarde gekregen.
Een veelvoorkomende fout is i optellen bij total in plaats van newNumber. Denk eraan dat we het totaal willen bijhouden van alle waarden dat de gebruiker heeft ingevuld en niet het totaal van het aantal keren dat de lus doorlopen wordt.
Omdat we nu toch spreken van de teller van de lus, kunnen we deze gaan gebruiken om wiskundige bewerkingen op te lossen. Bijvoorbeeld:
$s=\sum\limits_{n=1}^{100}n$
Het is geen probleme als je (nog) niet gewoon bent aan deze schrijfwijze. Het is gewoon een leuke manier om het volgende te bedoelen :
$s=1+2+3+4+5 \ldots 98+99+100$
De code hieronder voegt alle getallen bij elkaar van 1 tot 100. Het demonstreert een manier om het totaal bij te houden in een lus. Er wordt ook een aparte variabele sum gebruikt om het totaal bij te houden.
# Wat is de waarde van sum? sum = 0 for i in range(1,101): sum = sum + i print(sum)
Hier volgt een andere manier. Hier wordt er vijf keer aan de gebruiker gevraagd om een getal in te geven en we tellen het aantal keer dat de gebruiker nul ingeeft :
total = 0 for i in range(5): newNumber = int(input( "Geef een getal: ")) if newNumber == 0: total += 1 print("Je hebt in totaal ",total," keer nul ingegeven")
Een programmeur dat begrijpt hoe een geneste for lus werkt en weet hoe het bijhouden van een totaal werkt zou het resultaat van de code hieronder moeten kunnen voorspellen.
# Wat is de waarde van a? a = 0 for i in range(10): a=a+1 print(a) # Wat is de waarde van a? a = 0 for i in range(10): a = a + 1 for j in range(10): a = a + 1 print(a) # Wat is de waarde van a? a = 0 for i in range(10): a = a + 1 for j in range(10): a = a + 1 print(a)
Ga niet te snel over deze alinea. Probeer het en voorspel het resultaat van de code hierboven. Copieer dan het Python programma en laat het lopen om te zien of je gelijk had. Indien dit niet zo is zoek je uit waarom.
4.2 Voorbeeld for Lussen
Dit voorbeeld toont meerdere for lussen en toont hoe ze werken.
# Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Print 'Hi' 10 times for i in range(10): print("Hi") # Print 'Hello' 5 times and 'There' once for i in range(5): print("Hello") print("There") # Print 'Hello' 'There' 5 times for i in range(5): print("Hello") print("There") # Print the numbers 0 to 9 for i in range(10): print(i) # Two ways to print the numbers 1 to 10 for i in range(1, 11): print(i) for i in range(10): print(i + 1) # Two ways to print the even numbers 2 to 10 for i in range(2, 12, 2): print(i) for i in range(5): print((i + 1) * 2) # Count down from 10 down to 1 (not zero) for i in range(10, 0, -1): print(i) # Print numbers out of a list for i in [2, 6, 4, 2, 4, 6, 7, 4]: print(i) # What does this print? Why? for i in range(3): print("a") for j in range(3): print("b") # What is the value of a? a = 0 for i in range(10): a = a + 1 print(a) # What is the value of a? a = 0 for i in range(10): a = a + 1 for j in range(10): a = a + 1 print(a) # What is the value of a? a = 0 for i in range(10): a = a + 1 for j in range(10): a = a + 1 print(a) # What is the value of sum? sum = 0 for i in range(1, 101): sum = sum + i
4.3 While Lussen
Een for lus wordt gebruikt wanneer het programma weet hoeveel keer een bepaald stukje coding moet herhaald worden. Een while lus wordt gebruikt wanneer een programma een bepaalde lus moet uitvoeren tot er zich een bepaalde conditie voordoet.
Het is misschien raar maar een while lus kan gebruikt worden telkens wanneer een for lus nodig is. Het kan gebruikt worden om een lus te maken tot wanneer een variabele de juiste waarde heeft gekregen door deze telkens met 1 te verhogen. Waarom hebben we dan een for lus als de while lu alles kan? De for lus is simpeler in het gebruik en om te programmeren. Een for lus kan er als volgt uitzien :
for i in range(10): print(i)
...met een while lus ziet dat er zo uit :
i = 0 while i < 10: print(i) i = i + 1
Lijn 1 van de while lus bevat een “sentinel” (schildwacht) variabele die zal gebruikt worden om te kijken hoeveel keer de lus uitgevoerd wordt. Dit gebeurt automatisch in de for lus. Lijn 2 bevat de actuele while lus. Het formaat van de while lus is zeer gelijkaardige aan een if statement. Zolang de condition niet gebeurt, wordt de code van de lus opnieuw uitgevoerd. Lijn 4 verhoogtde waarde met 1. In een for lus gebeurt dit automatisch, wat opnieuw voor een codelijn minder zorgt. Zoals je kan zien is de code van een for lus meer compact dan die van een while lus en is ze gemakkelijker te lezen. Anderzijds zou je wel altijd een while kunnen gebruiken.
Een veelvoorkomende fout is het verwarren tussen een for lus en een while lus. De code hieronder toont een programmeur die het verschil niet goed kan maken tussen een for lus en een while lus.
while range(10): print(i)
De range functie werkt alleen met een for lus. Gebruik ze niet met een while lus!
4.3.1 Gebruik van de optel operator
Optel operatoren worden veel gebruikt in while lussen. Het is mogelijk om de code :
i = i + 1
korter te schrijven als volgt :
i += 1
In de while lus zou het er als volgt uitzien :
i = 0 while i < 10: print(i) i += 1
Dit kan ook met aftrekkingen en vermenigvuldigingen. Bijvoorbeeld :
i *= 2
Is hetzelfde als :
i = i * 2
Kijk of je kan vinden wat het volgende uitprint :
i = 1 while i <= 2 ** 32: print(i) i *= 2
4.3.2 Blijf in de lus tot de gebruiker wil stoppen
Een veel voorkomende bewerking is om te blijven herhalen tot wanneer de gebruiker vraagt om te stoppen :
quit = "n" while quit == "n": quit = input ("Wil je stoppen? ")
Er zijn verschillende manieren om te stoppen. Je kan gebruik maken van een booleaanse variabele zoals hieronder :
done = False while not done: quit = input ("Wil je stoppen? ") if quit == "j" : done = True; attack = input ("Wil je de draak aanvallen? ") if attack == "j": print ("Jammer, je bent dood.") done = True;
Dit is geen perfecte code want als de gebruiker vraagt om te stoppen, wordt er toch nog gevraagd of de draak moet aangevallen worden. Hoe kan je dit oplossen?
Hier zie je een voorbeeld door gebruik te maken van een while lus waar de code herhaalt wordt tot de waarde in de buurt komt van nul :
value = 0 increment = 0.5 while value < 0.999: value += increment increment *= 0.5 print(value)
4.3.3 Veelvoorkomende problemen met while Lussen
De programmeur wil aftellen tot 10. Wat is er fout en hoe kan je het oplossen?
i = 10 while i == 0: print (i) i -= 1
Wat is er fout met deze lus die probeert te tellen tot 10. Wat gebeurt er wanneer je het programma start? Hoe kan je dit oplossen?
i = 1 while i < 10: print (i)
4.4 Voorbeeld while Lussen
Hier is een programma dat de verschillende while lussen toont die we net hebben besproken.
# Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # A while loop can be used anywhere a for loop is used: i = 0 while i < 10: print(i) i = i + 1 # This is the same as: for i in range(10): print(i) # It is possible to short hand the code: # i = i + 1 # With the following: # i += 1 # This can be done with subtraction, and multiplication as well. i = 0 while i < 10: print(i) i += 1 # What would this print? i = 1 while i <= 2**32: print(i) i *= 2 # A very common operation is to loop until the user performs # a request to quit quit = "n" while quit == "n": quit = input("Do you want to quit? ") # There may be several ways for a loop to quit. Using a boolean # to trigger the event is a way of handling that. done = False while not done: quit = input("Do you want to quit? ") if quit == "y": done = True attack = input("Does your elf attach the dragon? ") if attack == "y": print("Bad choice, you died.") done = True value = 0 increment = 0.5 while value < 0.999: value += increment increment *= 0.5 print(value) # -- Common problems with while loops -- # The programmer wants to count down from 10 # What is wrong and how to fix it? i = 10 while i == 0: print(i) i -= 1 # What is wrong with this loop that tries # to count to 10? What will happen when it is run? i = 1 while i < 10: print(i)
4.5 Willekeurige getallen
Willekeurige getallen worden veel gebruikt voor spelletjes en simulaties.
4.5.1 De randrange Functie
Standaard weet Python niet hoe hij een willekeurg getal moet maken. Het is noodzakelijk dat Python een code library (bibliotheek) importeert om willekeurige getallen te kunnen aanmaken. Dus wanneer je wil gebruik maken van willekeurige getallen dan moet je eerst bovenaan je programma het import statement vermelden :
import random
Net zoals met pygame, is het belangrijk om geen bestand aan te maken met dezelfde naam als wat je wil importeren. Het aanmaken van een bestand random.py zal ervoor zorgen dat Python dit bestand zal importeren in plaats van de systeem library die nodig is voor het creeren van willekeurige getallen.
Willekeurige getallen kunnen worden gecreerd met de randrange functie. Bijvoorbeeld, Deze code genereert de willekeurige getalle, van 0 tot 49. Standaard is de ondergrens 0.
my_number = random.randrange(50)
Het volgende voorbeeld genereert willekeurige getallen van 100 tot 200. The next code example generates random numbers from 100 to 200. Net zoals de range functie is de tweede parameter de bovengrens zonder het getal zelf. Daarom moet je 201 als bovengrens ingeven als het getal 200 er bij moet zijn.
my_number = random.randrange(100,201)
Wanneer een programma een willekeurig element wil kiezen uit een lijst is dit zeer gemakkelijk :
my_list = ["rock","paper","scissors"] random_index = random.randrange(3) print(my_list[random_index])
4.5.2 De random Functie
Alle bovenstaande code genereert gehele getallen. Wanneer er een reeel getal nodig is kan de gebruiker gebruik maken van de random functie.
De code hieronder genereert een random getal van 0 tot 1 zoals 0.4355991106620656.
my_number=random.random()
Met wat simpeler wiskunde kunnen we dit getal aanpassen. De code hieronder bevoorbeeld genereert een reeel getal tussen 10 en 15 :
my_number=random.random()*5+10
4.6 Niet-lus herhalingsvragen
- Doorstreep de variabelen die niet geldig zijn in Python.
pi PI fred Fred GreatBigVariable greatBigVariable great_big_variable great.big.variable 2x x2x total% #left
- Omcirkel de variabelnamen die geldig zijn, maar niet aan te raden.
pi PI fred Fred GreatBigVariable greatBigVariable great_big_variable great.big.variable 2x x2x total% #left
- Geef een voorbeeld van een Python uitdrukking (expression):
- Wat is een “operator” in Python?
- Wat print het volgende programma?
x = 3 x + 1 print(x)
- Verbeter de volgende code:
user_name = input("Enter your name: )"
- Verbeter de volgende code:
value = int(input(print("Enter your age")))
- Verbeter de volgende code:
temperature = float (input("Temperature")) if temperature > = 90 print("It is hot outside.")
- Verbeter de volgende code:
print("Welcome to Oregon Trail!") userInput = input("What is your occupation?") print("A. Banker") print("B. Carpenter") print("C. Farmer") if userInput = A: money = 100 else if userInput = B: money = 70 else if userInput = C: money = 50
- Wat is er fout met deze code?
x = input("Enter a number:") if x > 100 print ("You entered a large number.") else print ("You didn't enter a large number.")
- Schrijf een programma dat de gebruiker vraagt hoeveel euromunten en eurocenten ze hebben. Dan print je de som van al het geld in eurocent.
4.7 Herhalingsvragen over lussen
Click here for a multiple-choice review quiz.
- Schrijf een Python programma dat gebruik maakt van een for lus om je naam 10 keer te printen gevolgd door 1 keer het woord einde om af te sluiten.
- Schrijf een Python programma dat gebruik maakt van een for lus om 20 keer "Red" en dan "Gold" te printen.
- Schrijf een Python programma dat gebruik maakt van een for lus om de even getallen van 2 tot 100 te printen, inclusief 100.
- Schrijf een Python programma dat gebruik maakt van een while lus om af te tellen van 10 tot 0 inclusief 0 en dan gevolgd door het woord "ontploft!"
- Er zijn vier dingen fout met dit programma. Vind en verbeter ze.
print("This program takes three numbers and returns the sum.") total = 0 for i in range(3): x = input("Enter a number: ") total = total + i print("The total is:",x)
- Schrijf een Python programma dat:
- de gebruiker vraagt naar 7 getallen
- de totale som van de getallen afdrukt.
- het aantal keer dat er een positief getal werd ingegeven, het aantal keer dat er een egatief getal werd ingegeven en het aantal keer dat er nul werd ingegeven.
4.8 Willekeurige getallen Herhalingsvragen
- Schrijf een programma dat willekeurige gehele getallen print tussen 1 en 10 (inclusief).
- Schrijf een programma dat een willekeurig reele getal print tussen 1 en 10 (inclusief).
- Kop-of-munt.
- Maak een programma dat kiest tussen 0 of 1.
- In plaats van 0 of 1, print kop of munt.
- Voeg een lus toe dat het programma 50 keer uitvoert.
- maak een totaal voor het aantal keer kop en voor het aantal keer munt.
- Schrijf een programma steen - schaar - papier
- Maak een programma dat random 0, 1, of 2 print.
- Pas het programma aan zodat het random schaar, steen, papier door gebruik te maken van een if statements. Gebruik geen lijst, zoals beschreven in het hoofdstuk.
- Voeg de keuze van de gebruiker toe aan het programma.
- Het zal gemakkelijker zijn als je hem vraagt om 1, 2, of 3 in te geven.
- Voeg condities toe om te zien wie er wint.
You are not logged in. Log in here and track your progress.
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin