Skip to content

牌谱数据格式说明

本文档详细说明了牌谱文件(如 data/record/*.json)的数据结构。该说明基于 src/analyzer/simulator.cppsrc/analyzer/action.cppinclude/base/tziakcha.h 中的处理逻辑。

概述

牌谱文件是一个 JSON 对象,包含比赛元数据、玩家信息以及详细的游戏动作脚本。

根对象结构

字段 类型 说明
id String 牌谱唯一标识符。
belongs String 牌谱所属对局(session)。
script String 编码的游戏脚本字符串。若脚本已解码并存储在 step 字段中,此字段为 "<Decoded>"
step Object 解码后的游戏数据。包含核心的游戏动作和状态信息。详见 Step 数据

Step 数据

step 对象包含了一场游戏的完整数据。

字段 类型 说明
g Object 游戏配置信息(例如 t 字段表示标题)。
p Array 玩家信息列表(包含名字、ID等)。
w String 牌墙数据(十六进制字符串)。每两个字符表示一张牌的 ID。
d Integer 骰子点数。编码为4个4位数值(Nibbles)。
i Integer 圈风/局数信息。计算公式 (i / 4) % 4 可得当前的圈风索引(0:东, 1:南, 2:西, 3:北)。
a Array 游戏动作序列。详见 动作数据格式
b Integer 结算标志位。
位 0-3:赢家位掩码(Winner Mask)。
位 4-7:放铳者位掩码(Discarder Mask)。
y Array 每个玩家的结算详情(如番数、和牌信息等)。

动作数据格式 (Action Format)

a 字段是一个数组,其中每个动作由一个包含 3 个整数的数组表示:[combined, data, time]

索引 名称 说明
0 combined 复合字段,编码了玩家索引动作类型
1 data 数据负载。根据动作类型的不同,结构也不同。包含牌ID、吃碰杠详情等。
2 time 动作发生的时间戳(毫秒,相对于游戏开始)。

combined 字段解码

第一个整数通过位运算组合了玩家索引和动作类型。

数据项 位范围 解析逻辑 (C++)
玩家索引 Bits 4-5 (combined >> 4) & 3
动作类型 Bits 0-3 combined & 15

动作类型与 Data 结构详情

以下是所有动作类型及其 data 字段的详细位结构说明。

0: 开局/初始手牌 (Start Play)

  • 说明: 游戏开始,此时模拟器会从初始状态(配牌)中捕获各家手牌。
  • Data: 0 (无数据)

1: 补花 (Flower Replacement)

  • 说明: 玩家进行补花操作。
  • Data 结构:
部分 位范围 掩码/计算 说明
补入牌ID Low Byte (0-7) data & 0xFF 补进手中的牌的 ID。
花牌偏移 High Byte (8-11) (data >> 8) & 15 拔出的花牌基准值。实际花牌 ID = 值 + 136
自动补花 Bit 12 data & 0x1000 标志位。若置位,表示为系统自动补花。

2: 出牌 (Discard)

  • 说明: 玩家打出一张牌。
  • Data 结构:
部分 位范围 掩码/计算 说明
牌 ID Low Byte (0-7) data & 0xFF 打出的牌的 ID。
手切标识 Bit 8 (data >> 8) & 1 1 = 手切(打出手里的牌);0 = 模切(直接打出刚摸的牌)。

3: 吃 (Chi / Chow)

  • 说明: 玩家吃上家打出的牌,组成顺子。
  • Data 结构:
部分 位范围 掩码/计算 说明
基准牌值 Bits 0-5 (data & 0x3F) << 2 吃牌组合的基准牌值。
供牌方向 Bits 6-9 (data >> 6) & 3 供牌来源方向(相对)。
第1张偏移 Bits 10-11 (data >> 10) & 3 顺子第1张牌相对于基准值的偏移。
第2张偏移 Bits 12-13 (data >> 12) & 3 顺子第2张牌相对于基准值的偏移。
第3张偏移 Bits 14-15 (data >> 14) & 3 顺子第3张牌相对于基准值的偏移。

4: 碰 (Peng / Pung)

  • 说明: 玩家碰任意一家打出的牌,组成刻子。
  • Data 结构:
部分 位范围 掩码/计算 说明
基准牌值 Bits 0-5 (data & 0x3F) << 2 碰牌组合的基准牌值。
供牌方向 Bits 6-9 (data >> 6) & 3 供牌来源方向(相对)。
牌偏移 Bits 10-11 (data >> 10) & 3 实际牌相对于基准值的偏移(用于确定具体是哪几张)。

5: 杠 (Gang / Kong)

  • 说明: 包含明杠、暗杠和加杠(补杠)。
  • Data 结构:
部分 位范围 掩码/计算 说明
基准牌值 Bits 0-5 (data & 0x3F) << 2 杠牌的基准牌值。
供牌方向 Bits 6-9 (data >> 6) & 3 0 表示暗杠(自己摸4张);非0 表示明杠/加杠供牌方。
牌偏移 Bits 10-11 (data >> 10) & 3 牌的偏移值。
加杠标识 Bits 8-11 (Mask) data & 0x0300 若等于 0x0300,表示为加杠(碰牌后补杠)。

6: 和牌 (Win / Hu)

  • 说明: 玩家和牌(自摸或荣和)。
  • Data 结构:
部分 位范围 掩码/计算 说明
自动和牌 Bit 0 data & 1 是否为自动和牌。
番数 Bits 1+ data >> 1 本次和牌的番数。

7: 摸牌 (Draw)

  • 说明: 玩家从牌墙摸一张牌。
  • Data 结构:
部分 位范围 掩码/计算 说明
牌 ID Low Byte (0-7) data & 0xFF 摸到的牌的 ID。
逆向/补花 High Byte (8-15) data & 0x0100 若置位(非0),表示从牌墙尾部摸牌(如杠上开花、补花时)。

8: 过 (Pass)

  • 说明: 玩家选择跳过当前可执行的动作(如吃碰杠和)。
  • Data 结构:
部分 位范围 掩码/计算 说明
模式 Bits 0-1 data & 3 0: 手动过 (Manual)
1: 自动过 (Auto)
2: 强制过 (Forced)

9: 弃和 (Abandon)

  • 说明: 弃权或无效的和牌操作声明(罕见)。
  • Data: 0

示例解析 (基于 0ae10q6N)

动作: [40, 2, 6812]

  1. Combined: 40 (0x28)
    • 动作类型: 40 & 15 = 8 (Pass / 过)
    • 玩家索引: (40 >> 4) & 3 = 2 (Player 2)
  2. Data: 2
    • 模式: 2 (自动过)
  3. 累计时间: 6812 ms

动作: [2, 364, 7827]

  1. Combined: 2 (0x02)
    • 动作类型: 2 & 15 = 2 (Discard / 出牌)
    • 玩家索引: (2 >> 4) & 3 = 0 (Player 0)
  2. Data: 364 (0x16C)
    • Low Byte: 364 & 0xFF = 108 (牌 ID 108 -> 红中)
    • High Byte: 364 >> 8 = 1 (手切 = True)
  3. 累计时间: 7827 ms