趣味十足的石头剪刀布游戏:从代码到策略的全面解析

石头剪刀布作为一款广为人知的经典猜拳游戏,凭借其简单的规则和充满不确定性的玩法,深受各年龄段人群的喜爱。下面将为你详细介绍一个用 Python 编写的石头剪刀布游戏程序,该程序不仅实现了基础的游戏功能,还融入了多种策略,让游戏更具趣味性和挑战性。

一、游戏规则与目标概述

(一)基础游戏规则

本游戏以回合制的形式进行,具体规则如下:

(二)游戏获胜目标

游戏采用积分制,率先获得 5 分的一方将赢得整个系列赛的胜利。

二、代码结构与核心功能解析

(一)关键数据结构


beats = {'r': 's', 'p': 'r', 's': 'p'}
loses = {value: key for key, value in beats.items()}
state = {'player': 0, 'computer': 0, 'ties': 0}
guesses = []
default = random.choice('rps')
        

- beats字典:用于定义每种选择能击败的对象,例如beats['r'] = 's',表示石头(r)可以击败剪刀(s)。

- loses字典:通过对beats字典进行键值对反转得到,它定义了每种选择会被什么对象击败,比如loses['s'] = 'r',意味着剪刀(s)会被石头(r)击败。

- state字典:用于记录游戏的当前状态,包含玩家得分、电脑得分以及平局的次数。

- guesses列表:用于存储每一轮游戏中玩家和电脑的选择。

- default变量:随机选择初始的默认出拳选项。

(二)策略函数实现

程序中实现了三种不同的策略,电脑会随机选择其中一种策略来出拳:

  1. always_same 函数

    始终保持出同一种拳,即返回初始随机选择的default值。

    
    def always_same():
        return default
                    
  2. random_strategy 函数

    每次都随机从'r'、'p'、's'中选择一个出拳。

    
    def random_strategy():
        return random.choice('rps')
                    
  3. beat_last 函数

    根据玩家上一轮的出拳来选择能击败它的拳。如果是第一轮游戏,没有上一轮的记录,就返回default值。

    
    def beat_last():
        if not guesses:
            return default
        last, _ = guesses[-1]
        return loses[last]
                    

(三)玩家输入处理


def get_option():
    while True:
        choice = input('Enter "r" for rock, "p" for paper, "s" for scissors: ')
        if choice not in beats:
            print('Invalid choice.')
            continue
        return choice
        

(四)游戏主循环


print(__doc__)

while True:
    player = get_option()
    computer = strategy()
    guess = (player, computer)
    guesses.append(guess)

    print('Player chooses:', player)
    print('Computer chooses:', computer)

    if player == computer:
        state['ties'] += 1
        print('Tie!')
    elif beats[player] == computer:
        state['player'] += 1
        print('Player wins!')
    else:
        state['computer'] += 1
        print('Computer wins!')

    print()
    print('Player points:', state['player'])
    print('Computer points:', state['computer'])
    print()

    if state['player'] == 5:
        print('PLAYER WINS!')
        break

    if state['computer'] == 5:
        print('COMPUTER WINS!')
        break

print('Computer strategy:', strategy.__name__)
        

三、扩展练习与策略创新

(一)题目要求的策略实现

  1. 循环轮换策略

    
    def cycle_strategy():
        cycle = ['r', 'p', 's']
        # 假设用一个全局变量来记录当前索引
        if not hasattr(cycle_strategy, 'index'):
            cycle_strategy.index = 0
        result = cycle[cycle_strategy.index]
        cycle_strategy.index = (cycle_strategy.index + 1) % 3
        return result
                    
  2. 模仿上一次电脑选择的策略

    
    def copy_last_computer():
        if not guesses:
            return default
        _, last_computer = guesses[-1]
        return last_computer
                    

(二)自定义创新策略

  1. 统计偏好策略

    
    def statistical_strategy():
        if not guesses:
            return default
        player_choices = [choice[0] for choice in guesses]
        from collections import Counter
        most_common = Counter(player_choices).most_common(1)
        if most_common:
            preferred = most_common[0][0]
            return beats[preferred]
        return random_strategy()
                    
  2. 心理博弈策略

    
    def psychological_strategy():
        if not guesses:
            return default
        last_player, last_computer = guesses[-1]
        
        # 上一轮平局
        if last_player == last_computer:
            return beats[last_computer]
        # 上一轮玩家赢
        elif beats[last_player] == last_computer:
            return last_computer
        # 上一轮电脑赢
        else:
            options = ['r', 'p', 's']
            options.remove(last_computer)
            return random.choice(options)
                    

四、游戏运行示例与分析

假设电脑选择了beat_last策略(即根据玩家上一轮的出拳来选择能击败它的拳),游戏的运行过程可能如下:

  1. 第一轮
    • 玩家输入:r
    • 电脑选择:因为是第一轮,没有上一轮记录,所以返回default(假设为 p)
    • 结果:玩家出 r,电脑出 p,p 覆盖 r,电脑赢,电脑得 1 分。
  2. 第二轮
    • 玩家输入:s
    • 电脑选择:根据上一轮玩家出的 r,选择能击败 r 的 p(因为loses['r'] = 'p'
    • 结果:玩家出 s,电脑出 p,s 剪断 p,玩家赢,玩家得 1 分。
  3. 第三轮
    • 玩家输入:p
    • 电脑选择:根据上一轮玩家出的 s,选择能击败 s 的 r(因为loses['s'] = 'r'
    • 结果:玩家出 p,电脑出 r,p 覆盖 r,玩家赢,玩家得 2 分。
  4. 后续轮次
    • 继续按照这样的规则进行,直到有一方获得 5 分。

通过这个游戏示例可以看出,beat_last策略在一定程度上能够针对玩家的出拳进行反击,但如果玩家能够识破这一策略并进行相应的调整,就有可能在游戏中占据优势。这也体现了石头剪刀布游戏不仅是一个靠运气的游戏,还包含了策略和心理的博弈。

五、总结与拓展方向

(一)游戏特点总结

(二)拓展方向

  1. 图形用户界面(GUI):可以使用 Tkinter、PyQt 等库为游戏添加图形界面,使游戏更加直观和美观。
  2. 网络对战功能:实现网络连接功能,让玩家可以与远程的朋友进行对战。
  3. 更多策略:可以继续开发更多有趣的策略,如基于机器学习的策略,让电脑能够通过学习玩家的历史出拳来提高胜率。
  4. 游戏统计与分析:添加游戏统计功能,记录玩家的游戏历史、胜率等信息,并进行分析和展示。

通过对这个石头剪刀布游戏的解析和拓展,我们可以看到简单的游戏背后也蕴含着丰富的编程知识和策略思考。无论是对于编程初学者还是有经验的开发者,都可以从这个游戏中获得启发和乐趣。