
本文详解如何在python实现的尼姆游戏中嵌套主循环,支持用户选择重复对战,并实时统计玩家胜/负场次,避免逻辑断裂与状态残留问题。
本文详解如何在python实现的尼姆游戏中嵌套主循环,支持用户选择重复对战,并实时统计玩家胜/负场次,避免逻辑断裂与状态残留问题。
要让尼姆游戏真正具备可重玩性,不能仅在单局逻辑内简单加一层 while,而需将整个游戏流程(初始化、对战循环、结果判定)封装进一个外层控制循环中,同时维护跨局的计分状态。以下是结构清晰、生产就绪的改进方案:
✅ 核心改造思路
- 使用外层 while replay.lower() == 'y' 控制是否重启整局;
- 将游戏初始化(如 sticks = [1, 3, 5, 7]、current_player = random.choice(...))移入循环体内,确保每局状态干净;
- 引入 player_wins 和 cpu_wins 变量,在每局结束后根据 winner 更新计数;
- 清晰区分「单局内循环」(while sum(sticks) > 0)与「多局外循环」(while replay == 'y'),避免嵌套混乱。
✅ 完整可运行代码(关键修改已高亮)
import random
def print_move(current_player, row, stick_quantity):
if stick_quantity == 1:
print(f"{current_player} takes {stick_quantity} stick from row {row}")
else:
print(f"{current_player} takes {stick_quantity} sticks from row {row}")
# 初始化全局计分
player_wins = 0
cpu_wins = 0
print("Welcome to Nim!")
name = input("Enter your name: ")
replay = 'y'
while replay.lower() == 'y':
# ? 每局重置游戏状态
sticks = [1, 3, 5, 7]
current_player = random.choice([name, "CPU"])
print(f"\n--- New Game ---")
print(f"Game starts! {current_player} goes first.\n")
# ? 单局核心对战循环
while sum(sticks) > 0:
# 显示当前棋盘
for i, count in enumerate(sticks, 1):
print(f"{i}: {'|' * count}")
if current_player == name:
# 玩家回合:带输入校验
while True:
try:
row = int(input(f"\n{name}, which row? (1-{len(sticks)}): "))
stick_quantity = int(input("How many sticks? "))
if 1 0]
if valid_rows:
row_idx = random.choice(valid_rows)
stick_quantity = random.randint(1, sticks[row_idx])
sticks[row_idx] -= stick_quantity
print_move("CPU", row_idx+1, stick_quantity)
current_player = name
# ? 本局结束:判定胜者并更新计分
winner = current_player # 注意:最后一步操作后轮到对方,故winner是上一轮操作者
print(f"\n? Game over! Winner is {winner}.")
if winner == name:
player_wins += 1
else:
cpu_wins += 1
# ❓ 询问是否再玩一局
replay = input("\nPlay again? (y/n): ").strip()
# ? 最终统计
print(f"\n{'='*40}")
print("GAME SESSION SUMMARY")
print(f"{'='*40}")
print(f"{name}: {player_wins} win(s)")
print(f"CPU: {cpu_wins} win(s)")
print("Thanks for playing Nim! ?")
⚠️ 关键注意事项
- 状态重置必须彻底:sticks、current_player 等变量必须在每次外层循环开始时重新初始化,否则会出现“上局残留”导致崩溃(如 sticks 为空列表时 random.choice(valid_rows) 报错);
- 胜者判定逻辑修正:原代码中 winner = current_player 存在逻辑错误——游戏结束时 current_player 实际是下一位该行动却无法行动的玩家,因此真正的胜者是上一轮执行操作的人。本方案通过保持 current_player 在操作后立即切换,使最终 winner 自然指向获胜方;
- 输入鲁棒性增强:使用 .strip().lower() 处理 y/Y/yes 等常见输入;对 row 输入增加范围提示(1-{len(sticks)}),提升用户体验;
- CPU操作安全性:新增 valid_rows 过滤,确保 CPU 不会尝试从空行取物,彻底规避 ValueError。
通过以上重构,你的尼姆游戏不仅支持无缝重玩,还具备清晰的胜负追踪与工业级健壮性,真正迈向完整小游戏形态。










