Robert Johns | 06 Feb, 2025
Fact checked by Jim Markus

Build a Fun Number Guessing Game in Python (Step-by-Step)

Want to improve your Python skills while having fun? This beginner-friendly project will guide you through building a Number Guessing Game using Python, step-by-step.

By the end, you’ll have a working game where the computer picks a random number, and the player must guess it with hints along the way.

This project is perfect for beginners, as it covers essential programming concepts like:
- Using the random module to generate random numbers
- Working with loops and conditional statements
- Handling user input and validating errors
- Keeping track of high scores

Let’s dive in!

Step 1: Setting Up the Project

Before we start coding, let’s set up our Python project:

1. Make sure Python is installed on your computer. If not, download it from the official Python website.
2. Open your favorite code editor or IDE.
3. Create a new Python file, for example, number_guess.py.

Great, now, let's dive head first into our Python editor to get this build started.

Step 2: Understanding How the Game Works

The Number Guessing Game works like this:

- The computer picks a random number between 1 and 10.
- The player keeps guessing until they get it right.
- After each incorrect guess, the player gets a hint (higher or lower).
- The program keeps track of the number of attempts.
- The player’s best score (fewest attempts) is saved for future rounds.

Step 3: Importing the Required Module

We need the Python random module to generate random numbers. Let’s import it:

import random

The random.randint(a, b) function generates a random number between a and b (inclusive).

Step 4: Displaying the Best Score

Since we want to track the player’s best score, let’s write a Python function to show the lowest number of attempts from previous rounds:

def show_score(attempts_list):
    if not attempts_list:
        print("There is currently no best score, it's yours for the taking!")
    else:
        print(f"The current best score is {min(attempts_list)} attempts.")

How It Works:

  • If there are no previous scores, the player gets a message saying the scoreboard is empty.
  • Otherwise, we display the lowest attempt count (using min(attempts_list)).

Step 5: Writing the Main Game Logic

Now, let’s write the function that runs the game:

def start_game():
    attempts = 0  # Tracks the number of attempts in the current game
    rand_num = random.randint(1, 10)  # Generates a random number
    attempts_list = []  # Stores past attempts for tracking the best score

    print("Hello, traveler! Welcome to the game of guesses!")
    player_name = input("What is your name? ")  # Gets the player's name

    wanna_play = input(f"Hi, {player_name}, would you like to play the guessing game? (Enter Yes/No): ")

    if wanna_play.lower() != "yes":
        print("That's cool, Thanks!")
        exit()
    else:
        show_score(attempts_list)  # Show the best score before starting

    # Game loop
    while wanna_play.lower() == "yes":
        try:
            guess = int(input("Pick a number between 1 and 10: "))  # Get user input

            if guess < 1 or guess > 10:
                raise ValueError("Please guess a number within the given range")

            attempts += 1  # Count each guess

            if guess == rand_num:
                print("Nice! You got it! 🎉")
                print(f"It took you {attempts} attempts.")

                attempts_list.append(attempts)  # Save the attempt count
                wanna_play = input("Would you like to play again? (Enter Yes/No): ")

                if wanna_play.lower() != "yes":
                    print("That's cool, have a good one!")
                    break
                else:
                    attempts = 0  # Reset attempts for the new game
                    rand_num = random.randint(1, 10)  # Pick a new number
                    show_score(attempts_list)  # Show best score
                    continue
            else:
                # Provide hints
                if guess > rand_num:
                    print("It's lower! 📉")
                elif guess < rand_num:
                    print("It's higher! 📈")

        except ValueError as err:
            print("Oh no! That is not a valid number. Try again...")
            print(err)  # Show error message

How It Works:

  • The game welcomes the player and asks if they want to play.
  • It picks a random number between 1 and 10.
  • The player guesses, and the game provides hints if the guess is incorrect.
  • Once the player guesses correctly, it saves the number of attempts.
  • The game keeps track of the best score and offers the player a chance to play again.
  • If the player enters something invalid (like text instead of a number), the game catches the error and asks again.

The core functionality of our Number Guessing Game is handled within the start_game() function. Let’s break it down into key Python techniques used:

Using a while Loop for Continuous Gameplay

We use a while loop to keep the game running until the player decides to stop:

while wanna_play.lower() == "yes":
  • The lower() method converts the player's response to lowercase to ensure case-insensitive input.
  • If the player types "Yes", "YES", or "yEs", it all gets converted to "yes" for consistent comparisons.
  • If they say "no", the loop ends, and the game stops.

Using try-except for Error Handling

When taking user input, we must ensure they enter a valid number with a try-except block. Otherwise, the program could crash.

try:
    guess = int(input("Pick a number between 1 and 10: "))
  • The try block attempts to convert the user’s input into an integer using int().
  • If the user types something invalid (e.g., a letter, symbol, or blank space), Python would normally throw an error and crash.
  • Instead, the except ValueError as err: block catches the error gracefully and displays a friendly message:
except ValueError as err:
    print("Oh no! That is not a valid number. Try again...")
    print(err)

This is a great way to handle unexpected user behavior and prevent program crashes.

Validating User Input with if Conditions

Even if the user enters a number, it might be outside the allowed range (1 to 10). We handle this with an if condition:

if guess < 1 or guess > 10:
    raise ValueError("Please guess a number within the given range")
  • If the number is less than 1 or greater than 10, we use raise ValueError() to manually trigger an error.
  • This sends the program directly into the except block, displaying an error message.

Using if-elif-else for Guess Feedback

Once the user enters a valid number, we compare it with the randomly generated number:

if guess == rand_num:
    print("Nice! You got it! 🎉")
    print(f"It took you {attempts} attempts.")
  • If the guess is correct, we celebrate 🎉 and record the number of attempts.

If the guess is wrong, we provide a helpful hint:

elif guess > rand_num:
    print("It's lower! 📉")
elif guess < rand_num:
    print("It's higher! 📈")
  • This simple hint helps players narrow down their guesses.

Keeping Track of the Best Score

We store the number of attempts in a list so we can track the best score across multiple games:

attempts_list.append(attempts)
  • The min(attempts_list) function finds the smallest number in the list, showing the best performance so far.
  • The show_score() function prints this best score before the next round starts.

Resetting the Game for Another Round

After a correct guess, the player is asked if they want to play again:

wanna_play = input("Would you like to play again? (Enter Yes/No): ")
  • If they type "yes", we reset key variables:
attempts = 0
rand_num = random.randint(1, 10)
show_score(attempts_list)
  • A new random number is generated for the next round.
  • The attempts counter is reset to 0.
  • The best score is displayed before the new round begins.

This ensures the game runs smoothly without restarting the entire script.

Step 6: Running the Game

Now, let’s call the start_game() function to start everything when the script runs:

if __name__ == "__main__":
    start_game()

Why Is This Needed?

This line ensures that our game runs only when the script is executed directly, not when it is imported as a module.

Without this check:

If someone imports our number_guess.py script into another Python program, it would automatically start the game.

With this check:

  • If __name__ == "__main__" is true, it means the script was run directly, so it starts the game.
  • If it was imported elsewhere, the start_game() function does not execute automatically.

This is a best practice for writing Python programs, making our code modular and reusable.

This ensures the game starts only when the script is run directly (and not if it's imported as a module).

Final Code: Number Guessing Game

Here’s the complete code for your Number Guessing Game:

import random

def show_score(attempts_list):
    if not attempts_list:
        print("There is currently no best score, it's yours for the taking!")
    else:
        print(f"The current best score is {min(attempts_list)} attempts.")

def start_game():
    attempts = 0
    rand_num = random.randint(1, 10)
    attempts_list = []

    print("Hello, traveler! Welcome to the game of guesses!")
    player_name = input("What is your name? ")
    wanna_play = input(f"Hi, {player_name}, would you like to play the guessing game? (Enter Yes/No): ")

    if wanna_play.lower() != "yes":
        print("That's cool, Thanks!")
        exit()
    else:
        show_score(attempts_list)

    while wanna_play.lower() == "yes":
        try:
            guess = int(input("Pick a number between 1 and 10: "))

            if guess < 1 or guess > 10:
                raise ValueError("Please guess a number within the given range")

            attempts += 1

            if guess == rand_num:
                print("Nice! You got it! 🎉")
                print(f"It took you {attempts} attempts.")
                attempts_list.append(attempts)
                wanna_play = input("Would you like to play again? (Enter Yes/No): ")

                if wanna_play.lower() != "yes":
                    print("That's cool, have a good one!")
                    break
                else:
                    attempts = 0
                    rand_num = random.randint(1, 10)
                    show_score(attempts_list)
                    continue
            else:
                if guess > rand_num:
                    print("It's lower! 📉")
                elif guess < rand_num:
                    print("It's higher! 📈")

        except ValueError as err:
            print("Oh no! That is not a valid number. Try again...")
            print(err)

if __name__ == "__main__":
    start_game()

Wrapping Up

Congratulations! You’ve built a complete Number Guessing Game using Python!

This project helped you learn:

- Random Number Generation (random.randint(1, 10))
- Loops (while loop to keep the game running)
- Error Handling (try-except to handle invalid input)
- User Input Validation (ensuring numbers stay in range)
- Conditional Statements (if-elif-else to give hints)
- List Operations (min(attempts_list) to track the best score)
- Modular Programming (if __name__ == "__main__" to control script execution)

Next Steps: Enhance the Game!

- Expand the number range (1 to 100)
- Give the player a limited number of guesses
- Add difficulty levels (Easy, Medium, Hard)

The best way to learn Python is by building fun projects—so keep experimenting!

By Robert Johns

Technical Editor for Hackr.io | 15+ Years in Python, Java, SQL, C++, C#, JavaScript, Ruby, PHP, .NET, MATLAB, HTML & CSS, and more... 10+ Years in Networking, Cloud, APIs, Linux | 5+ Years in Data Science | 2x PhDs in Structural & Blast Engineering

View all post by the author

Subscribe to our Newsletter for Articles, News, & Jobs.

I accept the Terms and Conditions.

Disclosure: Hackr.io is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.

In this article

Learn More

Please login to leave comments