news 2026/2/7 13:20:14

开发简易AI猜拳游戏,机器随机出拳,记录对战胜胜率,探索简单博弈策略。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开发简易AI猜拳游戏,机器随机出拳,记录对战胜胜率,探索简单博弈策略。

我将为您开发一个功能完整的AI猜拳游戏系统,包含多种博弈策略和统计分析功能。

项目结构

ai_rock_paper_scissors/

├── main.py # 主程序入口

├── game_engine.py # 游戏引擎模块

├── ai_strategies.py # AI策略模块

├── statistics.py # 统计分析模块

├── player.py # 玩家类模块

├── utils.py # 工具函数模块

├── data_manager.py # 数据管理模块

├── config.py # 配置文件

├── requirements.txt # 依赖包列表

├── README.md # 项目说明

├── knowledge_cards.md # 核心知识点卡片

└── data/ # 数据存储目录

├── game_history.json

└── player_stats.json

1. requirements.txt

pandas>=1.3.0

numpy>=1.21.0

matplotlib>=3.5.0

seaborn>=0.11.0

tqdm>=4.64.0

collections-extended>=2.0.0

2. config.py - 配置文件

"""

AI猜拳游戏配置文件

包含游戏参数、AI策略配置、界面设置等

"""

# 游戏基础配置

GAME_CONFIG = {

"choices": ["石头", "剪刀", "布"],

"choice_symbols": {"石头": "✊", "剪刀": "✌️", "布": "✋"},

"win_rules": {

"石头": "剪刀", # 石头赢剪刀

"剪刀": "布", # 剪刀赢布

"布": "石头" # 布赢石头

},

"rounds_default": 10,

"save_history": True,

"show_animation": True

}

# AI策略配置

AI_STRATEGIES = {

"random": {

"name": "随机策略",

"description": "完全随机选择,作为基准策略",

"weight": 1.0

},

"frequency": {

"name": "频率分析策略",

"description": "分析对手历史选择频率,预测并克制",

"weight": 1.2,

"learning_rate": 0.1

},

"pattern": {

"name": "模式识别策略",

"description": "识别对手的选择模式,预测下一步",

"weight": 1.3,

"pattern_length": 3

},

"counter": {

"name": "反击策略",

"description": "针对对手的优势选择进行反击",

"weight": 1.1

},

"mixed": {

"name": "混合策略",

"description": "结合多种策略,动态调整权重",

"weight": 1.4,

"strategies": ["frequency", "pattern", "counter"]

}

}

# 统计分析配置

STATS_CONFIG = {

"track_detailed": True,

"save_interval": 10, # 每多少局保存一次数据

"charts_enabled": True,

"export_formats": ["json", "csv", "txt"]

}

# 难度等级配置

DIFFICULTY_LEVELS = {

"easy": {

"name": "简单",

"ai_strategy": "random",

"win_rate_target": 0.3

},

"normal": {

"name": "普通",

"ai_strategy": "frequency",

"win_rate_target": 0.5

},

"hard": {

"name": "困难",

"ai_strategy": "mixed",

"win_rate_target": 0.7

},

"expert": {

"name": "专家",

"ai_strategy": "pattern",

"win_rate_target": 0.8

}

}

3. utils.py - 工具函数模块

"""

工具函数模块

提供游戏所需的各种辅助函数

"""

import random

import time

import json

from typing import List, Dict, Tuple, Optional

from collections import Counter, defaultdict

from datetime import datetime

import numpy as np

class GameUtils:

"""游戏工具类"""

@staticmethod

def get_choice_index(choice: str) -> int:

"""

获取选择对应的索引

Args:

choice: 选择名称 ("石头", "剪刀", "布")

Returns:

对应的索引 (0, 1, 2)

"""

choices = ["石头", "剪刀", "布"]

try:

return choices.index(choice)

except ValueError:

raise ValueError(f"无效选择: {choice},有效选择为: {choices}")

@staticmethod

def get_choice_name(index: int) -> str:

"""

获取索引对应的选择名称

Args:

index: 索引 (0, 1, 2)

Returns:

选择名称

"""

choices = ["石头", "剪刀", "布"]

if 0 <= index < len(choices):

return choices[index]

else:

raise ValueError(f"无效索引: {index}")

@staticmethod

def determine_winner(player_choice: str, ai_choice: str,

win_rules: Dict[str, str]) -> str:

"""

判断胜负

Args:

player_choice: 玩家选择

ai_choice: AI选择

win_rules: 胜负规则

Returns:

"player": 玩家获胜, "ai": AI获胜, "tie": 平局

"""

if player_choice == ai_choice:

return "tie"

# 检查玩家是否获胜

if win_rules[player_choice] == ai_choice:

return "player"

else:

return "ai"

@staticmethod

def calculate_win_rate(wins: int, total_games: int) -> float:

"""

计算胜率

Args:

wins: 获胜次数

total_games: 总游戏次数

Returns:

胜率 (0.0-1.0)

"""

if total_games == 0:

return 0.0

return wins / total_games

@staticmethod

def format_percentage(value: float) -> str:

"""

格式化百分比显示

Args:

value: 小数形式的比例

Returns:

格式化的百分比字符串

"""

return f"{value:.1%}"

@staticmethod

def animate_text(text: str, delay: float = 0.05):

"""

文字动画效果

Args:

text: 要显示的文本

delay: 字符间延迟时间

"""

for char in text:

print(char, end='', flush=True)

time.sleep(delay)

print()

class DataUtils:

"""数据处理工具类"""

@staticmethod

def save_json(data: Dict, filename: str):

"""

保存数据到JSON文件

Args:

data: 要保存的数据

filename: 文件名

"""

try:

with open(filename, 'w', encoding='utf-8') as f:

json.dump(data, f, ensure_ascii=False, indent=2)

except Exception as e:

print(f"保存文件失败: {e}")

@staticmethod

def load_json(filename: str) -> Dict:

"""

从JSON文件加载数据

Args:

filename: 文件名

Returns:

加载的数据字典

"""

try:

with open(filename, 'r', encoding='utf-8') as f:

return json.load(f)

except FileNotFoundError:

return {}

except Exception as e:

print(f"加载文件失败: {e}")

return {}

@staticmethod

def calculate_trend(values: List[float], window_size: int = 5) -> float:

"""

计算数值趋势

Args:

values: 数值列表

window_size: 滑动窗口大小

Returns:

趋势值 (-1到1,负值表示下降趋势,正值表示上升趋势)

"""

if len(values) < window_size:

return 0.0

recent_values = values[-window_size:]

x = np.arange(len(recent_values))

y = np.array(recent_values)

# 计算线性回归斜率

slope = np.polyfit(x, y, 1)[0]

# 归一化到[-1, 1]范围

normalized_slope = max(-1.0, min(1.0, slope * 10))

return normalized_slope

class StrategyUtils:

"""策略工具类"""

@staticmethod

def detect_pattern(sequence: List[str], pattern_length: int = 3) -> Optional[str]:

"""

检测序列中的模式

Args:

sequence: 选择序列

pattern_length: 模式长度

Returns:

预测的下一项,如果没有检测到模式则返回None

"""

if len(sequence) < pattern_length * 2:

return None

# 查找最近的模式

recent_pattern = sequence[-pattern_length:]

pattern_str = ''.join(recent_pattern)

# 在历史中查找相同模式后的选择

occurrences = []

for i in range(len(sequence) - pattern_length * 2):

if sequence[i:i+pattern_length] == recent_pattern:

next_choice = sequence[i + pattern_length]

occurrences.append(next_choice)

if occurrences:

# 返回最常见的后续选择

counter = Counter(occurrences)

return counter.most_common(1)[0][0]

return None

@staticmethod

def calculate_frequency_distribution(sequence: List[str]) -> Dict[str, float]:

"""

计算频率分布

Args:

sequence: 选择序列

Returns:

各选择的频率字典

"""

if not sequence:

return {"石头": 0.33, "剪刀": 0.33, "布": 0.34}

counter = Counter(sequence)

total = len(sequence)

return {

choice: count / total

for choice, count in counter.items()

}

@staticmethod

def get_counter_choice(target_choice: str) -> str:

"""

获取克制指定选择的选择

Args:

target_choice: 目标选择

Returns:

能克制目标选择的选择

"""

counter_map = {

"石头": "布", # 布克石头

"剪刀": "石头", # 石头克剪刀

"布": "剪刀" # 剪刀克布

}

return counter_map.get(target_choice, "石头")

class ValidationUtils:

"""数据验证工具类"""

@staticmethod

def validate_player_choice(choice: str) -> bool:

"""

验证玩家选择是否有效

Args:

choice: 玩家选择

Returns:

是否有效

"""

valid_choices = ["石头", "剪刀", "布", "1", "2", "3"]

return choice in valid_choices

@staticmethod

def normalize_choice(choice: str) -> str:

"""

标准化选择输入

Args:

choice: 原始输入

Returns:

标准化后的选择

"""

choice_map = {

"1": "石头",

"2": "剪刀",

"3": "布",

"石头": "石头",

"剪刀": "剪刀",

"布": "布"

}

return choice_map.get(choice, choice)

@staticmethod

def validate_game_config(config: Dict) -> bool:

"""

验证游戏配置是否有效

Args:

config: 配置字典

Returns:

是否有效

"""

required_keys = ["choices", "win_rules", "rounds_default"]

return all(key in config for key in required_keys)

4. player.py - 玩家类模块

"""

玩家类模块

定义玩家和AI的行为和属性

"""

from typing import List, Dict, Optional

from dataclasses import dataclass, field

from utils import GameUtils, StrategyUtils, ValidationUtils

@dataclass

class Player:

"""玩家基类"""

name: str

player_type: str = "human" # "human" 或 "ai"

stats: Dict[str, int] = field(default_factory=lambda: {

"wins": 0, "losses": 0, "ties": 0, "total_games": 0

})

choice_history: List[str] = field(default_factory=list)

win_rate_history: List[float] = field(default_factory=list)

def make_choice(self, **kwargs) -> str:

"""

做出选择(由子类实现)

Args:

**kwargs: 额外参数

Returns:

选择结果

"""

raise NotImplementedError("子类必须实现此方法")

def update_stats(self, result: str):

"""

更新统计数据

Args:

result: 游戏结果 ("win", "lose", "tie")

"""

self.stats["total_games"] += 1

if result == "win":

self.stats["wins"] += 1

elif result == "lose":

self.stats["losses"] += 1

elif result == "tie":

self.stats["ties"] += 1

# 更新胜率历史

current_win_rate = GameUtils.calculate_win_rate(

self.stats["wins"], self.stats["total_games"]

)

self.win_rate_history.append(current_win_rate)

def get_current_win_rate(self) -> float:

"""

获取当前胜率

Returns:

当前胜率

"""

return GameUtils.calculate_win_rate(

self.stats["wins"], self.stats["total_games"]

)

def get_choice_frequency(self) -> Dict[str, float]:

"""

获取选择频率

Returns:

各选择的频率

"""

return StrategyUtils.calculate_frequency_distribution(self.choice_history)

def add_choice_to_history(self, choice: str):

"""

添加选择到历史记录

Args:

choice: 选择结果

"""

self.choice_history.append(choice)

# 限制历史记录长度,避免内存占用过多

max_history = 1000

if len(self.choice_history) > max_history:

self.choice_history = self.choice_history[-max_history:]

class HumanPlayer(Player):

"""人类玩家类"""

def __init__(self, name: str = "玩家"):

super().__init__(name=name, player_type="human")

def make_choice(self, **kwargs) -> str:

"""

人类玩家做出选择

Args:

**kwargs: 额外参数,包括可用选择列表

Returns:

选择结果

"""

available_choices = kwargs.get("choices", ["石头", "剪刀", "布"])

while True:

try:

print(f"\n{self.name},请选择:")

for i, choice in enumerate(available_choices, 1):

print(f" {i}. {choice}")

user_input = input("\n请输入选择 (1-3 或 石头/剪刀/布): ").strip()

if ValidationUtils.validate_player_choice(user_input):

choice = ValidationUtils.normalize_choice(user_input)

# 验证选择是否在可用选项中

if choice in available_choices:

self.add_choice_to_history(choice)

return choice

else:

print("❌ 无效选择,请重试")

else:

print("❌ 输入格式错误,请重试")

except KeyboardInterrupt:

print("\n\n游戏被用户中断")

raise

except Exception as e:

print(f"❌ 发生错误: {e},请重试")

class AIPlayer(Player):

"""AI玩家类"""

def __init__(self, name: str = "AI", strategy: str = "random"):

super().__init__(name=name, player_type="ai")

self.strategy = strategy

self.strategy_weights = kwargs.get("strategy_weights", {})

self.opponent_history = []

self.pattern_memory = defaultdict(list)

def make_choice(self, **kwargs) -> str:

"""

AI根据策略做出选择

Args:

**kwargs: 额外参数,包括对手历史、游戏规则等

Returns:

选择结果

"""

opponent_history = kwargs.get("opponent_history", [])

available_choices = kwargs.get("choices", ["石头", "剪刀", "布"])

win_rules = kwargs.get("win_rules", {})

# 根据策略选择

if self.strategy == "random":

choice = self._random_strategy(available_choices)

elif self.strategy == "frequency":

choice = self._frequency_strategy(opponent_history, available_choices)

elif self.strategy == "pattern":

choice = self._pattern_strategy(opponent_history, available_choices)

elif self.strategy == "counter":

choice = self._counter_strategy(opponent_history, available_choices)

elif self.strategy == "mixed":

choice = self._mixed_strategy(opponent_history, available_choices, kwargs)

else:

choice = self._random_strategy(available_choices)

self.add_choice_to_history(choice)

return choice

def _random_strategy(self, available_choices: List[str]) -> str:

"""随机策略"""

return random.choice(available_choices)

def _frequency_strategy(self, opponent_history: List[str],

available_choices: List[str]) -> str:

"""

频率分析策略

分析对手历史选择,预测并克制最常出现的选择

"""

if not opponent_history:

return self._random_strategy(available_choices)

# 计算对手选择频率

freq_dist = StrategyUtils.calculate_frequency_distribution(opponent_history)

# 找出对手最常选择的选项

most_frequent = max(freq_dist.items(), key=lambda x: x[1])[0]

# 选择能克制对手最常选择项的选项

counter_choice = StrategyUtils.get_counter_choice(most_frequent)

# 确保选择可用

if counter_choice in available_choices:

return counter_choice

else:

return self._random_strategy(available_choices)

def _pattern_strategy(self, opponent_history: List[str],

available_choices: List[str]) -> str:

"""

模式识别策略

识别对手的选择模式,预测下一步

"""

if len(opponent_history) < 6: # 需要足够的历史数据

return self._frequency_strategy(opponent_history, available_choices)

# 尝试检测模式

predicted_choice = StrategyUtils.detect_pattern(opponent_history, pattern_length=3)

if predicted_choice:

# 如果检测到模式,选择克制预测选择的选项

counter_choice = StrategyUtils.get_counter_choice(predicted_choice)

if counter_choice in available_choices:

return counter_choice

# 如果没检测到模式,回退到频率策略

return self._frequency_strategy(opponent_history, available_choices)

def _counter_strategy(self, opponent_history: List[str],

available_choices: List[str]) -> str:

"""

反击策略

针对对手的优势选择进行反击

"""

if not opponent_history:

return self._random_strategy(available_choices)

# 分析对手的"优势"(即经常获胜的选择)

# 这里简化处理,直接找对手最近的选择趋势

recent_choices = opponent_history[-5:] if len(opponent_history) >= 5 else opponent_history

if recent_choices:

# 选择克制对手最近选择的选项

last_choice = recent_choices[-1]

counter_choice = StrategyUtils.get_counter_choice(last_choice)

if counter_choice in available_choices:

return counter_choice

return self._random_strategy(available_choices)

def _mixed_strategy(self, opponent_history: List[str],

available_choices: List[str],

kwargs: Dict) -> str:

"""

混合策略

结合多种策略,动态调整权重

"""

strategies = ["frequency", "pattern", "counter"]

weights = [0.4, 0.4, 0.2] # 默认权重

# 根据历史数据调整权重

if len(opponent_history) > 10:

# 如果有足够数据,增加模式识别的权重

weights = [0.3, 0.5, 0.2]

elif len(opponent_history) < 5:

# 如果数据较少,主要使用频率和反击策略

weights = [0.5, 0.2, 0.3]

# 随机选择策略(根据权重)

chosen_strategy = random.choices(strategies, weights=weights)[0]

# 调用对应策略

if chosen_strategy == "frequency":

return self._frequency_strategy(opponent_history, available_choices)

elif chosen_strategy == "pattern":

return self._pattern_strategy(opponent_history, available_choices)

elif chosen_strategy == "counter":

return self._counter_strategy(opponent_history, available_choices)

else:

return self._random_strategy(available_choices)

def update_opponent_history(self, opponent_choice: str):

"""

更新对手历史记录

Args:

opponent_choice: 对手的选择

"""

self.opponent_history.append(opponent_choice)

# 限制历史记录长度

max_history = 500

if len(self.opponent_history) > max_history:

self.opponent_history = self.opponent_history[-max_history:]

def set_strategy(self, strategy: str):

"""

设置AI策略

Args:

strategy: 策略名称

"""

self.strategy = strategy

def get_strategy_description(self) -> str:

"""

获取策略描述

Returns:

策略描述

"""

from config import AI_STRATEGIES

strategy_info = AI_STRATEGIES.get(self.strategy, {})

return strategy_info.get("description", "未知策略")

5. ai_strategies.py - AI策略模块

"""

AI策略模块

实现各种高级AI策略算法

"""

import numpy as np

from typing import List, Dict, Tuple, Optional

from collections import defaultdict, deque

from utils import StrategyUtils, GameUtils

import random

class AdvancedAIStrategies:

"""高级AI策略类"""

def __init__(self):

self.strategy_performance = defaultdict(list)

self.adaptation_threshold = 0.1

def markov_chain_strategy(self, history: List[str], order: int = 1) -> Optional[str]:

"""

马尔可夫链策略

基于状态转移概率预测对手下一步

Args:

history: 历史选择序列

order: 马尔可夫链阶数

Returns:

预测的下一项

"""

if len(history) < order + 1:

return None

# 构建状态转移矩阵

transitions = defaul

关注我,有更多实用程序等着你!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 18:45:11

基于spring的景点网站[VUE]-计算机毕业设计源码+LW文档

摘要&#xff1a;随着旅游业的蓬勃发展&#xff0c;游客对于景点信息获取的便捷性和全面性有了更高要求。本文设计并实现了一个基于Spring框架的景点网站&#xff0c;旨在为游客提供丰富、准确的景点信息&#xff0c;同时为景点管理者提供高效的管理平台。该网站采用Spring、Sp…

作者头像 李华
网站建设 2026/1/30 7:31:48

YOLOFuse餐厅后厨卫生监控方案

YOLOFuse餐厅后厨卫生监控方案 在一家连锁快餐店的深夜厨房里&#xff0c;灶火渐熄&#xff0c;油烟未散。监控画面中&#xff0c;普通摄像头已几乎无法分辨角落是否有员工未戴帽作业&#xff0c;而一只悄然爬行的老鼠也隐没于昏暗的地面阴影之中。这样的场景&#xff0c;在传…

作者头像 李华
网站建设 2026/1/29 23:08:35

leetcode 831. Masking Personal Information 隐藏个人信息-耗时100%

Problem: 831. Masking Personal Information 隐藏个人信息 解题过程 耗时100%&#xff0c;首先判断是邮箱还是手机号&#xff0c;邮箱拿到前面的小写字母&#xff0c;后面的小写后缀&#xff0c;拼起来就行。手机号按照长度拼起来就行&#xff0c;后面几个数字放上去 复杂度 C…

作者头像 李华
网站建设 2026/1/29 23:09:03

2026年区块链技术在农业果园领域的应用:技术革新与产业升级

文章目录引言一、技术原理&#xff1a;区块链赋能农业的核心机制1.1 分布式账本与数据不可篡改1.2 智能合约与自动化执行1.3 跨链互操作与生态协同二、应用场景&#xff1a;区块链重构果园产业链2.1 供应链透明化&#xff1a;从田间到餐桌的全流程追溯2.2 农业金融创新&#xf…

作者头像 李华
网站建设 2026/1/30 5:11:09

YOLOFuse机场跑道异物检测部署

YOLOFuse机场跑道异物检测部署 在现代民航运营中&#xff0c;一次看似微小的跑道异物&#xff08;FOD&#xff09;事件&#xff0c;可能引发连锁反应——轻则延误航班&#xff0c;重则酿成空难。2019年某国际枢纽机场因一块脱落的金属片导致多架飞机轮胎受损&#xff0c;直接经…

作者头像 李华