← 返回列表
命令行猜数字游戏
一个经典的交互式脚本,利用 Random 模块生成随机数,并通过 While 循环判断用户输入。该案例展示了基本的逻辑控制、输入输出交互以及异常处理。
快速预览:
import random
target = random.randint(1, 100)
while True:
guess = int(input("请输入你猜测的数字: "))
if guess == target:
print("恭喜你,猜对了!")
break
print("太大了" if guess > target else "太小了")
应用场景与价值
虽然猜数字游戏看似简单,但它包含了程序设计的核心要素,是学习编程的绝佳入门案例:
- 编程教学: 适合初学者理解循环、条件判断、用户输入等基础概念
- 逻辑思维训练: 培养二分查找的思维方式,提升问题解决能力
- 交互式应用: 展示如何创建用户友好的命令行界面
- 游戏开发基础: 为开发更复杂的游戏打下基础(状态管理、用户反馈)
- 算法实践: 可扩展为 AI 自动猜数字,学习二分查找算法
这个简单的游戏蕴含了丰富的编程知识,是从"学习代码"到"用代码解决问题"的重要跨越。
基础知识
random 模块
random 模块提供了生成随机数的功能,是 Python 标准库的一部分。
import random
# 生成随机整数
random.randint(1, 100) # 1到100之间的随机整数(包含1和100)
random.randrange(0, 100, 5) # 0到100之间,步长为5的随机数
# 生成随机浮点数
random.random() # 0到1之间的随机浮点数
random.uniform(1.5, 5.5) # 1.5到5.5之间的随机浮点数
# 序列操作
random.choice([1, 2, 3]) # 从列表中随机选择一个元素
random.shuffle(my_list) # 随机打乱列表顺序
while 循环
while 循环在条件为真时持续执行代码块:
while 条件:
# 循环体
# 如果条件始终为真,将无限循环
break # 跳出循环
continue # 跳过本次循环,继续下一次
用户输入
input() 函数用于获取用户输入,返回字符串类型:
name = input("请输入你的名字: ") # 返回字符串
age = int(input("请输入年龄: ")) # 转换为整数
条件表达式(三元运算符)
Python 的简洁写法:
# 传统写法
if guess > target:
message = "太大了"
else:
message = "太小了"
# 条件表达式
message = "太大了" if guess > target else "太小了"
代码详解
让我们逐步分析猜数字游戏的实现逻辑:
import random
导入 random 模块,用于生成随机目标数字。
target = random.randint(1, 100)
生成1到100之间的随机整数作为目标数字。这个数字对玩家保密,是游戏的核心。
while True:
创建无限循环。游戏将持续进行,直到玩家猜对数字(通过 break 退出循环)。
guess = int(input("请输入你猜测的数字: "))
获取用户输入并转换为整数。注意:input() 返回的是字符串,必须用 int() 转换。
if guess == target:
print("恭喜你,猜对了!")
break
判断用户猜测是否正确。如果相等,显示祝贺信息并用 break 退出循环,游戏结束。
print("太大了" if guess > target else "太小了")
给出提示:如果猜测的数字大于目标数字,提示"太大了";否则提示"太小了"。使用条件表达式简化代码。
完整代码
基础版本:带计数和输入验证
import random
def guess_number_game():
"""猜数字游戏 - 基础版本"""
print("=" * 50)
print(" 欢迎来到猜数字游戏!")
print("=" * 50)
print("我已经想好了一个1到100之间的数字,")
print("请你来猜猜看是多少吧!\n")
target = random.randint(1, 100)
attempts = 0
max_attempts = 10
while attempts < max_attempts:
try:
guess = int(input(f"第 {attempts + 1} 次猜测,请输入数字 (1-100): "))
# 输入验证
if guess < 1 or guess > 100:
print("⚠️ 请输入1到100之间的数字!\n")
continue
attempts += 1
if guess == target:
print(f"\n🎉 恭喜你!猜对了!")
print(f"答案就是 {target},你用了 {attempts} 次猜测。")
# 评价
if attempts <= 3:
print("💯 太厉害了!你是猜数字高手!")
elif attempts <= 6:
print("👍 不错哦!")
else:
print("✅ 完成挑战!")
break
elif guess > target:
print(f"📉 太大了!还剩 {max_attempts - attempts} 次机会\n")
else:
print(f"📈 太小了!还剩 {max_attempts - attempts} 次机会\n")
except ValueError:
print("❌ 输入无效,请输入一个数字!\n")
else:
# 循环正常结束(未被 break 打断)
print(f"\n💔 游戏结束!你已用完所有机会。")
print(f"正确答案是: {target}")
# 运行游戏
if __name__ == "__main__":
guess_number_game()
# 询问是否再玩一次
while input("\n是否再玩一次?(y/n): ").lower() == 'y':
print("\n" + "-" * 50 + "\n")
guess_number_game()
print("\n感谢游玩!再见!👋")
进阶版本:难度选择和游戏历史
import random
from datetime import datetime
class NumberGuessingGame:
"""猜数字游戏类"""
DIFFICULTY_LEVELS = {
'1': {'name': '简单', 'range': (1, 50), 'attempts': 10},
'2': {'name': '中等', 'range': (1, 100), 'attempts': 8},
'3': {'name': '困难', 'range': (1, 200), 'attempts': 10},
'4': {'name': '专家', 'range': (1, 1000), 'attempts': 15}
}
def __init__(self):
self.game_history = []
def select_difficulty(self):
"""选择难度"""
print("\n请选择难度:")
for key, level in self.DIFFICULTY_LEVELS.items():
range_info = level['range']
print(f"{key}. {level['name']} - 范围: {range_info[0]}-{range_info[1]}, 机会: {level['attempts']}次")
while True:
choice = input("\n请输入难度 (1-4): ").strip()
if choice in self.DIFFICULTY_LEVELS:
return self.DIFFICULTY_LEVELS[choice]
print("无效选择,请重新输入")
def play_round(self, difficulty):
"""进行一局游戏"""
min_num, max_num = difficulty['range']
max_attempts = difficulty['attempts']
target = random.randint(min_num, max_num)
attempts = 0
guesses = []
print(f"\n开始游戏!数字范围: {min_num}-{max_num}")
print(f"你有 {max_attempts} 次猜测机会\n")
start_time = datetime.now()
while attempts < max_attempts:
try:
guess = int(input(f"[{attempts + 1}/{max_attempts}] 请输入你的猜测: "))
if guess < min_num or guess > max_num:
print(f"⚠️ 请输入 {min_num}-{max_num} 之间的数字!\n")
continue
attempts += 1
guesses.append(guess)
if guess == target:
end_time = datetime.now()
time_spent = (end_time - start_time).total_seconds()
print(f"\n🎉 恭喜!猜对了!")
print(f"答案: {target}")
print(f"用时: {time_spent:.1f}秒")
print(f"猜测次数: {attempts}")
print(f"猜测历史: {guesses}")
# 记录游戏历史
self.game_history.append({
'difficulty': difficulty['name'],
'attempts': attempts,
'time': time_spent,
'success': True
})
return True
# 提供更智能的提示
diff = abs(guess - target)
if diff <= 5:
hint = "🔥 非常接近!"
elif diff <= 10:
hint = "🌡️ 很接近了"
elif diff <= 20:
hint = "🌤️ 有点接近"
else:
hint = "❄️ 还很远"
direction = "太大了" if guess > target else "太小了"
print(f"{direction} {hint}\n")
except ValueError:
print("❌ 请输入有效数字!\n")
# 游戏失败
print(f"\n💔 游戏结束!正确答案是: {target}")
self.game_history.append({
'difficulty': difficulty['name'],
'attempts': max_attempts,
'time': (datetime.now() - start_time).total_seconds(),
'success': False
})
return False
def show_statistics(self):
"""显示游戏统计"""
if not self.game_history:
print("\n暂无游戏记录")
return
print("\n" + "=" * 50)
print(" 游戏统计")
print("=" * 50)
total_games = len(self.game_history)
wins = sum(1 for game in self.game_history if game['success'])
win_rate = (wins / total_games) * 100
print(f"总游戏局数: {total_games}")
print(f"胜利次数: {wins}")
print(f"胜率: {win_rate:.1f}%")
if wins > 0:
avg_attempts = sum(g['attempts'] for g in self.game_history if g['success']) / wins
avg_time = sum(g['time'] for g in self.game_history if g['success']) / wins
print(f"平均猜测次数: {avg_attempts:.1f}")
print(f"平均用时: {avg_time:.1f}秒")
print("=" * 50)
def run(self):
"""运行游戏主循环"""
print("=" * 50)
print(" 猜数字游戏 v2.0")
print("=" * 50)
while True:
print("\n请选择操作:")
print("1. 开始游戏")
print("2. 查看统计")
print("3. 退出")
choice = input("\n请输入选项 (1-3): ").strip()
if choice == '1':
difficulty = self.select_difficulty()
self.play_round(difficulty)
elif choice == '2':
self.show_statistics()
elif choice == '3':
print("\n感谢游玩!再见!👋")
break
else:
print("无效选项,请重新输入")
# 运行游戏
if __name__ == "__main__":
game = NumberGuessingGame()
game.run()
高级版本:AI 自动猜测(二分查找演示)
import random
import time
def ai_guess_number(min_num=1, max_num=100, show_process=True):
"""
AI 使用二分查找算法猜数字
参数:
min_num: 最小值
max_num: 最大值
show_process: 是否显示猜测过程
"""
target = random.randint(min_num, max_num)
attempts = 0
low = min_num
high = max_num
print(f"\nAI 开始猜测 {min_num}-{max_num} 之间的数字...")
print(f"(答案是 {target},但 AI 不知道)\n")
if show_process:
time.sleep(1)
while low <= high:
attempts += 1
# 二分查找:取中间值
guess = (low + high) // 2
if show_process:
print(f"第 {attempts} 次猜测: {guess} (范围: {low}-{high})")
time.sleep(0.5)
if guess == target:
print(f"\n✅ AI 猜对了!答案是 {target}")
print(f"用了 {attempts} 次猜测")
print(f"理论最少次数: {(max_num - min_num).bit_length()} 次")
return attempts
elif guess > target:
if show_process:
print(f" → 太大了,缩小范围到 {low}-{guess - 1}\n")
high = guess - 1
else:
if show_process:
print(f" → 太小了,缩小范围到 {guess + 1}-{high}\n")
low = guess + 1
return attempts
def compare_strategies(min_num=1, max_num=100, rounds=100):
"""
对比随机猜测和二分查找的效率
参数:
rounds: 测试轮数
"""
print(f"\n对比测试: 随机猜测 vs 二分查找")
print(f"范围: {min_num}-{max_num}, 测试轮数: {rounds}\n")
random_attempts = []
binary_attempts = []
for i in range(rounds):
target = random.randint(min_num, max_num)
# 随机猜测策略
attempts = 0
available = list(range(min_num, max_num + 1))
while True:
attempts += 1
guess = random.choice(available)
available.remove(guess)
if guess == target:
random_attempts.append(attempts)
break
# 二分查找策略
attempts = 0
low, high = min_num, max_num
while low <= high:
attempts += 1
guess = (low + high) // 2
if guess == target:
binary_attempts.append(attempts)
break
elif guess > target:
high = guess - 1
else:
low = guess + 1
# 输出结果
print("结果统计:")
print(f"随机猜测 - 平均: {sum(random_attempts) / len(random_attempts):.2f} 次")
print(f"二分查找 - 平均: {sum(binary_attempts) / len(binary_attempts):.2f} 次")
print(f"\n效率提升: {(1 - sum(binary_attempts) / sum(random_attempts)) * 100:.1f}%")
# 演示 AI 猜数字
ai_guess_number(1, 100, show_process=True)
# 策略对比
compare_strategies(1, 100, rounds=100)
运行示例
基础版本
uv run main.py
预期输出
==================================================
欢迎来到猜数字游戏!
==================================================
我已经想好了一个1到100之间的数字,
请你来猜猜看是多少吧!
第 1 次猜测,请输入数字 (1-100): 50
📈 太小了!还剩 9 次机会
第 2 次猜测,请输入数字 (1-100): 75
📉 太大了!还剩 8 次机会
第 3 次猜测,请输入数字 (1-100): 62
📈 太小了!还剩 7 次机会
第 4 次猜测,请输入数字 (1-100): 68
📉 太大了!还剩 6 次机会
第 5 次猜测,请输入数字 (1-100): 65
🎉 恭喜你!猜对了!
答案就是 65,你用了 5 次猜测。
👍 不错哦!
是否再玩一次?(y/n):
扩展思路
1. 多人对战模式
def multiplayer_mode():
"""两个玩家轮流猜测,看谁先猜对"""
target = random.randint(1, 100)
players = ['玩家1', '玩家2']
turn = 0
while True:
current_player = players[turn % 2]
guess = int(input(f"{current_player} 的回合,请输入猜测: "))
if guess == target:
print(f"🏆 {current_player} 获胜!")
break
else:
print("太大了" if guess > target else "太小了")
turn += 1
2. 反向模式:玩家想数字,AI 猜
def reverse_mode():
"""玩家想一个数字,AI 来猜"""
print("请在心里想一个1到100之间的数字,不要告诉我")
input("准备好了请按回车...")
low, high = 1, 100
attempts = 0
while low <= high:
attempts += 1
guess = (low + high) // 2
print(f"\n我猜是: {guess}")
feedback = input("(h=太大, l=太小, c=猜对了): ").lower()
if feedback == 'c':
print(f"太好了!我用了 {attempts} 次猜对了!")
break
elif feedback == 'h':
high = guess - 1
elif feedback == 'l':
low = guess + 1
3. 添加提示系统
hints = {
'even': lambda x: "是偶数" if x % 2 == 0 else "是奇数",
'divisible': lambda x: f"能被 {random.choice([3, 5, 7])} 整除" if x % 3 == 0 else "不能被3整除",
'digit_sum': lambda x: f"各位数字之和是 {sum(int(d) for d in str(x))}"
}
def get_hint(target, hint_type):
"""获取提示"""
return hints[hint_type](target)
4. 成就系统
achievements = {
'一击必中': lambda attempts: attempts == 1,
'三猜之内': lambda attempts: attempts <= 3,
'完美策略': lambda guesses, target: all(g < target for g in guesses[:-1][:len(guesses)//2]),
}
def check_achievements(attempts, guesses, target):
"""检查获得的成就"""
unlocked = []
for name, condition in achievements.items():
if condition(attempts):
unlocked.append(name)
return unlocked
5. 排行榜系统
import json
def save_score(name, attempts, difficulty):
"""保存分数到排行榜"""
try:
with open('leaderboard.json', 'r') as f:
leaderboard = json.load(f)
except FileNotFoundError:
leaderboard = []
leaderboard.append({
'name': name,
'attempts': attempts,
'difficulty': difficulty,
'date': datetime.now().isoformat()
})
# 按尝试次数排序
leaderboard.sort(key=lambda x: x['attempts'])
with open('leaderboard.json', 'w') as f:
json.dump(leaderboard[:10], f, indent=2) # 只保留前10名
6. 图形界面版本
使用 tkinter 创建 GUI:
import tkinter as tk
from tkinter import messagebox
class GuessNumberGUI:
def __init__(self, root):
self.root = root
self.root.title("猜数字游戏")
self.target = random.randint(1, 100)
self.attempts = 0
# 创建界面元素
self.label = tk.Label(root, text="猜一个1到100之间的数字")
self.label.pack()
self.entry = tk.Entry(root)
self.entry.pack()
self.button = tk.Button(root, text="猜测", command=self.make_guess)
self.button.pack()
def make_guess(self):
try:
guess = int(self.entry.get())
self.attempts += 1
if guess == self.target:
messagebox.showinfo("恭喜", f"猜对了!用了{self.attempts}次")
self.reset_game()
elif guess > self.target:
self.label.config(text="太大了!")
else:
self.label.config(text="太小了!")
self.entry.delete(0, tk.END)
except ValueError:
messagebox.showerror("错误", "请输入有效数字")
def reset_game(self):
self.target = random.randint(1, 100)
self.attempts = 0
self.label.config(text="猜一个1到100之间的数字")
root = tk.Root()
app = GuessNumberGUI(root)
root.mainloop()
学习要点
通过这个猜数字游戏,你可以掌握:
- 循环控制: while 循环的使用和退出条件
- 条件判断: if-elif-else 的逻辑组合
- 用户交互: input() 和 print() 的配合使用
- 异常处理: try-except 处理输入错误
- 数据验证: 检查用户输入的有效性
- 算法思维: 二分查找的实现和优化
- 面向对象: 用类组织游戏逻辑和数据
- 数据持久化: 保存游戏历史和排行榜
这些技能是编程的基础,掌握后可以应用到更复杂的项目中。猜数字游戏虽小,但五脏俱全,是学习编程的绝佳起点。