Files
game-cards/README.md

142 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 掼蛋卡牌游戏 (Guandan Card Game)
基于 Godot 4.6.3 开发的掼蛋卡牌游戏。**训练模式**已基本可用,联机与回放为后续阶段。
## 环境要求
- **Godot 4.6.3+** ([godotengine.org](https://godotengine.org/download))
- 安装命令: `winget install GodotEngine.GodotEngine`
## 快速开始
```bash
git clone <repo>
cd game-cards
# Godot 编辑器 → "导入" → 选择 project.godot → F5 运行
```
主场景: `res://src/ui/scenes/main_menu.tscn`
## 训练模式
进入"训练室"后由玩家(座位 0对 3 个 L2 规则 AI**玩家始终是出牌方**AI 跟牌或过牌)。每局共 27 张/人,从 2 开始打。
### 玩法
1. 鼠标点击手牌:选中(牌上抬 25px + 黄边高亮)
2. 双击手牌:直接出该单张
3. `出牌` 按钮:按当前选中提交牌型
4. `过牌` 按钮:本轮放权(领出者不能过)
5. `建议` 按钮:调 L2 AI 给出当前最优出法
### 牌型支持
单张 / 对子 / 三张 / 三带二 / 顺子5+/ 连对6+ 双数)/ 钢板6+ 3 整除)/ 同花顺 / 炸弹 / 火箭
## UI 特性
- **手牌自动换行**: `HandArea extends FlowContainer`27+ 张牌自动多行
- **按花色+点数排序**: 渲染前 `_sort_by_rank_and_suit` 统一顺序
- **出牌动画**: ghost 节点从原位飞行 + 缩放至桌面中央0.3s
- **点评文字**: 出牌方 + 牌型 + 张数 + 主阶0.2s 淡入 → 0.6s 停留 → 0.3s 淡出
- **选中上抬**: 选中时 `position.y` -25px tween0.12s QUAD+EASE_OUT
- **Hint 高亮**: L2 AI 推荐的牌自动高亮(与选中共用 `set_selected`
## 项目结构
```
game-cards/
├── src/
│ ├── core/ # 纯逻辑层(零 Godot 依赖)
│ │ ├── card.gd # Card 类4 字节打包)
│ │ ├── deck.gd # Deck 与发牌
│ │ ├── game_state.gd # 牌局状态、Phase、Action 日志
│ │ ├── round.gd # 单轮出牌序列
│ │ ├── hand_evaluator.gd # 牌型判定(含主阶、是否纯炸弹)
│ │ ├── rule_engine.gd # 牌型比较与合法性
│ │ ├── move_generator.gd # 给定手牌生成所有合法出法
│ │ ├── actions.gd # Action 数据类
│ │ ├── rule_config.gd # 规则配置(主阶、级牌等)
│ │ └── constants.gd # 牌型枚举与常量
│ ├── ai/
│ │ ├── base_ai.gd # AI 抽象接口
│ │ ├── l1_basic_ai.gd # L1: 贪心最小牌
│ │ └── l2_rule_ai.gd # L2: 全枚举选最小压制
│ ├── game/
│ │ ├── game_controller.gd # 通用回合推进
│ │ ├── training_controller.gd # 训练模式:单玩家 vs 3 AI
│ │ └── replay_recorder.gd # Action 日志 → 重放
│ ├── autoload/
│ │ ├── config.gd # 规则与全局配置
│ │ ├── event_bus.gd # 全局信号总线
│ │ └── audio_manager.gd # 音效播放(未启用)
│ └── ui/
│ ├── scenes/
│ │ ├── main_menu.tscn # 主菜单
│ │ └── training_room.tscn # 训练室1280×720
│ └── components/
│ ├── hand_area.tscn # FlowContainer 手牌区
│ └── card_node.tscn # 单张卡牌55×80
├── tests/ # GUT 单元测试(占位)
├── docs/superpowers/ # 设计规格与实施计划
└── assets/ # 卡牌图片、UI 素材
```
## 关键架构决策
1. **`core/` 零 Godot 依赖** — 便于未来用 Rust 移植核心逻辑
2. **Card 用 4 字节打包**suit+rank 占 1 字节card_id 占 2 字节)— 减少内存与序列化成本
3. **GDScript 强类型 Array[Card]** — 编译期类型检查;规避 Godot 4.6.3 `Array.duplicate()` 丢类型 bug统一用 `for c in src: dst.append(c)` 模式
4. **AI 三级** — L1 贪心 / L2 枚举 / L3 策略(待实现)
5. **出牌动画用 ghost 节点** — 临时挂到 `get_tree().root` 避免 FlowContainer 重排干扰
## 配置 Autoload
项目设置 → 自动加载 (Autoload)
| 名称 | 路径 |
|------|------|
| Config | `res://src/autoload/config.gd` |
| EventBus | `res://src/autoload/event_bus.gd` |
| AudioManager | `res://src/autoload/audio_manager.gd` |
## 运行测试
```bash
# GUT推荐
godot --headless -s addons/gut/gut_cmdln.gd -gdir=res://tests
```
> 当前 `tests/` 仅有占位文件,无实际用例。
## 已知问题与限制
- 27+ 张牌的极端出牌(如 27 张单牌连出)`start_x` 可能为负,飞出左边界(实际不可能)
- CommentaryLabel y=360-380 与 TableLabel 底部 10px 视觉重叠
- L3 策略 AI 尚未实现
- 联机 / 观战 / 回放 均为占位
## 开发计划
| 阶段 | 内容 | 状态 |
|------|------|------|
| 训练模式 | 核心 + L1/L2 AI + UI | **进行中** |
| L3 策略 AI | 配合/防守/控牌策略 | 待开发 |
| 完整对局 | 4 人完整出完一轮 | 待开发 |
| 联机 | Action 同步 + 房间 | 待开发 |
| 观战 / 回放 | Action 流式回放 | 待开发 |
## 设计文档
- [主设计规格](./docs/superpowers/specs/2026-05-28-guandan-card-game-design.md)
- [训练模式实施计划](./docs/superpowers/plans/2026-05-28-guandan-training-mode.md)
- [手牌换行 + 出牌动画 + 点评设计](./docs/superpowers/specs/2026-06-02-hand-wrap-and-play-animation-design.md)
- [手牌换行 + 出牌动画实施计划](./docs/superpowers/plans/2026-06-02-hand-wrap-and-play-animation.md)
## 提交约定
- 单步可工作的 commit
- 类型前缀: `feat: / fix: / refactor: / docs: / chore:`
- 范围标注: `feat(ui): / fix(core):`
- 中英文皆可,遵循仓库历史风格(见 `git log --oneline`