石头剪刀布(Paper-Scissors-Rock)规则人人皆知,但亲手用代码实现一遍,你会对"如何把现实规则翻译成程序逻辑"有全新的体会。这个项目非常适合练手:数据结构、随机数、条件判断、循环一网打尽,而且代码量不大,十几行就能跑起来。
玩法介绍
玩家和电脑同时出拳,石头赢剪刀、剪刀赢布、布赢石头,相同则平局。我们做"人机对战"版:玩家输入 0/1/2 选择出拳,电脑随机出拳,每局判定胜负并计分,打完 5 局后公布总比分。
第 1 步:定义出拳选项
用列表存储三种出拳,编号约定:0=石头、1=剪刀、2=布。这个顺序不是随便定的——第 4 步的胜负判定会用到它的数学规律。
import random
choices = ["石头", "剪刀", "布"]
# 玩家输入 0/1/2,分别对应 石头/剪刀/布
第 2 步:玩家出拳与输入校验
用 input 读取编号,处理两种情况:输入不是数字、数字不在 0~2 范围内。用 while 循环 + continue 让玩家重新输入,直到合法为止。
while True:
text = input("请出拳(0=石头 1=剪刀 2=布): ")
if not text.isdigit():
print("请输入数字 0、1 或 2!")
continue
player = int(text)
if player not in (0, 1, 2):
print("编号必须是 0、1 或 2!")
continue
break
第 3 步:电脑随机出拳
电脑用 random.randint(0, 2) 生成一个随机编号,再用列表把它翻译成文字显示出来。这里体现了"编号 ↔ 名称"的双向映射思想。
computer = random.randint(0, 2)
print(f"你出 {choices[player]},电脑出 {choices[computer]}")
第 4 步:胜负判定
不用写一堆 if 嵌套,直接用编号之差:对上述顺序,只要 (player - computer) % 3 == 2 就是玩家赢,== 1 就是玩家输,== 0 平局。验证一下:石头(0) 对 剪刀(1),(0-1) % 3 = 2,石头赢,正确!
diff = (player - computer) % 3
if diff == 0:
print("平局!")
elif diff == 2:
print("你赢啦!")
else:
print("你输了...")
这个取模技巧的本质:把三种出拳排成一个环,胜负只取决于环上的相对位置,与具体编号无关。理解它比背代码更有价值。
第 5 步:计分与多局循环
用两个变量记分,用 for 循环固定打 5 局;每局结束打印当前比分,全部打完公布最终结果。下面这段是完整版,已经包含出拳定义,可直接运行:
import random
choices = ["石头", "剪刀", "布"]
wins = losses = 0
for round_no in range(1, 6):
print(f"\n===== 第 {round_no} 局 =====")
while True:
text = input("请出拳(0=石头 1=剪刀 2=布): ")
if not text.isdigit():
print("请输入数字 0、1 或 2!")
continue
player = int(text)
if player not in (0, 1, 2):
print("编号必须是 0、1 或 2!")
continue
break
computer = random.randint(0, 2)
print(f"你出 {choices[player]},电脑出 {choices[computer]}")
diff = (player - computer) % 3
if diff == 0:
print("平局!")
elif diff == 2:
print("你赢啦!")
wins += 1
else:
print("你输了...")
losses += 1
print(f"当前比分:你 {wins} : {losses} 电脑")
print("\n===== 最终结果 =====")
if wins > losses:
print(f"恭喜你以 {wins}:{losses} 获胜!")
elif wins < losses:
print(f"可惜,{wins}:{losses},电脑赢了...")
else:
print(f"{wins}:{losses},打平!")
第 6 步:完整代码与运行
保存为 rps.py,运行 python3 rps.py 开玩,效果大致如下:
===== 第 1 局 =====
请出拳(0=石头 1=剪刀 2=布): 0
你出 石头,电脑出 剪刀
你赢啦!
当前比分:你 1 : 0 电脑
...
===== 最终结果 =====
恭喜你以 3:1 获胜!
想自由控制局数,可以把 for round_no in range(1, 6) 改成 while 循环并询问玩家是否继续。注意:第 4 步的取模判定与编号顺序绑定,如果自己改编号,判定公式也要跟着改——这正是"数据结构影响算法"的生动例子。
💡 改进方向:①改为三局两胜,提前分出胜负就结束;②让电脑"根据玩家上一手出克制拳",做成会成长的 AI;③在终端打印石头/剪刀/布的 ASCII 图案,观感更佳;④用 pygame 做出拳动画,把文字游戏升级成真正的"游戏"。