design, write and debug programs that accomplish specific goals, including controlling or simulating physical systems; solve problems by decomposing them into smaller parts.
use logical reasoning to explain how some simple algorithms work and to detect and correct errors in algorithms and programs
6.2a
LO: To use and update variables in a program. (2)
We have seen how we can update the values referenced by variables, now we will look to see how to use conditional statements to how many attempts have been made - and when to stop the game when a limit is reached. Take a close look at the code for our game so far, what changes will we have to make to the structure of our program now that the game has two endings - winning (guessing the number) or losing (not guessing the number):
#declare a flag variable play = True #we say it is True because we want the game to start #declare a variable to reference our mystery number mystery_num = 14 #declare a variable to reference the number of guesses number_of_guesses = 0 #introduce print("This game will ask you to guess a mystery number between 0 and 20.") print("") #this is just a blank line to make it look clearer #start the game loop while play: #update the number of guesses by 1 number_of_guesses = number_of_guesses + 1 #get input user_input = input("Enter a number between 0 and 20 :") #cast to int guess = int(user_input) #compare the guess with mystery number if guess == mystery_num: play = False if guess > mystery_num: #respond to user print("Too big, try again") if guess < mystery_num: #respond to user print("Too small, try again") else: print("Well done, you guessed the mystery number!") print("The mystery number was", mystery_num) print("You guessed the number in", number_of_guesses, "guesses!") print("Thanks for playing.")
Before we even look at a way to limit the number of guesses in the game we have a problem - we end the game by breaking the game loop, that can only be done once and we now have two endings (win/lose).
What we need is a way of containing some code and only running it if the the user wins and having some other code run if the user loses - what could we possibly use???
Hopefully, the answer you was thinking of was to use a function - a way of containing code that is only run if, and when, the function is called. In our case we will need two functions - one will run if the user wins and one to run if the player loses:
#the winning function def win(): print("Well done, you guessed the mystery number!") print("The mystery number was", mystery_num) print("You guessed the number in", number_of_guesses, "guesses!") print("Thanks for playing.") #the losing function def lose(): print("Sorry, you didn't win this time.")
We now have two ways of responding to the user depending on the outcome of the game. We can call the winning function win() inside the if guess == mystery_num: statement - if the user guesses the correct number. We can call the losing function lose() inside the else: statement - we will check the number of huesses within the game loop. Let's have a look at how this new code will look:
#declare a flag variable play = True #we say it is True because we want the game to start #declare a variable to reference our mystery number mystery_num = 14 #declare a variable to reference the number of guesses number_of_guesses = 0 #define a function to call if the user wins def win(): print("Well done, you guessed the mystery number!") print("The mystery number was", mystery_num) print("You guessed the number in", number_of_guesses, "guesses!") print("Thanks for playing.") #define a function to call if the user loses def lose(): print("Sorry, you didn't win this time.") #introduce print("This game will ask you to guess a mystery number between 0 and 20.") print("") #this is just a blank line to make it look clearer #start the game loop while play: #update the number of guesses by 1 number_of_guesses = number_of_guesses + 1 #get input user_input = input("Enter a number between 0 and 20 :") #cast to int guess = int(user_input) #compare the guess with mystery number if guess == mystery_num: play = False #call the winning function win() if guess > mystery_num: #respond to user print("Too big, try again") if guess < mystery_num: #respond to user print("Too small, try again") else: #call the losing function lose()
You can try this code by running the 6_guessingGame_with_functions.py file from the Resources seection below. It has a bug in it - there are no errors but the program does not behave the way we want it to, if the user guesses the correct answer then the lose() function is called as well when the loop breaks, the instructions in the else: block are run!
Maybe we need to check how many guesses the user has had and then call the lose() function. Think about how we could use an if statement to check that the user has had less than 6 guesses (remembering that computers start counting at 0)...
How about this:
if number_of_guesses < 5: lose()
This would be the first thing we would test for in our game loop. Let's look how this would look now and make sure we end the game loop - notice that we no longer need the else statement:
#start the game loop while play: #check how many guesses the user has had if number_of_guesses > 5: #call the losing function lose() #end the play loop play = False #update the number of guesses by 1 number_of_guesses = number_of_guesses + 1 #get input user_input = input("Enter a number between 0 and 20 :") #cast to int guess = int(user_input) #compare the guess with mystery number if guess == mystery_num: play = False #call the winning function win() if guess > mystery_num: #respond to user print("Too big, try again") if guess < mystery_num: #respond to user print("Too small, try again")
If you edit your code and run this program you will notice that the lose() function is called ad then the game gives the user another go! Can you think why this has happened?
Back in 5.2b we learned that we could use a Boolean flag to start and stop a while loop - the loop would not run if the flag variable was False. In our game loop, changing the play flag variable to False will stop the game loop from running the next time. Here we have encountered a situataion where we want the while loop to stop before it has completed all the instructions inside of it, we want to break out of the loop at a certain point. To do this we can use the break command. This will end the loop there and then, the other instructions below it will not be carried out, the loop will not complete.
#start the game loop while play: #check how many guesses the user has had if number_of_guesses > 5: #call the losing function lose() #break out of the game loop now break #update the number of guesses by 1 number_of_guesses = number_of_guesses + 1 #get input user_input = input("Enter a number between 0 and 20 :") #cast to int guess = int(user_input) #compare the guess with mystery number if guess == mystery_num: play = False #call the winning function win() if guess > mystery_num: #respond to user print("Too big, try again") if guess < mystery_num: #respond to user print("Too small, try again")
Our program now works as we wanted it to. All that needs changing is the introduction to tell the user that they have to guess the mystery number in six guesses. The complete program is available below as 6_guessingGame_with_limit.py