Build a game where the user guesses a randomly generated number.
Build a game where the user guesses a randomly generated number.
{% raw %}
Building a number-guessing game in Python is a great way to practice control flow, user input, and random number generation. Below are some input ideas and the steps to implement this game.
Game Steps
- Welcome Message: Display a welcome message and explain the game rules to the user.
- Random Number Generation: Generate a random number within a specified range (e.g., 1 to 100).
- User Input: Prompt the user to guess the number.
- Feedback: Provide feedback on whether the guess is too high, too low, or correct.
- Repeat: Allow the user to guess again until they find the correct number.
- End Game: Congratulate the user and display the number of attempts taken.
Input Ideas
Here are some specific inputs you can use to enhance the game:
- Range of Numbers: Allow the user to choose the range (e.g., 1 to 50, 1 to 100, or 1 to 1000) to adjust the difficulty.
- Maximum Attempts: Set a limit on the number of attempts (e.g., 5 or 10 attempts) to increase the challenge.
- Hints: Provide hints after a certain number of wrong guesses, such as whether the number is even or odd.
- Difficulty Levels: Offer different difficulty levels (easy, medium, hard) that affect the range of numbers and the number of attempts allowed.
- Play Again Option: After the game ends, ask if the user wants to play again.
- Input Validation: Ensure the user inputs a valid number within the specified range.
Additional Features
- Scoring System: Introduce a scoring system based on the number of attempts.
- Leaderboard: Track and display the top scores or fastest guesses.
- Graphical Interface: Use a library like Tkinter to create a GUI version of the game.
Solutions
A. Simple CLI Game
The game generates a random number between 1 and 100 using random.randint(1, 100).
User Input: The user is prompted to guess the number.
Feedback: The game provides feedback after each guess:
- If the guess is too low, it prompts the user to guess higher.
- If the guess is too high, it prompts the user to guess lower.
Win Condition: When the user guesses the correct number, the game congratulates the player and displays the number of attempts it took to guess correctly.
import randomdef get_user_guess(): try: guess = int(input("Enter your guess: ")) except ValueError: print("Invalid input. Please enter a valid integer.") get_user_guess() return guessdef get_random_number(): secret_number = random.randint(1, 100) return secret_numberdef number_guessing_game(): """ A simple number guessing game where the user tries to guess a randomly generated number between 1 and 100. """ # Generate a random number between 1 and 100 secret_number = get_random_number() attempts = 0 print("Welcome to the Number Guessing Game!") print("I'm thinking of a number between 1 and 100.") while True: attempts += 1 guess = get_user_guess() # Check if the guess is correct if guess < secret_number: print("Too low! Try again.") elif guess > secret_number: print("Too high! Try again.") else: print(f"Congratulations! You guessed the number in {attempts} attempts.") breakif __name__ == "__main__": number_guessing_game()B. With Difficulty Levels, Play Again Option, Input Validations
- Range of Numbers: The range of numbers is adjusted based on the selected difficulty level.
- Maximum Attempts: The number of attempts is limited based on the difficulty level.
- Hints: A hint is provided after half of the maximum attempts if the player has not yet guessed the correct number.
- Difficulty Levels: Three difficulty levels (Easy, Medium, Hard) determine the range of numbers and the number of attempts.
- Play Again Option: After the game ends, the player is asked if they want to play again.
- Input Validation: The game ensures that the user inputs a valid number within the specified range.
import randomdef print_menu(): """ Function to print menu""" print("Welcome to the Enhanced Number Guessing Game!") # Select difficulty level print("Select difficulty level:") print("1. Easy (Range: 1-50, 10 attempts)") print("2. Medium (Range: 1-100, 7 attempts)") print("3. Hard (Range: 1-1000, 5 attempts)")def get_min_max_total_attempts(difficulty): # Set parameters based on difficulty level if difficulty == 1: min_value, max_value, max_attempts = 1, 50, 10 elif difficulty == 2: min_value, max_value, max_attempts = 1, 100, 7 else: min_value, max_value, max_attempts = 1, 1000, 5 return min_value, max_value, max_attemptsdef play(secret_number, min_value, max_value, max_attempts): attempts = 0 hints_given = False print(f"\nI'm thinking of a number between {min_value} and {max_value}.") print(f"You have {max_attempts} attempts to guess it.\n") while attempts < max_attempts: guess = get_valid_number(f"Attempt {attempts + 1}: Enter your guess: ", min_value, max_value) attempts += 1 if guess < secret_number: print("Too low! Try again.") elif guess > secret_number: print("Too high! Try again.") else: print(f"Congratulations! You guessed the number in {attempts} attempts.") break # Provide a hint after half the attempts if the user hasn't guessed correctly if attempts == max_attempts // 2 and not hints_given: hint = "even" if secret_number % 2 == 0 else "odd" print(f"Hint: The number is {hint}.") hints_given = True if attempts == max_attempts and guess != secret_number: print(f"\nSorry, you've used all {max_attempts} attempts. The correct number was {secret_number}.")def get_valid_number(prompt, min_value, max_value): """Helper function to get a valid number within a specified range.""" while True: try: num = int(input(prompt)) if min_value <= num <= max_value: return num else: print(f"Please enter a number between {min_value} and {max_value}.") except ValueError: print("Invalid input. Please enter a valid integer.")def play_again(): # Ask the user if they want to play again play_again = input("\nDo you want to play again? (yes/no): ").strip().lower() if play_again == 'yes': number_guessing_game() else: print("Thank you for playing! Goodbye.")def number_guessing_game(): """ An enhanced number guessing game where the user selects a difficulty level and attempts to guess a randomly generated number within a range. """ print_menu() difficulty = get_valid_number("Choose a difficulty level (1, 2, or 3): ", 1, 3) min_value, max_value, max_attempts = get_min_max_total_attempts(difficulty) secret_number = random.randint(min_value, max_value) play(secret_number, min_value, max_value, max_attempts) play_again() if __name__ == "__main__": number_guessing_game()C. With Leaderboard
import osimport randomLEADERBOARD_FILE = "leaderboard.txt"def load_leaderboard(): """Load the leaderboard from a file.""" if os.path.exists(LEADERBOARD_FILE): with open(LEADERBOARD_FILE, "r") as file: leaderboard = [line.strip().split(",") for line in file.readlines()] leaderboard = [(name, int(score)) for name, score in leaderboard] return sorted(leaderboard, key=lambda x: x[1]) return []def save_leaderboard(leaderboard): """Save the leaderboard to a file.""" with open(LEADERBOARD_FILE, "w") as file: for name, score in leaderboard: file.write(f"{name},{score}\n")def display_leaderboard(leaderboard): """Display the top scores from the leaderboard.""" print("\n--- Leaderboard ---") if leaderboard: for i, (name, score) in enumerate(leaderboard[:10], start=1): print(f"{i}. {name}: {score} attempts") else: print("No scores yet. Be the first to play!") print("-------------------\n")def update_leaderboard(player_name, attempts): """Update the leaderboard with the player's score.""" leaderboard = load_leaderboard() leaderboard.append((player_name, attempts)) leaderboard = sorted(leaderboard, key=lambda x: x[1])[:10] # Keep only top 10 scores save_leaderboard(leaderboard)def print_menu(): """ Function to print menu""" print("Welcome to the Enhanced Number Guessing Game!") # Select difficulty level print("Select difficulty level:") print("1. Easy (Range: 1-50, 10 attempts)") print("2. Medium (Range: 1-100, 7 attempts)") print("3. Hard (Range: 1-1000, 5 attempts)")def get_min_max_total_attempts(difficulty): # Set parameters based on difficulty level if difficulty == 1: min_value, max_value, max_attempts = 1, 50, 10 elif difficulty == 2: min_value, max_value, max_attempts = 1, 100, 7 else: min_value, max_value, max_attempts = 1, 1000, 5 return min_value, max_value, max_attemptsdef play(secret_number, min_value, max_value, max_attempts): attempts = 0 hints_given = False print(f"\nI'm thinking of a number between {min_value} and {max_value}.") print(f"You have {max_attempts} attempts to guess it.\n") while attempts < max_attempts: guess = get_valid_number(f"Attempt {attempts + 1}: Enter your guess: ", min_value, max_value) attempts += 1 if guess < secret_number: print("Too low! Try again.") elif guess > secret_number: print("Too high! Try again.") else: print(f"Congratulations! You guessed the number in {attempts} attempts.") player_name = input("Enter your name for the leaderboard: ").strip() update_leaderboard(player_name, attempts) break # Provide a hint after half the attempts if the user hasn't guessed correctly if attempts == max_attempts // 2 and not hints_given: hint = "even" if secret_number % 2 == 0 else "odd" print(f"Hint: The number is {hint}.") hints_given = True if attempts == max_attempts and guess != secret_number: print(f"\nSorry, you've used all {max_attempts} attempts. The correct number was {secret_number}.")def get_valid_number(prompt, min_value, max_value): """Helper function to get a valid number within a specified range.""" while True: try: num = int(input(prompt)) if min_value <= num <= max_value: return num else: print(f"Please enter a number between {min_value} and {max_value}.") except ValueError: print("Invalid input. Please enter a valid integer.")def play_again(): # Ask the user if they want to play again play_again = input("\nDo you want to play again? (yes/no): ").strip().lower() if play_again == 'yes': number_guessing_game() else: print("Thank you for playing! Goodbye.")def number_guessing_game(): """ An enhanced number guessing game where the user selects a difficulty level and attempts to guess a randomly generated number within a range. """ display_leaderboard(load_leaderboard()) print_menu() difficulty = get_valid_number("Choose a difficulty level (1, 2, or 3): ", 1, 3) min_value, max_value, max_attempts = get_min_max_total_attempts(difficulty) secret_number = random.randint(min_value, max_value) play(secret_number, min_value, max_value, max_attempts) display_leaderboard(load_leaderboard()) play_again() if __name__ == "__main__": number_guessing_game()D. With TkInter Gui
- Graphical User Interface (GUI): Uses Tkinter to create a window-based interface for the game.
- Difficulty Levels: Players can select from three difficulty levels that adjust the range of numbers and the number of attempts.
- Scoring System: Keeps track of how many attempts it takes the player to guess the correct number.
- Leaderboard: The top 10 scores are saved to a file and can be viewed through the GUI.
- Hints: After half the maximum attempts, the player is provided a hint whether the number is even or odd.
- Input Validation: Ensures that the player inputs a valid integer within the specified range.
- Play Again: After a game ends, the interface resets, allowing the player to start a new game.
import tkinter as tkimport tkinter.simpledialogfrom tkinter import messageboximport randomimport osLEADERBOARD_FILE = "leaderboard.txt"class NumberGuessingGame: def __init__(self, root): self.root = root self.root.title("Number Guessing Game") self.min_value = 1 self.max_value = 100 self.max_attempts = 10 self.attempts = 0 self.secret_number = 0 self.player_name = "" self.hints_given = False self.create_widgets() def create_widgets(self): """Create the main interface widgets.""" self.difficulty_label = tk.Label(self.root, text="Select Difficulty Level:") self.difficulty_label.pack(pady=10) self.difficulty_var = tk.IntVar(value=2) self.difficulty_easy = tk.Radiobutton(self.root, text="Easy (1-50)", variable=self.difficulty_var, value=1, command=self.set_difficulty) self.difficulty_medium = tk.Radiobutton(self.root, text="Medium (1-100)", variable=self.difficulty_var, value=2, command=self.set_difficulty) self.difficulty_hard = tk.Radiobutton(self.root, text="Hard (1-1000)", variable=self.difficulty_var, value=3, command=self.set_difficulty) self.difficulty_easy.pack() self.difficulty_medium.pack() self.difficulty_hard.pack() self.start_button = tk.Button(self.root, text="Start Game", command=self.start_game) self.start_button.pack(pady=10) self.guess_label = tk.Label(self.root, text="Enter your guess:") self.guess_entry = tk.Entry(self.root) self.submit_button = tk.Button(self.root, text="Submit Guess", command=self.check_guess) self.attempts_label = tk.Label(self.root, text="Attempts left: N/A") self.leaderboard_button = tk.Button(self.root, text="Show Leaderboard", command=self.show_leaderboard) self.leaderboard_button.pack(pady=10) def set_difficulty(self): """Set the game difficulty based on user selection.""" difficulty = self.difficulty_var.get() if difficulty == 1: self.min_value, self.max_value, self.max_attempts = 1, 50, 10 elif difficulty == 2: self.min_value, self.max_value, self.max_attempts = 1, 100, 7 else: self.min_value, self.max_value, self.max_attempts = 1, 1000, 5 def start_game(self): """Start the game by generating a random number and resetting the attempts.""" self.secret_number = random.randint(self.min_value, self.max_value) self.attempts = 0 self.hints_given = False self.difficulty_label.pack_forget() self.difficulty_easy.pack_forget() self.difficulty_medium.pack_forget() self.difficulty_hard.pack_forget() self.start_button.pack_forget() self.guess_label.pack(pady=10) self.guess_entry.pack(pady=10) self.submit_button.pack(pady=10) self.attempts_label.pack(pady=10) self.update_attempts_label() def update_attempts_label(self): """Update the label that shows how many attempts are left.""" attempts_left = self.max_attempts - self.attempts self.attempts_label.config(text=f"Attempts left: {attempts_left}") def check_guess(self): """Check the user's guess and provide feedback.""" try: guess = int(self.guess_entry.get()) if guess < self.min_value or guess > self.max_value: messagebox.showerror("Error", f"Please enter a number between {self.min_value} and {self.max_value}.") return except ValueError: messagebox.showerror("Error", "Please enter a valid integer.") return self.attempts += 1 self.update_attempts_label() if guess < self.secret_number: messagebox.showinfo("Result", "Too low! Try again.") elif guess > self.secret_number: messagebox.showinfo("Result", "Too high! Try again.") else: messagebox.showinfo("Congratulations!", f"You guessed the number in {self.attempts} attempts.") self.record_score() self.reset_game() return if self.attempts == self.max_attempts: messagebox.showinfo("Game Over", f"Sorry, you've used all {self.max_attempts} attempts. The correct number was {self.secret_number}.") self.reset_game() if self.attempts == self.max_attempts // 2 and not self.hints_given: hint = "even" if self.secret_number % 2 == 0 else "odd" messagebox.showinfo("Hint", f"Hint: The number is {hint}.") self.hints_given = True def record_score(self): """Record the player's score and update the leaderboard.""" self.player_name = tkinter.simpledialog.askstring("Name", "Enter your name for the leaderboard:") if not self.player_name: self.player_name = "Anonymous" leaderboard = self.load_leaderboard() leaderboard.append((self.player_name, self.attempts)) leaderboard = sorted(leaderboard, key=lambda x: x[1])[:10] # Keep only top 10 scores self.save_leaderboard(leaderboard) def load_leaderboard(self): """Load the leaderboard from a file.""" if os.path.exists(LEADERBOARD_FILE): with open(LEADERBOARD_FILE, "r") as file: leaderboard = [line.strip().split(",") for line in file.readlines()] return [(name, int(score)) for name, score in leaderboard] return [] def save_leaderboard(self, leaderboard): """Save the leaderboard to a file.""" with open(LEADERBOARD_FILE, "w") as file: for name, score in leaderboard: file.write(f"{name},{score}\n") def show_leaderboard(self): """Display the top scores from the leaderboard.""" leaderboard = self.load_leaderboard() if leaderboard: leaderboard_str = "\n".join([f"{i+1}. {name}: {score} attempts" for i, (name, score) in enumerate(leaderboard)]) else: leaderboard_str = "No scores yet. Be the first to play!" messagebox.showinfo("Leaderboard", leaderboard_str) def reset_game(self): """Reset the game to the initial state.""" self.guess_label.pack_forget() self.guess_entry.pack_forget() self.submit_button.pack_forget() self.attempts_label.pack_forget() self.difficulty_label.pack(pady=10) self.difficulty_easy.pack() self.difficulty_medium.pack() self.difficulty_hard.pack() self.start_button.pack(pady=10)if __name__ == "__main__": root = tk.Tk() app = NumberGuessingGame(root) root.mainloop(){% endraw %}
This post is licensed under CC BY 4.0 by the author.