零基础 30 分钟上手!Python 猜数字游戏实战(含完整代码 + 分步解析)

猜数字游戏是一款经典的小游戏,玩家需要根据提示猜出一个预设的数字。本文将使用 Python 实现一个具有现代界面的猜数字游戏,涵盖从基础逻辑到图形界面的完整开发过程。通过这个项目,你将学习 Python 编程的核心概念,包括变量、数据类型、控制结构、函数、模块以及图形界面开发。

一、游戏基本原理与流程

猜数字游戏的基本规则如下:

  1. 计算机随机生成一个 1 到 100 之间的整数
  2. 玩家输入一个猜测的数字
  3. 计算机根据玩家的猜测给出提示(猜大了、猜小了或猜对了)
  4. 玩家继续猜测,直到猜对为止
  5. 游戏结束后,显示玩家的猜测次数和游戏评价

下面是一个简单的命令行版本实现:

import random

def guess_number():
    # 生成1到100之间的随机数
    secret_number = random.randint(1, 100)
    attempts = 0
    
    print("欢迎来到猜数字游戏!我已经想好了一个1到100之间的数字,你可以开始猜了。")
    
    while True:
        try:
            # 获取玩家的猜测
            guess = int(input("请输入你的猜测:"))
            attempts += 1
            
            # 检查猜测结果
            if guess < secret_number:
                print("猜小了!再大一点。")
            elif guess > secret_number:
                print("猜大了!再小一点。")
            else:
                print(f"恭喜你,猜对了!答案就是 {secret_number}。")
                print(f"你一共用了 {attempts} 次猜测。")
                
                # 根据猜测次数给出评价
                if attempts <= 5:
                    print("你太厉害了!简直是个天才!")
                elif attempts <= 10:
                    print("不错!继续努力!")
                else:
                    print("还需要加油哦!下次会更好!")
                break
                
        except ValueError:
            print("请输入有效的整数!")

# 启动游戏
guess_number()

在这里插入图片描述

知识点解析

  1. 随机数生成:使用 random.randint(1, 100) 生成 1 到 100 之间的随机整数
  2. 循环结构:使用 while True 创建无限循环,直到猜对为止
  3. 条件判断:使用 if-elif-else 判断猜测结果并给出相应提示
  4. 异常处理:使用 try-except 处理非整数输入的情况
  5. 用户交互:使用 input() 获取用户输入,print() 输出提示信息

二、游戏功能扩展

我们可以对基础版本进行扩展,增加以下功能:

  1. 游戏难度选择:允许玩家选择不同难度(数字范围不同)
  2. 游戏次数统计:记录玩家的游戏次数和最佳成绩
  3. 历史记录:保存每次游戏的结果
  4. 游戏提示:显示猜测范围的上下限

下面是扩展后的代码:

import random

class GuessNumberGame:
    def __init__(self):
        self.difficulty_levels = {
            "easy": (1, 50),
            "medium": (1, 100),
            "hard": (1, 200)
        }
        self.current_difficulty = "medium"
        self.game_history = []
        self.best_score = float('inf')  # 初始化为无穷大
    
    def set_difficulty(self):
        """设置游戏难度"""
        print("\n选择游戏难度:")
        print("1. 简单 (1-50)")
        print("2. 中等 (1-100)")
        print("3. 困难 (1-200)")
        
        while True:
            choice = input("请选择难度 (1-3): ")
            if choice == '1':
                self.current_difficulty = "easy"
                break
            elif choice == '2':
                self.current_difficulty = "medium"
                break
            elif choice == '3':
                self.current_difficulty = "hard"
                break
            else:
                print("无效选择,请重新输入!")
    
    def play_game(self):
        """开始一轮游戏"""
        # 获取当前难度的数字范围
        min_num, max_num = self.difficulty_levels[self.current_difficulty]
        secret_number = random.randint(min_num, max_num)
        attempts = 0
        lower_bound = min_num
        upper_bound = max_num
        
        print(f"\n游戏开始!我已经想好了一个{lower_bound}{upper_bound}之间的数字,你可以开始猜了。")
        
        while True:
            try:
                guess = int(input(f"请输入你的猜测 ({lower_bound}-{upper_bound}): "))
                
                # 检查猜测是否在有效范围内
                if guess < lower_bound or guess > upper_bound:
                    print(f"请输入{lower_bound}{upper_bound}之间的数字!")
                    continue
                
                attempts += 1
                
                if guess < secret_number:
                    print("猜小了!再大一点。")
                    lower_bound = max(lower_bound, guess + 1)  # 更新下限
                elif guess > secret_number:
                    print("猜大了!再小一点。")
                    upper_bound = min(upper_bound, guess - 1)  # 更新上限
                else:
                    print(f"恭喜你,猜对了!答案就是 {secret_number}。")
                    print(f"你一共用了 {attempts} 次猜测。")
                    
                    # 记录游戏结果
                    result = {
                        "difficulty": self.current_difficulty,
                        "attempts": attempts,
                        "date": f"{time.strftime('%Y-%m-%d %H:%M:%S')}"
                    }
                    self.game_history.append(result)
                    
                    # 更新最佳成绩
                    if attempts < self.best_score:
                        self.best_score = attempts
                        print("恭喜!你创造了新的最佳成绩!")
                    
                    # 根据猜测次数给出评价
                    if attempts <= 5:
                        print("你太厉害了!简直是个天才!")
                    elif attempts <= 10:
                        print("不错!继续努力!")
                    else:
                        print("还需要加油哦!下次会更好!")
                    
                    break
                    
            except ValueError:
                print("请输入有效的整数!")
    
    def show_history(self):
        """显示游戏历史记录"""
        if not self.game_history:
            print("\n暂无游戏记录。")
            return
        
        print("\n=== 游戏历史记录 ===")
        for i, game in enumerate(self.game_history, 1):
            print(f"{i}. {game['date']} - {game['difficulty'].capitalize()}难度 - {game['attempts']}次猜测")
        
        if self.best_score != float('inf'):
            print(f"\n你的最佳成绩: {self.best_score}次猜测")
    
    def run(self):
        """运行游戏主循环"""
        print("欢迎来到猜数字游戏!")
        
        while True:
            print("\n=== 主菜单 ===")
            print("1. 开始新游戏")
            print("2. 设置难度")
            print("3. 查看历史记录")
            print("4. 退出游戏")
            
            choice = input("请选择操作 (1-4): ")
            
            if choice == '1':
                self.play_game()
            elif choice == '2':
                self.set_difficulty()
            elif choice == '3':
                self.show_history()
            elif choice == '4':
                print("感谢游玩!再见!")
                break
            else:
                print("无效选择,请重新输入!")

# 启动游戏
if __name__ == "__main__":
    import time  # 仅在主程序中导入time模块
    game = GuessNumberGame()
    game.run()

在这里插入图片描述

知识点解析

  1. 类的设计:使用 GuessNumberGame 类封装游戏的所有功能
  2. 属性与方法:类包含难度设置、游戏历史、最佳成绩等属性,以及游戏逻辑的各种方法
  3. 数据结构:使用字典存储难度级别,列表存储游戏历史
  4. 模块化设计:将不同功能封装为独立的方法,提高代码的可维护性
  5. 菜单驱动程序:使用循环和条件语句实现游戏主菜单

三、图形界面实现

使用 Tkinter 库创建一个图形界面版本的猜数字游戏:

import tkinter as tk
from tkinter import messagebox, ttk
import random
import time

class GuessNumberGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("猜数字游戏")
        self.root.geometry("600x500")
        self.root.resizable(False, False)
        self.root.configure(bg="#f0f0f0")
        
        # 设置中文字体
        self.font = ("SimHei", 12)
        
        # 游戏变量
        self.difficulty_levels = {
            "简单": (1, 50),
            "中等": (1, 100),
            "困难": (1, 200)
        }
        self.current_difficulty = "中等"
        self.secret_number = None
        self.attempts = 0
        self.lower_bound = 1
        self.upper_bound = 100
        self.game_history = []
        self.best_score = float('inf')
        
        # 创建界面
        self.create_widgets()
        
        # 开始新游戏
        self.start_new_game()
    
    def create_widgets(self):
        """创建游戏界面组件"""
        # 标题
        title_frame = tk.Frame(self.root, bg="#f0f0f0")
        title_frame.pack(pady=20)
        
        title_label = tk.Label(title_frame, text="猜数字游戏", font=("SimHei", 24, "bold"), bg="#f0f0f0", fg="#333")
        title_label.pack()
        
        # 游戏信息框架
        info_frame = tk.Frame(self.root, bg="#f0f0f0")
        info_frame.pack(pady=10)
        
        self.difficulty_label = tk.Label(info_frame, text=f"难度: {self.current_difficulty}", font=self.font, bg="#f0f0f0")
        self.difficulty_label.pack(side=tk.LEFT, padx=20)
        
        self.attempts_label = tk.Label(info_frame, text=f"尝试次数: {self.attempts}", font=self.font, bg="#f0f0f0")
        self.attempts_label.pack(side=tk.LEFT, padx=20)
        
        self.range_label = tk.Label(info_frame, text=f"范围: {self.lower_bound} - {self.upper_bound}", font=self.font, bg="#f0f0f0")
        self.range_label.pack(side=tk.LEFT, padx=20)
        
        # 输入框架
        input_frame = tk.Frame(self.root, bg="#f0f0f0")
        input_frame.pack(pady=20)
        
        self.guess_label = tk.Label(input_frame, text="请输入你的猜测:", font=self.font, bg="#f0f0f0")
        self.guess_label.pack(side=tk.LEFT, padx=10)
        
        self.guess_entry = tk.Entry(input_frame, font=self.font, width=10)
        self.guess_entry.pack(side=tk.LEFT, padx=10)
        self.guess_entry.bind("<Return>", self.check_guess)
        
        self.guess_button = tk.Button(input_frame, text="猜测", font=self.font, command=self.check_guess, bg="#4CAF50", fg="white", padx=10, pady=5)
        self.guess_button.pack(side=tk.LEFT, padx=10)
        
        # 提示框架
        self.hint_frame = tk.Frame(self.root, bg="#f0f0f0")
        self.hint_frame.pack(pady=20)
        
        self.hint_label = tk.Label(self.hint_frame, text="开始猜测吧!", font=("SimHei", 14, "bold"), bg="#f0f0f0", fg="#333")
        self.hint_label.pack()
        
        # 历史记录框架
        history_frame = tk.Frame(self.root, bg="#f0f0f0")
        history_frame.pack(pady=10, fill=tk.BOTH, expand=True)
        
        history_label = tk.Label(history_frame, text="猜测历史:", font=self.font, bg="#f0f0f0")
        history_label.pack(anchor=tk.W)
        
        self.history_text = tk.Text(history_frame, font=self.font, width=60, height=8, bg="white", wrap=tk.WORD)
        self.history_text.pack(fill=tk.BOTH, expand=True, padx=10)
        self.history_text.config(state=tk.DISABLED)
        
        # 按钮框架
        button_frame = tk.Frame(self.root, bg="#f0f0f0")
        button_frame.pack(pady=20)
        
        self.new_game_button = tk.Button(button_frame, text="新游戏", font=self.font, command=self.start_new_game, bg="#2196F3", fg="white", padx=10, pady=5)
        self.new_game_button.pack(side=tk.LEFT, padx=10)
        
        self.difficulty_button = tk.Button(button_frame, text="设置难度", font=self.font, command=self.set_difficulty, bg="#FF9800", fg="white", padx=10, pady=5)
        self.difficulty_button.pack(side=tk.LEFT, padx=10)
        
        self.history_button = tk.Button(button_frame, text="游戏历史", font=self.font, command=self.show_game_history, bg="#9C27B0", fg="white", padx=10, pady=5)
        self.history_button.pack(side=tk.LEFT, padx=10)
    
    def start_new_game(self):
        """开始新游戏"""
        # 重置游戏状态
        self.min_num, self.max_num = self.difficulty_levels[self.current_difficulty]
        self.secret_number = random.randint(self.min_num, self.max_num)
        self.attempts = 0
        self.lower_bound = self.min_num
        self.upper_bound = self.max_num
        
        # 更新界面
        self.difficulty_label.config(text=f"难度: {self.current_difficulty}")
        self.attempts_label.config(text=f"尝试次数: {self.attempts}")
        self.range_label.config(text=f"范围: {self.lower_bound} - {self.upper_bound}")
        self.hint_label.config(text="开始猜测吧!", fg="#333")
        
        # 清空历史记录
        self.history_text.config(state=tk.NORMAL)
        self.history_text.delete(1.0, tk.END)
        self.history_text.config(state=tk.DISABLED)
        
        # 聚焦到输入框
        self.guess_entry.delete(0, tk.END)
        self.guess_entry.focus()
    
    def check_guess(self, event=None):
        """检查用户猜测"""
        try:
            guess = int(self.guess_entry.get())
            
            # 检查猜测是否在有效范围内
            if guess < self.lower_bound or guess > self.upper_bound:
                self.hint_label.config(text=f"请输入{self.lower_bound}{self.upper_bound}之间的数字!", fg="red")
                return
            
            self.attempts += 1
            
            # 更新历史记录
            self.history_text.config(state=tk.NORMAL)
            self.history_text.insert(tk.END, f"尝试 {self.attempts}: {guess}\n")
            self.history_text.config(state=tk.DISABLED)
            self.history_text.see(tk.END)  # 滚动到底部
            
            # 检查猜测结果
            if guess < self.secret_number:
                self.hint_label.config(text="猜小了!再大一点。", fg="blue")
                self.lower_bound = max(self.lower_bound, guess + 1)  # 更新下限
            elif guess > self.secret_number:
                self.hint_label.config(text="猜大了!再小一点。", fg="orange")
                self.upper_bound = min(self.upper_bound, guess - 1)  # 更新上限
            else:
                self.hint_label.config(text=f"恭喜你,猜对了!答案就是 {self.secret_number}。", fg="green")
                
                # 记录游戏结果
                result = {
                    "difficulty": self.current_difficulty,
                    "attempts": self.attempts,
                    "date": time.strftime('%Y-%m-%d %H:%M:%S')
                }
                self.game_history.append(result)
                
                # 更新最佳成绩
                if self.attempts < self.best_score:
                    self.best_score = self.attempts
                    messagebox.showinfo("恭喜", f"你创造了新的最佳成绩:{self.attempts}次猜测!")
                
                # 禁用猜测按钮
                self.guess_button.config(state=tk.DISABLED)
                self.guess_entry.config(state=tk.DISABLED)
                
                # 根据猜测次数给出评价
                if self.attempts <= 5:
                    evaluation = "你太厉害了!简直是个天才!"
                elif self.attempts <= 10:
                    evaluation = "不错!继续努力!"
                else:
                    evaluation = "还需要加油哦!下次会更好!"
                
                # 显示评价
                self.history_text.config(state=tk.NORMAL)
                self.history_text.insert(tk.END, f"\n游戏结束!你用了 {self.attempts} 次猜测。\n{evaluation}")
                self.history_text.config(state=tk.DISABLED)
            
            # 更新界面
            self.attempts_label.config(text=f"尝试次数: {self.attempts}")
            self.range_label.config(text=f"范围: {self.lower_bound} - {self.upper_bound}")
            self.guess_entry.delete(0, tk.END)
            self.guess_entry.focus()
            
        except ValueError:
            self.hint_label.config(text="请输入有效的整数!", fg="red")
    
    def set_difficulty(self):
        """设置游戏难度"""
        # 创建难度选择对话框
        difficulty_window = tk.Toplevel(self.root)
        difficulty_window.title("设置难度")
        difficulty_window.geometry("300x200")
        difficulty_window.resizable(False, False)
        difficulty_window.configure(bg="#f0f0f0")
        difficulty_window.transient(self.root)  # 使对话框成为主窗口的子窗口
        difficulty_window.grab_set()  # 模态对话框
        
        # 设置中文字体
        font = ("SimHei", 12)
        
        # 标题
        title_label = tk.Label(difficulty_window, text="选择游戏难度", font=("SimHei", 16, "bold"), bg="#f0f0f0", fg="#333")
        title_label.pack(pady=15)
        
        # 难度选项
        difficulty_var = tk.StringVar(value=self.current_difficulty)
        
        easy_radio = tk.Radiobutton(difficulty_window, text="简单 (1-50)", variable=difficulty_var, value="简单", font=font, bg="#f0f0f0")
        easy_radio.pack(anchor=tk.W, padx=40, pady=5)
        
        medium_radio = tk.Radiobutton(difficulty_window, text="中等 (1-100)", variable=difficulty_var, value="中等", font=font, bg="#f0f0f0")
        medium_radio.pack(anchor=tk.W, padx=40, pady=5)
        
        hard_radio = tk.Radiobutton(difficulty_window, text="困难 (1-200)", variable=difficulty_var, value="困难", font=font, bg="#f0f0f0")
        hard_radio.pack(anchor=tk.W, padx=40, pady=5)
        
        # 确认按钮
        def confirm_difficulty():
            self.current_difficulty = difficulty_var.get()
            difficulty_window.destroy()
            self.start_new_game()
        
        confirm_button = tk.Button(difficulty_window, text="确定", font=font, command=confirm_difficulty, bg="#4CAF50", fg="white", padx=10, pady=5)
        confirm_button.pack(pady=15)
    
    def show_game_history(self):
        """显示游戏历史记录"""
        if not self.game_history:
            messagebox.showinfo("游戏历史", "暂无游戏记录。")
            return
        
        # 创建历史记录对话框
        history_window = tk.Toplevel(self.root)
        history_window.title("游戏历史记录")
        history_window.geometry("500x400")
        history_window.resizable(False, False)
        history_window.configure(bg="#f0f0f0")
        history_window.transient(self.root)  # 使对话框成为主窗口的子窗口
        
        # 设置中文字体
        font = ("SimHei", 12)
        
        # 标题
        title_label = tk.Label(history_window, text="游戏历史记录", font=("SimHei", 16, "bold"), bg="#f0f0f0", fg="#333")
        title_label.pack(pady=15)
        
        # 创建表格
        columns = ("序号", "日期", "难度", "尝试次数")
        tree = ttk.Treeview(history_window, columns=columns, show="headings", height=10)
        
        # 设置列标题
        for col in columns:
            tree.heading(col, text=col)
            tree.column(col, width=100, anchor=tk.CENTER)
        
        # 添加数据
        for i, game in enumerate(self.game_history, 1):
            tree.insert("", tk.END, values=(i, game["date"], game["difficulty"], game["attempts"]))
        
        tree.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        
        # 最佳成绩
        if self.best_score != float('inf'):
            best_label = tk.Label(history_window, text=f"你的最佳成绩: {self.best_score}次猜测", font=font, bg="#f0f0f0", fg="#333")
            best_label.pack(pady=10)
        
        # 关闭按钮
        close_button = tk.Button(history_window, text="关闭", font=font, command=history_window.destroy, bg="#f44336", fg="white", padx=10, pady=5)
        close_button.pack(pady=15)

# 启动游戏
if __name__ == "__main__":
    root = tk.Tk()
    app = GuessNumberGUI(root)
    root.mainloop()

在这里插入图片描述
在这里插入图片描述

知识点解析

  1. Tkinter 基础:使用 Tkinter 创建窗口、标签、按钮等界面元素
  2. 事件处理:通过绑定事件(如按钮点击、回车键)触发相应的函数
  3. 界面布局:使用 pack() 方法进行界面布局管理
  4. 对话框:创建模态对话框用于设置难度和显示历史记录
  5. 数据可视化:使用 Treeview 组件展示游戏历史记录
  6. 状态管理:在界面上实时更新游戏状态(如尝试次数、猜测范围)

四、游戏优化与扩展

我们可以进一步优化和扩展游戏,例如:

  1. 添加音效和动画:在猜对或猜错时播放不同的音效,添加动画效果增强用户体验
  2. 保存游戏数据:使用文件或数据库保存游戏历史记录,实现跨会话的持久化存储
  3. 网络功能:添加多人对战或联机游戏功能
  4. 游戏统计:增加更详细的统计数据,如不同难度的胜率、平均猜测次数等

下面是一个添加音效功能的示例:

# 在GuessNumberGUI类中添加以下代码
def __init__(self, root):
    # ... 原有代码 ...
    self.sound_enabled = True
    # 添加音效按钮
    self.sound_button = tk.Button(button_frame, text="音效: 开", font=self.font, command=self.toggle_sound, bg="#607D8B", fg="white", padx=10, pady=5)
    self.sound_button.pack(side=tk.LEFT, padx=10)
    
    # 尝试导入playsound模块用于播放音效
    try:
        from playsound import playsound
        self.playsound = playsound
    except ImportError:
        self.playsound = None
        self.sound_enabled = False
        self.sound_button.config(state=tk.DISABLED, text="音效: 不可用")

def toggle_sound(self):
    """切换音效开关"""
    self.sound_enabled = not self.sound_enabled
    self.sound_button.config(text=f"音效: {'开' if self.sound_enabled else '关'}")

def play_sound(self, sound_type):
    """播放音效"""
    if not self.sound_enabled or self.playsound is None:
        return
    
    try:
        if sound_type == "correct":
            # 播放猜对的音效
            self.playsound("correct_sound.mp3")
        elif sound_type == "incorrect":
            # 播放猜错的音效
            self.playsound("incorrect_sound.mp3")
    except Exception as e:
        print(f"播放音效时出错: {e}")
        self.sound_enabled = False
        self.sound_button.config(state=tk.DISABLED, text="音效: 出错")

def check_guess(self, event=None):
    # ... 原有代码 ...
    # 检查猜测结果
    if guess < self.secret_number:
        self.hint_label.config(text="猜小了!再大一点。", fg="blue")
        self.play_sound("incorrect")  # 播放猜错音效
    elif guess > self.secret_number:
        self.hint_label.config(text="猜大了!再小一点。", fg="orange")
        self.play_sound("incorrect")  # 播放猜错音效
    else:
        self.hint_label.config(text=f"恭喜你,猜对了!答案就是 {self.secret_number}。", fg="green")
        self.play_sound("correct")  # 播放猜对音效
    # ... 原有代码 ...

在这里插入图片描述

总结

通过这个猜数字游戏项目,我们学习了 Python 编程的多个方面:

  1. 基础语法:变量、数据类型、控制结构、函数等
  2. 面向对象编程:使用类和对象组织代码,提高代码的可维护性
  3. 模块化设计:将不同功能封装为独立的模块和方法
  4. 图形界面开发:使用 Tkinter 创建交互式应用程序
  5. 用户交互与体验:设计友好的界面和流畅的用户体验

这个项目不仅帮助你掌握了 Python 编程的基础知识,还为你开发更复杂的应用程序打下了坚实的基础。建议你继续扩展这个游戏,添加更多功能,进一步提升自己的编程技能!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值