mjAi/README.md

224 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 成都麻将Ai
## 项目目录结构
#### **1. 项目根目录**
- `README.md`:描述项目的目标、规则实现、训练流程和使用方法。
- `requirements.txt`:列出项目依赖的库,例如 `torch`、`gym`、`numpy` 等。
- `setup.py`:如果希望将项目打包为模块供他人使用,可以在此配置。
#### **2. 配置目录 (`configs/`)**
- `training_config.yaml`:包含训练超参数,如学习率、批量大小、强化学习算法的参数。
- `game_rules.yaml`:定义麻将规则,如番种加分规则、牌的花色、缺一门规则等。
#### **3. 数据目录 (`data/`)**
- `raw/`:存储原始麻将对局数据(如网络抓取或模拟对局)。
- `processed/`:存储格式化后的训练数据,例如 Numpy 数组或 Tensor 格式。
- `self_play/`:存储自我对弈产生的对局记录,用于强化学习。
#### **4. 模型目录 (`models/`)**
- `checkpoints/`:保存模型的中间状态,用于断点恢复训练或版本管理。
- `trained_model.py`:最终导出的模型文件,可直接加载和部署。
#### **5. 核心代码目录 (`src/`)**
##### **游戏引擎 (`engine/`)**
- `mahjong_engine.py`:实现成都麻将规则,包括摸牌、打牌、碰、杠、胡牌等逻辑。
- `game_state.py`:描述麻将局面状态的建模,包括手牌、牌河、明牌等。
- `utils.py`:通用工具函数,例如洗牌、牌序转换等。
##### **AI 模块 (`ai/`)**
- `model.py`:定义 AI 的深度学习模型(例如基于卷积或 Transformer 的网络)。
- `training.py`:训练脚本,包含监督学习或强化学习的逻辑。
- `evaluation.py`:评估模型表现的代码,支持对局胜率、番数统计等。
- `self_play.py`:实现自我对弈逻辑,用当前模型生成新训练数据。
##### **强化学习环境 (`environment/`)**
- `gym_env.py`:封装麻将引擎为 OpenAI Gym 环境,用于强化学习训练。
- `reward.py`:定义奖励函数,例如胡牌加分、放炮减分等。
##### **数据处理 (`data_processing/`)**
- `preprocess.py`:从原始数据中提取特征并转化为模型输入格式。
- `augmentation.py`:数据增强方法,例如随机调整牌序、模拟不同对局风格。
- `data_loader.py`:实现批量加载数据的逻辑。
##### **单元测试 (`tests/`)**
- 测试麻将引擎、AI 模型和强化学习环境的模块,确保代码可靠性。
#### **6. 脚本目录 (`scripts/`)**
- `train.py`:启动训练流程,包括加载数据、定义模型和运行训练。
- `evaluate.py`:加载模型并运行评估对局。
- `self_play.py`:启动 AI 自我对弈,生成强化学习数据。
- `preprocess_data.py`:将原始数据预处理为训练格式。
#### **7. 日志目录 (`logs/`)**
- 记录训练过程中的指标、对局日志和评估结果。
## 成都麻将规则:
- 成都麻将使用的是108张牌包括条、筒、万三种花色每种花色从1到9各四张没有东南西北风牌和中发白字牌。
### 基本规则
- **缺一门**:玩家必须选择缺少一种花色(条、筒、万中的任意一种),即只能用两种花色来胡牌。如果手中只有单一花色,则为清一色。
- **定缺**:游戏开始时,每位玩家需要扣下一张牌作为自己缺的那门,并且不能更改。如果本身就是两门牌,则可以报“天缺”而不扣牌。
- **起牌与打牌**:庄家通过掷骰子决定起牌位置,然后按顺序抓牌。庄家先出牌,之后每家依次摸牌打牌。
- **碰、杠**:允许碰牌和杠牌,但不允许吃牌。杠牌分为明杠和暗杠,明杠是其他玩家打出的牌被你碰后又摸到相同的牌;暗杠则是你自己摸到四张相同的牌。
- **胡牌**:胡牌的基本条件是拥有一个对子加上四个顺子或刻子(三个相同牌)。自摸为三家给分,点炮则由放炮者给分。
- **血战到底**:一家胡牌后,其他未胡牌的玩家继续游戏,直到只剩下最后一位玩家或者黄庄(所有牌都被摸完)为止。
### 特殊规则
- **下雨**:指杠牌,分为明杠和暗杠,明杠只收一家的钱,而暗杠可以收三家的钱。
- **查叫**:当出现黄庄时,需要检查每个玩家是否已经听牌(即差一张牌就能胡牌的状态),如果没有听牌,则可能需要赔偿其他玩家。
### 胡牌番数
- 根据不同的胡牌方式,有不同的计分方法。例如,清一色、带根(有额外的杠)、对子胡等都有相应的加分规则。
#### 详细番数计算
1. **平胡(基本胡)**四坎牌加一对将四坎牌可以是刻子或顺子计为1番。
2. **清一色**
- 不带杠的清一色称为“素清”计为2番。
- 带杠的清一色或清一色对子胡简称“清对”计为3番称为“极品”。
- 带两杠的清一色或清一色对子胡带杠计为4番称为“极中极”或“精品”。<!--存疑-->
3. **带幺九**
- **带幺九**指玩家手上的牌全部是由1和9组成的顺子、刻子或对子。例如123, 789, 111, 999, 11等。计为3番。
- **清带幺九**指玩家手上的牌不仅全部由1和9组成而且是同一花色条、筒、万即清一色的带幺九。计为1番。<!--存疑-->
4. **七对**手牌由7个对子组成计为2番。
5. **全求人**所有牌都是通过碰、杠、吃别人打出的牌来完成的计为6番。
6. **龙七对**七对中有一对是三张相同的牌计为12番。
7. **清七对**全部由一种花色组成的七对计为12番。
8. **杠上开花**在杠牌之后立即自摸胡牌计为1番。
9. **抢杠胡**当其他玩家明杠时你正好可以胡那张牌计为1番。
10. **天胡**庄家起牌后直接胡牌计为12番。
11. **地胡**闲家在第一轮打牌时就胡牌计为12番。
12. **大对子**手牌由四个对子加一个刻子组成计为2番。
13. **小七对**有六对加上一个对子计为2番。
14. **金钩吊**手上只剩下一张牌等别人打出然后胡牌计为1番。
15. **海底捞月**最后一张牌被玩家摸到并胡牌计为1番。
16. **海底炮**最后一张牌被打出导致玩家胡牌计为1番。
这些番数可以叠加例如如果一个玩家同时满足了清一色和七对那么他的总番数就是2番清一色+ 2番七对= 4番。
### 计分规则
- **基本分值**每番的具体分值可以根据不同的玩法和地区有所不同但一般情况下每番的分值可以设定为一个固定的数值比如5分、10分等。
- **翻倍规则**:某些地方可能会有额外的翻倍规则,例如,如果胡牌者是在“海底捞月”或“杠上开花”等特殊情况下胡牌,可能会有额外的加分。
**自摸 **:是指玩家通过自己摸牌完成胡牌。自摸时,其他玩家都需要给赢家支付相应的分数。
## 成都麻将规则建模
麻将游戏引擎建模代码于项目根src/engine/目录下。
## PPOProximal Policy Optimization算法
TensorBoard 通常会记录和可视化多种训练指标。你提到的这些图表代表了 PPO 训练过程中的不同方面。下面是对每个图表的解释:
### 1. `train/loss`
- **含义**:总损失函数值。
- **用途**:这是所有损失项的综合,包括策略梯度损失、价值函数损失等。通过观察这个指标,可以了解整个训练过程中的总体损失趋势。
### 2. `train/policy_gradient_loss`
- **含义**:策略梯度损失。
- **用途**这表示策略网络更新时的损失。PPO 通过剪裁来限制策略更新的幅度,以确保稳定的学习过程。观察这个指标可以帮助你了解策略更新的情况。
### 3. `train/value_loss`
- **含义**:价值函数损失。
- **用途**:这表示价值网络(用于估计状态值或状态-动作对的价值)的损失。价值函数的准确性对于评估策略的好坏非常重要。通过观察这个指标,可以了解价值网络的学习情况。
### 4. `train/learning_rate`
- **含义**:当前的学习率。
- **用途**:学习率是优化器的一个重要超参数,控制着每次更新时权重调整的幅度。观察学习率的变化可以帮助你了解学习率调度策略的效果。
### 5. `train/explained_variance`
- **含义**:解释方差。
- **用途**:这是一个衡量价值函数预测与实际回报之间差异的指标。解释方差越接近 1说明价值函数的预测越准确。通过观察这个指标可以评估价值函数的性能。
### 6. `train/entropy_loss`
- **含义**:熵损失。
- **用途**:熵损失鼓励策略具有一定的随机性,以防止过早收敛到局部最优解。通过观察这个指标,可以了解策略的探索程度。
### 7. `train/clip_range`
- **含义**:剪裁范围。
- **用途**PPO 使用剪裁来限制策略更新的幅度,以确保稳定性。剪裁范围是一个重要的超参数,决定了剪裁的严格程度。观察这个指标可以帮助你了解剪裁策略的效果。
### 8. `train/clip_fraction`
- **含义**:被剪裁的比例。
- **用途**:这个指标表示有多少比例的更新被剪裁。如果剪裁比例很高,可能意味着你的策略更新过于激进,需要调整剪裁范围或其他超参数。
### 9. `train/approx_kl`
- **含义**:近似 KL 散度。
- **用途**KL 散度衡量新旧策略之间的差异。PPO 通过控制 KL 散度来确保策略更新的稳定性。通过观察这个指标,可以了解策略更新的幅度和稳定性。
### 总结
这些图表提供了关于 PPO 训练过程的全面视图,帮助你监控和调试模型。以下是每个图表的主要用途:
- **`train/loss`**:总体损失,反映训练的整体进展。
- **`train/policy_gradient_loss`**:策略梯度损失,反映策略网络的更新情况。
- **`train/value_loss`**:价值函数损失,反映价值网络的学习情况。
- **`train/learning_rate`**:学习率,反映优化器的设置。
- **`train/explained_variance`**:解释方差,反映价值函数的准确性。
- **`train/entropy_loss`**:熵损失,反映策略的探索程度。
- **`train/clip_range`**:剪裁范围,反映策略更新的限制。
- **`train/clip_fraction`**:被剪裁的比例,反映策略更新的稳定性。
- **`train/approx_kl`**:近似 KL 散度,反映策略更新的幅度和稳定性。
## 参考
https://github.com/mangenotwork/CLI-Sichuan-Mahjong //golang命令行麻将
https://github.com/lauyikfung/SichuaMahjongAI //SichuaMahjongAI
https://github.com/risseraka/node-sichuan-mahjong //nodejs
https://github.imc.re/latorc/MahjongCopilot //麻将 AI 助手,基于 mjai (Mortal模型) 实现的机器人。
https://github.com/kennyzhang0819/Sichuan-Mahjong-AI-Testbed // Java 完整实现的四川麻将游戏的源代码