Python Project: Guessing Game
Renan Moura
Posted on January 4, 2021
This numbers guessing game is a simple game that allows you to practice many of the fundamentals of the Python language.
It is a great Python project for beginners and in this article, you will find not only the source code but also an explanation of how it works.
The game works like this:
- You choose a level: 1 (25 chances), 2 (15 chances), 3 (5 chances)
- The game will randomly pick a number from 1 to 1000
- In every turn, you pick a number
- The game will always tell you if your guess was lower or higher than the right number
- You win if you guess the right number before you run out of chances
- The game saves the highest score in a file named "score.txt".
Prerequisites
Although simple, this game involves many basic programming skills, and if you have any trouble following this code, don't worry, there is an article for every single thing you should know on this list:
- if name == ‘main’ in Python
- How to generate a random value between two integers in Python
- Conditionals in Python
- Functions in Python
while
Loops in Pythonfor
Loops in Python- String Interpolation with f-strings in Python
- User input in the command line in Python
- File Handling in Python
- Handling Exceptions in Python
The Game
My suggestion is to open a text editor like VSCode, copy and paste the code, or open this article in another browser window, and put it side by side with this window, this way you can read the explanation while following along with the code.
The code starts at the bottom, on the main block.
Choose a level: choose_level()
function
It calls the function choose_level()
on the main block and goes to the beginning of the code where the actual function choose_level()
is and where you pick a level and get the number of chances accordingly.
The input()
function is inside a while
loop that only breaks if you pick a valid integer, otherwise, it will catch the error with the try/except
block and print "Invalid choice", restarting the while
loop so the user can choose a level again.
If the input is valid, but not 1 or 2 or 3, the if
block will print "Not a valid level." and restart the loop using continue
so the user can choose a level again.
If the input is valid and either 1 or 2 or 3, the program moves on.
The core of the Game: play_game(chances)
function
Then the play_game(chances)
function is called on the main block with the number of chances returned from choose_level()
as an argument and the program goes to the implementation of play_game(chances)
.
Initializing the game
play_game(chances)
starts by picking a random number from 1 to 1000 and by initializing the number of points to 9999.
The for
loop uses the range(1, chances + 1)
function giving a turn starting at 1 and going up until the number of chances you chose based on the difficulty level.
Note that range()
does not include the number of the second argument, meaning that if you have 25 chances, it will only go until 24, that's why we have to make "chances + 1".
The code then uses f-strings to print your current turn and how many chances you have.
Receiving input from the player
Then you guess a number with the input()
function inside a while
loop.
Note the try/except
that catches an exception in case the user tries a value that's different from an int
.
If the value is invalid, the except block catches the error, prints "Invalid guess." and the while
loop restarts.
If you chose a valid value but it isn't between 1 and 1000, the if
block will be triggered, print a message, and use continue
to restart the loop.
If you choose a valid number that is between 1 and 1000, the break
command will be triggered, breaking out the while
loop, and the program then proceeds to check if your guess matches the right number on if guess == number:
.
Checking your guess
The if\else
block to check the guess against the right number goes two ways.
If the user nails it, the code will print the message with the score and call save_highest_score(points)
to save the score on a file (I will explain save_highest_score(points)
later).
If the user doesn't guess the right number, it will go to the else
block.
If the number is higher, the game prints "Your guess was too high, try a lower number.", if it is lower the game prints "Your guess was too low, try a higher number.".
The program then calls the function calculate_score(points, number, guess)
(I will also explain this one later) to calculate your current score based on how many times you guessed wrong.
You always start the game with 9999 and then lose points every turn you guess wrong.
When you run out of chances and wasn't still able to guess the number, the program goes to if turn == chances:
where it checks if you exhausted the number of chances, and if you did, it prints "You ran out of chances!" and gives you the answer.
Finally, the game prints "Game Over!".
Calculating the Score: calculate_score(points, number, guess)
function
Let's understand calculate_score(points, number, guess)
.
The function calculate_score(points, number, guess)
takes as arguments the current points the player has, the number they are trying to guess, and their current guess.
The code subtracts the right number from guess, and then we have a lost_points
that is then subtracted from points
.
Notice the use of the abs()
built-in function, it returns the absolute value of a number.
The absolute value of a number is the value without considering its sign. So both -790 and 790 become 790.
This is important because if the right number is 200 and we guess 1, lost_points
will be 199 which is alright, but if we guess 990, lost_points
will be -790, which will increase the total number of points instead of decreasing it due to the code doing subtraction with a negative number.
To see this in action, try removing abs()
from lost_points = abs(number - guess)
so it will look like this lost_points = number - guess
.
Saving the Final Score: save_highest_score(score)
function
Finally, let's analyze what save_highest_score(score)
does.
It opens the file "score.txt" to read the highest score recorded in the game.
If there is no such file, the except
block prints the message "There was no champion" since there is no previous score to compare.
If there is a file and it is not empty, the variable record
stores the highest score.
Then we check if the current player's score is higher than the previous one.
If it is, the program prints "You are the new champion!" and saves the new record on "score.txt".
If the current score is not higher than the one stored in the file the program prints "Try again to beat the champion!".
The Code
import random
def choose_level():
print("How hard do you want the game to be?")
print("1 - Easy - 25 chances to try")
print("2 - Medium - 15 chances to try")
print("3 - Hard - 5 chances to try")
while True:
try:
level = int(input("Choose the difficulty level (1 or 2 or 3): "))
if(level < 1 or level > 3):
print("Not a valid level.")
continue
break
except ValueError:
print("Invalid choice.")
if level == 1:
chances = 25
elif level == 2:
chances = 15
else:
chances = 5
return chances
def calculate_score(points, number, guess):
lost_points = abs(number - guess)
points = points - lost_points
return points
def save_highest_score(score):
record = 0
try:
with open("score.txt", "r") as score_file:
record_line = score_file.read()
if record_line:
record = int(record_line)
print(f"The record for this game is: {record} points.")
except FileNotFoundError:
print("There was no champion")
if score > record:
print("You are the new champion!")
with open("score.txt", "w") as score_file:
score_file.write(str(score))
else:
print("Try again to beat the champion!")
def play_game(chances):
number = random.randint(1,1000)
points = 9999
for turn in range(1, chances + 1):
print(f"-> Chance {turn} out of {chances}")
while True:
try:
guess = int(input("Type a number between 1 and 1000: "))
if(guess < 1 or guess > 1000):
print("Your guess must be between 1 and 1000!")
continue
break
except ValueError:
print("Invalid guess.")
if guess == number:
print(f">> You nailed it! Final score: {points} <<")
save_highest_score(points)
break
else:
if guess > number:
print("Your guess was too high, try a lower number.")
elif guess < number:
print("Your guess was too low, try a higher number.")
points = calculate_score(points, number, guess)
if turn == chances:
print(">> You ran out of chances! <<")
print(f"The right number is: {number}")
print("Game Over!")
if __name__ == "__main__":
print("###############################")
print("Welcome to the Guessing game!")
print("Guess the number from 1 to 1000")
print("###############################")
chances = choose_level()
play_game(chances)
Testing the Game
The trick to winning in this kind of game is to divide the numbers in half when guessing, this way you eliminate 50% of the numbers in every turn, making your space of possibilities smaller quickly.
Let's say the game starts with the random number 616.
Since this game goes from 1 to 1000, the logical first guess is 500.
Then the game will tell you guessed too low, so you know the right number is between 500 and 1000.
Then you try 750, the number in the middle of 500 and 1000.
The game will say you guessed too high, now you know the right answer is between 500 and 750.
You keep doing this until you either nail it or run out of chances.
To run the game, copy and paste the code in a file with any name, I chose the name "guessing_game.py", and then run:
python guessing_game.py
Or, depending on your Python installation:
python3 guessing_game.py
Here is a sample output of when you beat the game:
###############################
Welcome to the Guessing game!
Guess the number from 1 to 1000
###############################
How hard do you want the game to be?
1 - Easy - 25 chances to try
2 - Medium - 15 chances to try
3 - Hard - 5 chances to try
Choose the difficulty level (1 or 2 or 3): 1
-> Chance 1 out of 25
Type a number between 1 and 1000: 500
Your guess was too high, try a lower number.
-> Chance 2 out of 25
Type a number between 1 and 1000: 250
Your guess was too low, try a higher number.
-> Chance 3 out of 25
Type a number between 1 and 1000: 375
Your guess was too high, try a lower number.
-> Chance 4 out of 25
Type a number between 1 and 1000: 312
Your guess was too high, try a lower number.
-> Chance 5 out of 25
Type a number between 1 and 1000: 281
Your guess was too low, try a higher number.
-> Chance 6 out of 25
Type a number between 1 and 1000: 296
Your guess was too low, try a higher number.
-> Chance 7 out of 25
Type a number between 1 and 1000: 304
Your guess was too high, try a lower number.
-> Chance 8 out of 25
Type a number between 1 and 1000: 300
Your guess was too high, try a lower number.
-> Chance 9 out of 25
Type a number between 1 and 1000: 298
>> You nailed it! Final score: 9631 <<
There was no champion
You are the new champion!
Game Over!
Here is a sample output of when you lose:
###############################
Welcome to the Guessing game!
Guess the number from 1 to 1000
###############################
How hard do you want the game to be?
1 - Easy - 25 chances to try
2 - Medium - 15 chances to try
3 - Hard - 5 chances to try
Choose the difficulty level (1 or 2 or 3): 3
-> Chance 1 out of 5
Type a number between 1 and 1000: 4
Yout guess was too low, try a higher number.
-> Chance 2 out of 5
Type a number between 1 and 1000: 500
Your guess was too high, try a lower number.
-> Chance 3 out of 5
Type a number between 1 and 1000: 250
Yout guess was too low, try a higher number.
-> Chance 4 out of 5
Type a number between 1 and 1000: 23
Yout guess was too low, try a higher number.
-> Chance 5 out of 5
Type a number between 1 and 1000: 2
Your guess was too low, try a higher number.
>> You ran out of chances! <<
The right number is: 289
Game Over!
If you want to truly understand what is going on in this code, the best thing you can is to modify it and see what happens.
Try to change the messages in the print()
functions, change the number of chances for each level, come up with a different approach to calculate the score on calculate_score(points, number, guess)
, etc.
There are many changes you can do to make this game even better!
Posted on January 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 29, 2023