第29课:猜拳游戏V1.0——人机猜拳游戏
🎯 本课目标
- 综合运用条件判断和随机数
- 制作完整的人机对战猜拳游戏
- 实现游戏计分和胜负判定
- 添加多轮对战和统计功能
- 优化游戏交互体验
🤔 趣味引入:猜拳的"智慧"
想象一下:猜拳不只是运气,也有"智慧":
- ✊ 石头 → 砸碎剪刀,被布包裹
- ✋ 布 → 包裹石头,被剪刀剪破
- ✌️ 剪刀 → 剪破布,被石头砸碎
猜拳口诀:
- 石头赢剪刀,剪刀赢布,布赢石头
- 相同的出拳就是平局
今天,让我们一起用Python制作人机猜拳游戏,看看是你的运气好,还是电脑更聪明!
🔧 第一部分:基础猜拳游戏
1.1 最简单的猜拳
# 最简单的猜拳游戏
print("✊ 基础猜拳游戏")
print("=" * 50)
import random
def get_computer_choice():
"""电脑随机出拳"""
choices = ["石头", "剪刀", "布"]
return random.choice(choices)
def determine_winner(player, computer):
"""判断胜负"""
if player == computer:
return "平局"
if (player == "石头" and computer == "剪刀") or \
(player == "剪刀" and computer == "布") or \
(player == "布" and computer == "石头"):
return "玩家赢"
else:
return "电脑赢"
# 游戏开始
print("🎮 猜拳游戏开始!")
print("规则:石头赢剪刀,剪刀赢布,布赢石头")
print("=" * 40)
# 玩家出拳
player_choice = input("请出拳(石头/剪刀/布):")
# 验证输入
if player_choice in ["石头", "剪刀", "布"]:
# 电脑出拳
computer_choice = get_computer_choice()
# 判断胜负
result = determine_winner(player_choice, computer_choice)
# 显示结果
print(f"\n你出:{player_choice}")
print(f"电脑出:{computer_choice}")
print(f"结果:{result}")
else:
print("❌ 请输入:石头、剪刀或布")
1.2 带数字选择的猜拳
# 带数字选择的猜拳
print("\n🎮 数字选择猜拳")
print("=" * 50)
def get_choice_name(number):
"""根据数字返回对应的出拳名称"""
if number == 1:
return "石头"
elif number == 2:
return "剪刀"
elif number == 3:
return "布"
else:
return None
def get_choice_emoji(choice):
"""获取出拳表情"""
if choice == "石头":
return "✊"
elif choice == "剪刀":
return "✌️"
elif choice == "布":
return "✋"
return ""
print("请选择出拳:")
print("1. ✊ 石头")
print("2. ✌️ 剪刀")
print("3. ✋ 布")
try:
player_num = int(input("请输入(1-3):"))
if player_num in [1, 2, 3]:
player_choice = get_choice_name(player_num)
computer_choice = get_computer_choice()
result = determine_winner(player_choice, computer_choice)
player_emoji = get_choice_emoji(player_choice)
computer_emoji = get_choice_emoji(computer_choice)
print(f"\n{player_emoji} 你出:{player_choice}")
print(f"{computer_emoji} 电脑出:{computer_choice}")
print(f"结果:{result}")
else:
print("❌ 请输入1-3的数字!")
except ValueError:
print("❌ 请输入有效的数字!")
📊 第二部分:多轮对战系统
2.1 三局两胜制
# 三局两胜制猜拳
print("\n🏆 三局两胜制猜拳")
print("=" * 50)
def play_best_of_three():
"""三局两胜制游戏"""
player_score = 0
computer_score = 0
round_num = 1
print("🎮 三局两胜制开始!")
print("先赢两局者获胜!")
print("=" * 40)
while player_score < 2 and computer_score < 2:
print(f"\n📊 第{round_num}局")
print(f"当前比分:你 {player_score} - {computer_score} 电脑")
# 玩家出拳
print("\n请选择:")
print("1. ✊ 石头")
print("2. ✌️ 剪刀")
print("3. ✋ 布")
try:
player_num = int(input("请输入(1-3):"))
if player_num not in [1, 2, 3]:
print("❌ 请输入1-3!")
continue
player_choice = get_choice_name(player_num)
computer_choice = get_computer_choice()
result = determine_winner(player_choice, computer_choice)
player_emoji = get_choice_emoji(player_choice)
computer_emoji = get_choice_emoji(computer_choice)
print(f"\n{player_emoji} 你出:{player_choice}")
print(f"{computer_emoji} 电脑出:{computer_choice}")
if result == "玩家赢":
player_score += 1
print("🎉 你赢了这一局!")
elif result == "电脑赢":
computer_score += 1
print("💻 电脑赢了这一局!")
else:
print("🤝 平局!")
round_num += 1
except ValueError:
print("❌ 请输入数字!")
# 最终结果
print(f"\n{'='*50}")
print(f"{'🏆 最终结果':^50}")
print(f"{'='*50}")
print(f"最终比分:你 {player_score} - {computer_score} 电脑")
if player_score > computer_score:
print("🎉 恭喜你赢得了比赛!")
else:
print("💪 电脑赢了,下次加油!")
play_best_of_three()
2.2 五局三胜制
# 五局三胜制猜拳
print("\n🏆 五局三胜制猜拳")
print("=" * 50)
class RockPaperScissors:
"""猜拳游戏类"""
def __init__(self, rounds_to_win=3):
self.rounds_to_win = rounds_to_win
self.player_score = 0
self.computer_score = 0
self.draw_count = 0
self.total_rounds = 0
self.history = []
def play_round(self):
"""进行一局游戏"""
self.total_rounds += 1
print(f"\n📊 第{self.total_rounds}局")
print(f"当前比分:你 {self.player_score} - {self.computer_score} 电脑")
print(f"平局次数:{self.draw_count}")
# 玩家出拳
print("\n请选择:")
print("1. ✊ 石头")
print("2. ✌️ 剪刀")
print("3. ✋ 布")
print("0. 🚪 认输退出")
try:
player_num = int(input("请输入(0-3):"))
if player_num == 0:
return "quit"
if player_num not in [1, 2, 3]:
print("❌ 请输入0-3!")
return "invalid"
player_choice = get_choice_name(player_num)
computer_choice = get_computer_choice()
result = determine_winner(player_choice, computer_choice)
player_emoji = get_choice_emoji(player_choice)
computer_emoji = get_choice_emoji(computer_choice)
print(f"\n{player_emoji} 你出:{player_choice}")
print(f"{computer_emoji} 电脑出:{computer_choice}")
# 记录历史
self.history.append({
"round": self.total_rounds,
"player": player_choice,
"computer": computer_choice,
"result": result
})
if result == "玩家赢":
self.player_score += 1
print("🎉 你赢了这一局!")
elif result == "电脑赢":
self.computer_score += 1
print("💻 电脑赢了这一局!")
else:
self.draw_count += 1
print("🤝 平局!")
return result
except ValueError:
print("❌ 请输入数字!")
return "invalid"
def is_game_over(self):
"""判断游戏是否结束"""
return (self.player_score >= self.rounds_to_win or
self.computer_score >= self.rounds_to_win)
def get_winner(self):
"""获取最终胜者"""
if self.player_score > self.computer_score:
return "玩家"
elif self.computer_score > self.player_score:
return "电脑"
else:
return "平局"
def show_statistics(self):
"""显示统计数据"""
print(f"\n{'='*50}")
print(f"{'📊 比赛统计':^50}")
print(f"{'='*50}")
print(f"\n📈 总局数:{self.total_rounds}")
print(f"🏆 玩家胜:{self.player_score}局")
print(f"💻 电脑胜:{self.computer_score}局")
print(f"🤝 平局:{self.draw_count}局")
if self.total_rounds > 0:
win_rate = (self.player_score / self.total_rounds) * 100
print(f"📊 胜率:{win_rate:.1f}%")
# 出拳统计
player_choices = [h["player"] for h in self.history]
if player_choices:
print(f"\n📋 出拳统计:")
for choice in ["石头", "剪刀", "布"]:
count = player_choices.count(choice)
percentage = (count / len(player_choices)) * 100
bar = "█" * count
print(f" {choice}:{bar} {count}次({percentage:.0f}%)")
# 连胜记录
max_win_streak = 0
current_streak = 0
for h in self.history:
if h["result"] == "玩家赢":
current_streak += 1
max_win_streak = max(max_win_streak, current_streak)
else:
current_streak = 0
if max_win_streak > 0:
print(f"\n🔥 最长连胜:{max_win_streak}局")
def play_game(self):
"""运行完整游戏"""
print(f"🎮 欢迎来到猜拳游戏!")
print(f"🏆 {self.rounds_to_win}局{self.rounds_to_win}胜制")
print("先赢3局者获胜!")
print("=" * 40)
while not self.is_game_over():
result = self.play_round()
if result == "quit":
print("\n👋 你选择了认输退出")
break
if self.is_game_over():
winner = self.get_winner()
print(f"\n{'='*50}")
print(f"{'🏆 比赛结束!':^50}")
print(f"{'='*50}")
if winner == "玩家":
print("🎉🎉🎉 恭喜你赢得比赛!")
elif winner == "电脑":
print("💪 电脑赢得了比赛,下次加油!")
else:
print("🤝 平局!势均力敌!")
# 显示统计
self.show_statistics()
# 运行五局三胜制游戏
game = RockPaperScissors(3)
game.play_game()
🎯 第三部分:高级猜拳游戏
3.1 智能猜拳(带策略)
# 智能猜拳
print("\n🧠 智能猜拳游戏")
print("=" * 50)
class SmartRockPaperScissors(RockPaperScissors):
"""智能猜拳游戏类"""
def __init__(self, rounds_to_win=3):
super().__init__(rounds_to_win)
self.difficulty = "normal"
self.player_pattern = []
self.pattern_length = 3
def set_difficulty(self, difficulty):
"""设置难度"""
self.difficulty = difficulty
def smart_computer_choice(self):
"""智能选择电脑出拳"""
if self.difficulty == "easy":
# 简单模式:完全随机
return random.choice(["石头", "剪刀", "布"])
elif self.difficulty == "normal":
# 普通模式:50%随机,50%反制
if random.random() < 0.5:
return random.choice(["石头", "剪刀", "布"])
else:
return self.predict_and_counter()
elif self.difficulty == "hard":
# 困难模式:70%反制
if random.random() < 0.7:
return self.predict_and_counter()
else:
return random.choice(["石头", "剪刀", "布"])
else:
return random.choice(["石头", "剪刀", "布"])
def predict_and_counter(self):
"""预测玩家出拳并进行反制"""
if len(self.player_pattern) < self.pattern_length:
return random.choice(["石头", "剪刀", "布"])
# 分析玩家最近出拳模式
recent = self.player_pattern[-self.pattern_length:]
# 统计每种出拳的频率
counts = {"石头": 0, "剪刀": 0, "布": 0}
for choice in recent:
if choice in counts:
counts[choice] += 1
# 预测玩家最可能出的拳
predicted = max(counts, key=counts.get)
# 选择克制预测的出拳
counter = {
"石头": "布", # 布包石头
"剪刀": "石头", # 石头砸剪刀
"布": "剪刀" # 剪刀剪布
}
return counter[predicted]
def play_round(self):
"""重写play_round方法"""
self.total_rounds += 1
print(f"\n📊 第{self.total_rounds}局")
print(f"当前比分:你 {self.player_score} - {self.computer_score} 电脑")
print(f"难度:{'简单' if self.difficulty=='easy' else '普通' if self.difficulty=='normal' else '困难'}")
print("\n请选择:")
print("1. ✊ 石头")
print("2. ✌️ 剪刀")
print("3. ✋ 布")
print("0. 🚪 退出")
try:
player_num = int(input("请输入(0-3):"))
if player_num == 0:
return "quit"
if player_num not in [1, 2, 3]:
print("❌ 请输入0-3!")
return "invalid"
player_choice = get_choice_name(player_num)
# 记录玩家出拳模式
self.player_pattern.append(player_choice)
if len(self.player_pattern) > 10:
self.player_pattern.pop(0)
# 电脑智能出拳
computer_choice = self.smart_computer_choice()
result = determine_winner(player_choice, computer_choice)
player_emoji = get_choice_emoji(player_choice)
computer_emoji = get_choice_emoji(computer_choice)
print(f"\n{player_emoji} 你出:{player_choice}")
print(f"{computer_emoji} 电脑出:{computer_choice}")
# 记录历史
self.history.append({
"round": self.total_rounds,
"player": player_choice,
"computer": computer_choice,
"result": result
})
if result == "玩家赢":
self.player_score += 1
print("🎉 你赢了这一局!")
elif result == "电脑赢":
self.computer_score += 1
print("💻 电脑赢了这一局!")
else:
self.draw_count += 1
print("🤝 平局!")
return result
except ValueError:
print("❌ 请输入数字!")
return "invalid"
# 智能猜拳游戏
smart_game = SmartRockPaperScissors(3)
print("🎮 欢迎来到智能猜拳游戏!")
print("=" * 50)
print("请选择难度:")
print("1. 🌱 简单 - 电脑随机出拳")
print("2. 🌿 普通 - 电脑偶尔反制")
print("3. 🌳 困难 - 电脑会学习你的模式")
difficulty_choice = input("请选择(1-3):")
if difficulty_choice == "1":
smart_game.set_difficulty("easy")
elif difficulty_choice == "2":
smart_game.set_difficulty("normal")
elif difficulty_choice == "3":
smart_game.set_difficulty("hard")
else:
print("使用默认难度:普通")
smart_game.set_difficulty("normal")
smart_game.play_game()
3.2 多人猜拳锦标赛
# 多人猜拳锦标赛
print("\n🏟️ 多人猜拳锦标赛")
print("=" * 50)
class Tournament:
"""猜拳锦标赛类"""
def __init__(self):
self.players = []
self.matches = []
self.results = {}
def add_player(self, name):
"""添加选手"""
if name not in self.players:
self.players.append(name)
self.results[name] = {"wins": 0, "losses": 0, "draws": 0}
return True
return False
def remove_player(self, name):
"""移除选手"""
if name in self.players:
self.players.remove(name)
del self.results[name]
return True
return False
def play_match(self, player1, player2, rounds=3):
"""进行一场比赛"""
if player1 not in self.players or player2 not in self.players:
return None
p1_score = 0
p2_score = 0
match_history = []
print(f"\n⚔️ {player1} VS {player2}")
print(f"比赛采用{rounds}局{rounds//2+1}胜制")
for round_num in range(1, rounds + 1):
print(f"\n--- 第{round_num}局 ---")
# 玩家1出拳
print(f"\n{player1}请出拳:")
print("1. ✊ 石头 2. ✌️ 剪刀 3. ✋ 布")
p1_num = int(input("选择:"))
p1_choice = get_choice_name(p1_num)
# 玩家2出拳
print(f"\n{player2}请出拳:")
print("1. ✊ 石头 2. ✌️ 剪刀 3. ✋ 布")
p2_num = int(input("选择:"))
p2_choice = get_choice_name(p2_num)
# 判断胜负
if p1_choice == p2_choice:
result = "平局"
elif (p1_choice == "石头" and p2_choice == "剪刀") or \
(p1_choice == "剪刀" and p2_choice == "布") or \
(p1_choice == "布" and p2_choice == "石头"):
result = f"{player1}赢"
p1_score += 1
else:
result = f"{player2}赢"
p2_score += 1
match_history.append({
"round": round_num,
player1: p1_choice,
player2: p2_choice,
"result": result
})
print(f"\n{player1}出:{get_choice_emoji(p1_choice)} {p1_choice}")
print(f"{player2}出:{get_choice_emoji(p2_choice)} {p2_choice}")
print(f"结果:{result}")
if p1_score > rounds // 2 or p2_score > rounds // 2:
break
# 记录比赛结果
if p1_score > p2_score:
winner = player1
loser = player2
elif p2_score > p1_score:
winner = player2
loser = player1
else:
winner = None
loser = None
match_record = {
"player1": player1,
"player2": player2,
"p1_score": p1_score,
"p2_score": p2_score,
"winner": winner,
"history": match_history
}
self.matches.append(match_record)
# 更新统计
if winner:
self.results[winner]["wins"] += 1
self.results[loser]["losses"] += 1
else:
self.results[player1]["draws"] += 1
self.results[player2]["draws"] += 1
return match_record
def show_standings(self):
"""显示排名"""
print(f"\n{'='*50}")
print(f"{'🏆 锦标赛排名':^50}")
print(f"{'='*50}")
sorted_players = sorted(
self.players,
key=lambda p: self.results[p]["wins"],
reverse=True
)
print(f"\n{'排名':<6} {'选手':<10} {'胜':>4} {'负':>4} {'平':>4} {'胜率':>8}")
print("-" * 44)
for i, player in enumerate(sorted_players, 1):
stats = self.results[player]
total = stats["wins"] + stats["losses"] + stats["draws"]
win_rate = (stats["wins"] / total * 100) if total > 0 else 0
medal = ""
if i == 1:
medal = "🥇"
elif i == 2:
medal = "🥈"
elif i == 3:
medal = "🥉"
print(f"{medal}{i:<4} {player:<10} {stats['wins']:>4} {stats['losses']:>4} {stats['draws']:>4} {win_rate:>7.1f}%")
def show_match_history(self):
"""显示比赛历史"""
if not self.matches:
print("暂无比赛记录")
return
print(f"\n{'='*50}")
print(f"{'📋 比赛记录':^50}")
print(f"{'='*50}")
for i, match in enumerate(self.matches, 1):
print(f"\n比赛{i}:{match['player1']} VS {match['player2']}")
print(f"比分:{match['p1_score']} - {match['p2_score']}")
if match['winner']:
print(f"胜者:{match['winner']}")
else:
print("结果:平局")
# 锦标赛系统
tournament = Tournament()
print("🎮 欢迎来到猜拳锦标赛!")
print("=" * 50)
while True:
print("\n请选择操作:")
print("1. 👤 添加选手")
print("2. ❌ 移除选手")
print("3. ⚔️ 进行比赛")
print("4. 🏆 查看排名")
print("5. 📋 查看比赛记录")
print("6. 🚪 退出")
choice = input("\n请选择(1-6):")
if choice == "6":
print("👋 再见!")
break
elif choice == "1":
name = input("选手姓名:")
if tournament.add_player(name):
print(f"✅ 已添加选手:{name}")
print(f"当前参赛选手:{'、'.join(tournament.players)}")
else:
print("❌ 选手已存在!")
elif choice == "2":
name = input("选手姓名:")
if tournament.remove_player(name):
print(f"✅ 已移除选手:{name}")
else:
print("❌ 选手不存在!")
elif choice == "3":
if len(tournament.players) < 2:
print("❌ 至少需要2名选手!")
continue
print(f"\n参赛选手:{'、'.join(tournament.players)}")
p1 = input("第一位选手:")
p2 = input("第二位选手:")
if p1 not in tournament.players or p2 not in tournament.players:
print("❌ 选手不存在!")
continue
if p1 == p2:
print("❌ 不能和自己比赛!")
continue
tournament.play_match(p1, p2)
elif choice == "4":
tournament.show_standings()
elif choice == "5":
tournament.show_match_history()
else:
print("❌ 请选择1-6!")
🎮 第四部分:猜拳游戏增强
4.1 猜拳游戏大厅
# 猜拳游戏大厅
print("\n🎪 猜拳游戏大厅")
print("=" * 50)
def game_lobby():
"""猜拳游戏大厅"""
print("""
╔═══════════════════════════╗
║ 🎪 猜拳游戏大厅 ║
╠═══════════════════════════╣
║ 1. 🎮 快速开始 ║
║ 2. 🏆 三局两胜 ║
║ 3. 🏆 五局三胜 ║
║ 4. 🧠 智能模式 ║
║ 5. 🏟️ 锦标赛 ║
║ 6. 📊 战绩查询 ║
║ 0. 🚪 退出 ║
╚═══════════════════════════╝
""")
while True:
choice = input("请选择游戏模式(0-6):")
if choice == "0":
print("👋 感谢游玩!再见!")
break
elif choice == "1":
# 快速开始(一局定胜负)
print("\n🎮 快速开始 - 一局定胜负!")
player = input("请输入你的名字:")
player_num = int(input("请出拳(1.石头 2.剪刀 3.布):"))
if player_num in [1, 2, 3]:
player_choice = get_choice_name(player_num)
computer_choice = get_computer_choice()
result = determine_winner(player_choice, computer_choice)
print(f"\n{player}出:{get_choice_emoji(player_choice)} {player_choice}")
print(f"电脑出:{get_choice_emoji(computer_choice)} {computer_choice}")
if result == "玩家赢":
print("🎉 你赢了!")
elif result == "电脑赢":
print("💻 电脑赢了!")
else:
print("🤝 平局!")
elif choice == "2":
play_best_of_three()
elif choice == "3":
game = RockPaperScissors(3)
game.play_game()
elif choice == "4":
smart_game = SmartRockPaperScissors(3)
print("\n请选择难度:")
print("1. 🌱 简单")
print("2. 🌿 普通")
print("3. 🌳 困难")
diff = input("请选择(1-3):")
if diff == "1":
smart_game.set_difficulty("easy")
elif diff == "2":
smart_game.set_difficulty("normal")
elif diff == "3":
smart_game.set_difficulty("hard")
else:
smart_game.set_difficulty("normal")
smart_game.play_game()
elif choice == "5":
# 锦标赛模式
tournament = Tournament()
print("\n🏟️ 猜拳锦标赛")
players_count = int(input("参赛人数:"))
for i in range(players_count):
name = input(f"选手{i+1}姓名:")
tournament.add_player(name)
# 循环赛
players = tournament.players
for i in range(len(players)):
for j in range(i + 1, len(players)):
print(f"\n⚔️ 比赛:{players[i]} VS {players[j]}")
tournament.play_match(players[i], players[j], rounds=3)
tournament.show_standings()
elif choice == "6":
# 战绩查询
print("\n📊 战绩查询")
print("此功能需要持久化存储,敬请期待!")
print("💡 提示:可以在游戏中查看即时统计")
else:
print("❌ 请选择0-6!")
input("\n按回车键继续...")
# 运行游戏大厅
game_lobby()
📅 下节课预告
第30课:阶段项目-智能收银系统——商品选择、折扣计算、找零
下节课你将学习:
- 综合运用第三阶段所有知识
- 制作完整的智能收银系统
- 实现商品选择和结算功能
- 添加折扣和优惠计算
- 制作找零和小票打印功能
预习思考:
- 超市收银系统有哪些功能?
- 如何计算多种商品的总额?
- 折扣和优惠怎么实现?
💬 给家长的话
亲爱的家长:
今天孩子制作了猜拳游戏,这是综合运用条件判断、随机数和循环的趣味项目。通过这个项目,孩子学会了如何设计完整的游戏程序。
孩子今天学会了:
- ✅ 制作完整的人机对战游戏
- ✅ 实现多轮对战和计分系统
- ✅ 设计智能出拳策略
- ✅ 制作多人锦标赛模式
- ✅ 统计和分析游戏数据
猜拳游戏的教育价值:
| 能力 | 在项目中的应用 | 培养价值 |
|------|---------------|---------|
| 逻辑思维 | 胜负判断逻辑 | 条件推理 |
| 策略思维 | 智能出拳策略 | 战略思考 |
| 数据分析 | 游戏统计 | 数据思维 |
| 系统设计 | 多模式游戏 | 架构思维 |
| 用户体验 | 交互设计 | 产品思维 |
您可以这样做:
亲子互动:
- 一起游戏:和孩子玩真人猜拳
- 策略讨论:分析猜拳的策略
- 代码修改:一起修改游戏规则
- 创意扩展:设计新的游戏模式
温馨提示:
- 游戏是学习编程的好方式
- 鼓励孩子设计自己的游戏规则
- 分析游戏背后的逻辑和策略
- 用编程创造快乐的亲子时光
🏆 今日成就
完成了今天的学习,你:
🎮 制作了猜拳游戏
🏆 实现了多轮对战
🧠 设计了智能策略
🏟️ 举办了锦标赛
📊 分析了游戏数据
挑战任务:
- 添加更多出拳选项(如蜥蜴、史波克)
- 制作图形界面版本
- 实现网络对战功能
- 添加音效和动画效果