Commit Graph

12 Commits

Author SHA1 Message Date
d83494e669 feat: demo显示听牌状态+可胡张数
引擎: MahjongRoom.GetTingTiles(player) 返回所有可胡的unique tile
Demo: 每回合后显示'听牌: X: 🀄听N张(tile1 tile2...) | Y: 未听...'
包含已胡/副露中的tile计数,兼容wildcard和258规则

示例: 听牌: AI-东: 🀄听 1张(中) | AI-南: 未听 | AI-西: 未听 | AI-北: 未听
2026-07-05 00:20:53 +08:00
d734c0a384 fix: 圈风/门风/单钓将/四归一加_fanConfig守卫 + 精牌显示 + TileName修复
问题1: 圈风/门风/单钓将/四归一在南昌武汉等非Guobiao玩法中误生成
  修复: 4个新识别器加 _fanConfig.ContainsKey() 守卫,只有配了才生成
  Guobiao DSL 补充4个番型定义(圈风2/门风2/四归一2/单钓将1)

问题2: 翻牌定精信息未在demo显示
  修复: RenderDeal() 显示精牌(翻牌+正精+副精)

问题3: TileName?{tile}→ToStringCore(tile)
  修复: 带🀫前缀的数字牌显示 '🀫3万' 而非 '🀫?21'
2026-07-04 23:42:42 +08:00
359e02886f fix: --check输出区分能力注册 vs 规则覆盖, 不再误导
ValidateRuleCompliance 新增3项检查:
- 鸡胡缺失警告 (fan_types 应配鸡胡兜底)
- base_fan=0 番型警告 (标记番型需更高番型覆盖)
- 番型识别率统计 (DSL中有多少引擎能识别)

输出变更:
- 'DSL适配率' → '能力注册' (准确描述含义)
- 新增 '规则合规检查通过' (warnings=0时显示)
- --check末尾加警告: 能力注册≠完整规则覆盖
2026-07-04 22:13:53 +08:00
a338dac139 feat: --check 标志只验证DSL覆盖率不跑牌局
用法: dotnet run --project Demo -- --check --dsl new_variant
输出: 能力覆盖率 + 合规检查 + 仅验证模式退出

文档: README + dsl-specification 更新创建流程
2026-07-04 22:09:39 +08:00
237a6dc0ad feat: 规则级合规检查→适配率报告不再虚报100%
之前: CapabilityRegistry仅检查coarse-grained能力名(requires列表)
→ 所有DSL报100%即使有27条规则未实现

现在: 二层报告
- 能力适配率: 7/7(100%) ← 之前唯一指标
- 规则合规检查: ⚠ 9条规则引擎无法完全执行 ← 新增
  • 番型「将一色」(16)引擎无识别逻辑→0分
  • 番型「杠上开花/海底捞月/抢杠胡」事件番型无识别逻辑
  • fu_flag过水机制未实现

检查维度:
- 番型识别(21种已知pattern vs DSL fan_types)
- 番型条件字符串(hand_contains_wildcard等)
- wildcard behavior(substitute唯一支持)
- fu_flag过水机制
- pre_hooks(已知3种)
- scoring.mode(fan_table唯一支持)
2026-07-04 20:38:35 +08:00
ed30351ad0 feat: DSL适配率报告+零静默丢弃YAML字段
Root cause: .IgnoreUnmatchedProperties()→15+YAML字段被静默丢弃

修复:
1. 移除IgnoreUnmatchedProperties→未知字段立即报错
2. 补全所有缺失C#属性:GameInfo(engine_type/players),
   PhaseDslConfig(turn_order/fu_flag),DrawSubPhase(on_draw_flower/on_empty_deck),
   WinConditionConfig(pair_must_be_258 alias),PreHookConfig(condition),
   FlowerDslConfig→FlowerScoringConfig→FlowerMatchingConfig完整嵌套
3. FuFlagConfig/PlayersConfig新类
4. CapabilityRegistry.ComputeCoverage→DSL适配率百分比
5. Demo显示: DSL适配率:7/7(100%)

结果:4个DSL全部100%加载,无字段被静默丢弃
2026-07-04 20:16:47 +08:00
eb22f6ee28 feat: HUD显示所有玩家出牌记录 (DiscardHistory)
- GameState新增DiscardHistory字典 (per-player出牌记录)
- MahjongRoom.RecordDiscard统一记录出牌
- 人类模式HUD: 对手显示最近6张出牌
  例: AI-南: 10张手牌 | 已pung[..] | 出: 1万 3条 5筒
2026-07-04 17:39:29 +08:00
d416450e56 fix: CanAnKong硬编码false + 人类HUD显示听牌/杠/对手状态
修复:
- CanAnKong: 硬编码false → 检查手牌中4张相同(暗杠)
- HumanMahjongPlayer: 添加MeldsSolver依赖,实时检测听牌
- 人类HUD: 显示牌墙/副露/听牌🀄/杠类型(暗/明/加)
- 交互模式人类: 对手显示'X张手牌 | 已pung[..]'不暴露手牌
2026-07-04 17:24:05 +08:00
4302ec2fd5 feat: 集成测试 + 手动出牌模式 + discart pool幽灵牌修复
集成测试 (10个):
- 发牌: 庄14闲13, 牌墙55
- 回合流转: 庄家第一轮不摸牌, 非庄家摸牌后出牌
- 数据完整性: 10回合后手牌+副露+牌墙+弃牌=108
- 对局完整性: 4种DSL全部不出错完成
- 构造听牌: 完整手牌第一轮自摸

手动出牌 (--human):
- HumanMahjongPlayer: 显示手牌/可选操作/h=胡/p=碰/k=杠/1-N=出牌
- MahjongRoom: humanPlayer参数

修复: DiscardPool碰/胡后不移除→幽灵牌→总牌数溢出
2026-07-04 11:45:54 +08:00
c902482d4b fix: StepTurn回合流转重构 + 碰/杠牌数修正
Root cause:
1. 摸牌在碰/杠检测之前→摸的牌浪费→手牌净减
2. RemoveAll一次删光所有同牌→碰2张变删N张
3. 碰/杠后没让玩家出牌→手牌只减不补
4. 显示只展示手牌不展示暴露副露

修复:
- 重构StepTurn: 先处理LastDiscard反应(碰/杠/胡)
  没人反应才摸牌→决定→出牌
- RemoveAll→Remove 精准删除
- 碰/杠后强制出一张牌
- HandleDiscardReactions替代旧CheckReactions
- RenderFinal展示Exposed副露
2026-07-04 11:29:49 +08:00
b871395884 fix: 交互模式逐回合展示 + Deal()公开 + 发牌输出修正
问题:
1. 交互模式 Run() 直接跑完整局,只渲染最终状态
2. RenderGame 手牌.OrderBy()排序,洗牌后仍显顺序
3. 牌墙剩余显示0因为游戏已跑完

修复:
- 交互模式: room.Deal()→RenderDeal→逐回合StepTurn+ReadLine
- 发牌输出: 显示每人张数 + 牌墙剩余,不排序手牌
- 每回合: 显示事件(摸/打/碰/杠/胡) + 当前手牌
- Run()保留用于自动模式
2026-07-04 11:22:46 +08:00
3c6748bf06 [verified] feat: 麻将规则引擎 Demo 完整实现
RuleEngine 核心类:
- MahjongTile.cs — int编码 (1-29万条筒, 31-37字, 41-48花, 50-59宝牌)
- MeldsSolver.cs — 标准回溯 + wildcard缺口填充 + 七对/十三幺/全不靠
- PhaseMachine.cs — 回合机(摸打碰杠胡 + 优先级仲裁)
- ScoreEngine.cs — 番型计分 + 互斥图
- DslLoader.cs — YAML DSL加载 + 能力检查

4个DSL: 四川血战/广东鸡平胡/国标麻将/武汉麻将
控制台Demo: 交互模式 + 自动模式(--auto)
测试: 33个测试用例, 32个通过
2026-07-03 17:51:59 +08:00