本文完全由ai编写,仅供参考

Mahjonglab YAML 配置使用指南

本指南供玩家在创建房间时编写 YAML 配置使用。最推荐的方式是选择一个现有规则作为 base,只写需要修改的项目;没有写出的项目会保留该规则原值。

一、所有配置项速查

顶层

配置项 类型 简单用途
base 字符串 选择基础规则。使用它后,只需填写想修改的项目
room_config 字典 房间名、局数、分数、座位和计时规则
game_config 字典 牌山、人数、吃碰杠、公开方式等单局规则
calculator_config 字典 和牌牌型、番种、计分、结算和单局结束规则

可用的 base

配置模板
康庄众娱
兼用卡
青雀
国标
组合麻将

room_config

配置项 类型 简单用途
room_name 字符串 房间名称,最多 32 个字符
password 字符串 入座密码,最多 64 个字符;不影响观战
starting_score 二维整数列表 每位玩家和公共分数池的初始分数
starting_round 整数列表 初始局数,目前主要使用第一个整数
end_type 字符串 整个房间按局数或玩家分数结束
end_target 整数 结束所需的局数或目标分数
random_seat 布尔值 第一局开始前是否随机分配房间座位
seat_orders 二维整数列表 自定义每一局的方位与座位对应关系
main_time 非负整数 每次行动的主要时间,单位为秒
reserve_time 非负整数 每局共用的储备时间,单位为秒

game_config

配置项 类型 简单用途
wall 字符串 声明本规则使用的全部牌
shuffle 布尔值 是否随机洗牌
wallrand 整数列表 不随机洗牌时指定牌序
flower 01 字符串 标记 wall 中哪些牌是花牌
transparent 01 字符串 标记离开牌山后所有人都能看见的牌
opening_flower 布尔值 发牌后是否先进行起手补花
max_player 整数 玩家数,只能是 2、3、4
allow_chi 字符串列表 允许吃的花色
kan_after_chipon 布尔值 吃碰后是否允许补花、暗杠或加杠
chiponkan_with_empty_wall 布尔值 牌山到达保留张数后是否仍允许鸣杠或补花
riichi 整数 立直设置;当前功能未完成,应填写 0
show_after_win 布尔值 玩家和牌后是否公开其手牌
show_after_end 布尔值 一局结束后是否公开所有人的手牌
show_closed_kan 布尔值 暗杠时是否向其他玩家显示中间两张牌
multi_win 布尔值 是否允许一炮多响
tactical_call 整数 战术鸣牌模式,范围 -13

calculator_config

配置项 类型 简单用途
patterns 字符串列表 允许使用哪些和牌拆解方式
combinations 番种列表 定义可成立的番种、显示名称和分数
scorer 字典 决定成立番种怎样组合成最终分数
settlement 字典 决定和牌后每位玩家如何增减分数
end 字典 决定一局在何时结束或流局

patterns 可选值

用途
regular_win 一般型:面子加雀头
seven_pairs 七对
thirteen_orphans 十三幺
all_unconnected 全不靠
combination_dragon 组合龙

scorer.name 可选值

用途
pure_add 所有成立番种直接相加
group_max 每个番种组只取最高的一项
category_max 组合麻将专用的分类取高计分

settlement.name 可选值

用途
standard 用番数乘以各角色倍率
free_count 用逆波兰表达式自由计算分数变化
hand_award 组合麻将专用奖励结算

end.name 可选值

用途
standard 按和牌人数、后续摸牌次数和牌山余量结束一局

二、最简单的使用方法

1. 基于规则修改

只想修改房间名、时间或结束条件时,写法如下:

base: 康庄众娱
room_config:
  room_name: 周末麻将
  password: "1234"
  end_target: 300
  main_time: 20
  reserve_time: 60

没有写出的内容全部沿用“康庄众娱”。这是日常创建自定义房间最安全的写法。

2. 修改多个部分

base: 配置模板
room_config:
  room_name: 三人测试
  end_type: round
  end_target: 4
  starting_score:
    - [0]
    - [0]
    - [0]
    - [0]

game_config:
  max_player: 3
  allow_chi: []
  multi_win: false

3. YAML 基本写法

text: 普通文字
quoted_text: "包含特殊字符的文字"
integer: 10
enabled: true
disabled: false
list: [m, p, s]
empty_list: []
empty_dict: {}

注意:

三、room_config 详细说明

room_name

room_name: 我的房间

房间列表中显示的名称,最多 32 个字符。填写空字符串时,服务器会生成“用户名的房间”。

password

password: "1234"

最多 64 个字符。密码只在玩家入座时检查,匿名观战不需要密码。房间列表只显示该房间是否有密码,不会显示密码内容。

不设置密码:

password: ""

starting_score

每一行是一份分数。行数必须是玩家数加一,最后一行固定作为公共分数池。

四人单维分数:

starting_score:
  - [0]
  - [0]
  - [0]
  - [0]
  - [0] # 公共分数池

三人双维分数:

starting_score:
  - [25000, 0]
  - [25000, 0]
  - [25000, 0]
  - [0, 0] # 公共分数池

所有行必须具有相同维数。普通 standard 结算只使用第一维;多维分数应配合 free_count

starting_round

starting_round: [0]

表示第一局的局数索引。当前局数推进只会增加第一项,因此一般只写一个整数。[0] 表示从第 1 局开始显示和计算。

end_typeend_target

固定局数结束:

end_type: round
end_target: 8

表示完成 8 局后整个房间进入结束状态。

固定分数结束:

end_type: player_score
end_target: 200

任一玩家第一维分数达到 200 后结束。公共分数池不参与目标判断。

建议 end_target 使用正整数。

random_seat

random_seat: true

true 表示第一次开始游戏时随机打乱玩家所在的房间座位,只执行一次;false 保持玩家入座位置。

seat_orders

用于指定每局“游戏中的东南西北”如何映射到房间座位。每一项都必须是从 0max_player - 1 的完整排列,不能重复或遗漏。

四人示例:

seat_orders:
  - [0, 1, 2, 3]
  - [1, 2, 3, 0]

三人示例:

seat_orders:
  - [0, 1, 2]
  - [1, 2, 0]

列表为空或局数超过已填写的顺序时,系统按局数自动轮换:

seat_orders: []

main_timereserve_time

main_time: 10
reserve_time: 20

玩家需要选择行动时先消耗主要时间,主要时间用完后再消耗储备时间。

四、game_config 详细说明

wall

wall 按顺序写出规则中的每一张牌,每张牌都必须由“数字 + 花色”表示:

wall: 1m1m1m1m2m2m2m2m3m3m3m3m

不能把 1m2m3m 缩写成 123m,后者会被解析为一张点数为 123 的牌。

当前通用花色:

后缀 牌种
m 万子
p 筒子
s 索子
z 字牌,通常为 1~7
f 花牌牌面;还需要在 flower 中标记

自定义牌山必须保证牌数足以完成发牌和游戏。标准和牌拆解只识别 mpsz

shufflewallrand

随机洗牌:

shuffle: true
wallrand: []

固定牌序:

shuffle: false
wallrand: [0, 1, 2, 3]

wallrandwall 中按声明顺序排列的每张牌指定一个排序号,排序号最小的牌最先被摸。推荐填写与牌张数相同的 0..N-1 完整排列。

例如三张声明牌想按“第 3 张、第 1 张、第 2 张”的顺序摸取:

wall: 1m2m3m
shuffle: false
wallrand: [1, 2, 0]

当前配置检查不会阻止短列表、重复数字或越界数字,但它们可能造成不符合预期的牌序,因此不应使用。

flower

wall 中的声明位置,用 01 字符串标记花牌:

wall: 1m2m1f2f
flower: "0011"

第 3、4 张牌会具有花牌特性。没有花牌时写:

flower: ""

位图短于牌山时,未覆盖的牌视为普通牌;超出的字符被忽略。推荐始终与牌张数保持一致。

transparent

写法与 flower 相同:

transparent: "0100"

透明牌离开牌山后,即使在其他玩家手牌中,也会向所有人公开牌面。为避免透露其在手牌中的准确位置,非正常可见者看到的手牌 index 会被隐藏。

没有透明牌时写:

transparent: ""

opening_flower

opening_flower: true

发牌完成后先进入起手补花阶段。系统会依次让玩家选择补花或过;引擎不会替玩家自动补花。全部处理完成后由玩家 0 进入正常摸牌选择。

不需要起手补花时写 false

max_player

max_player: 4

只接受 234。修改人数时必须同步修改:

allow_chi

允许吃万、筒、索:

allow_chi: [m, p, s]

完全禁止吃牌:

allow_chi: []

只有被列出的牌花色可以组成吃牌行动。字牌通常不应加入。

kan_after_chipon

kan_after_chipon: true

true 表示玩家吃或碰后,也可以选择补花、暗杠或加杠;false 表示这些行动只在正常摸牌后提供。

chiponkan_with_empty_wall

chiponkan_with_empty_wall: false

false 表示剩余牌山达到 calculator_config.end.params.left_wall 时,不再允许会进行补摸的补花或杠;true 表示仍可选择。

riichi

riichi: 0

当前立直行动生成尚未实现,因此应保持 0。其他整数可能通过格式检查,但不会形成完整可用的立直规则。

手牌公开设置

show_after_win: true
show_after_end: false
show_closed_kan: true

multi_win

multi_win: true

true 允许同一张牌被多位玩家和牌;false 只执行优先确定的一次和牌。

tactical_call

tactical_call: -1
模式
-1 无战术鸣牌,行动确定后再播放鸣牌语音
0 单次立即战鸣,点击吃碰杠和时立即发声,之后不能更改已发声行动
1 单次延迟战鸣,等待更高优先级玩家表态后发声,之后不能更改
2 连续立即战鸣,被更高优先级行动截断后可再次选择
3 连续延迟战鸣,延迟发声且被截断后可再次选择

五、calculator_config 详细说明

一般玩家只需继承现有规则,不应重写计算器。只有要制作新规则时才需要修改本节内容。

patterns

patterns:
  - regular_win
  - seven_pairs
  - thirteen_orphans

系统会使用列出的每种拆解方式寻找和牌组合。可选值见文档开头的速查表。未知名称不会产生有效拆解。

combinations

每个番种包含三项:

combinations:
  - definition: 康众清一色
    display: 清一色
    score: 12
项目 类型 用途
definition 字符串 用已有番种定义组成的成立条件
display 字符串 结算时展示给玩家的名称
score 整数 番数或该规则使用的整数分值

definition 使用以空格分隔的逆波兰式,支持 andornot

# 同时满足 A 和 B
definition: A B and

# 满足 A 或 B
definition: A B or

# 满足 A 且不满足 B
definition: A B not and

不能使用括号。最终表达式必须恰好得到一个真假结果。

现有番种定义按规则添加前缀:

模板...
康众...
兼用卡...
青雀...
国标...
组合麻将...

注意:预设“康庄众娱”的番种定义前缀是“康众”。只能引用程序中已经实现的番种;随意写一个新名称会被当作不成立。

展示名称换行:

- definition: A B and
  display: "A\nB"
  score: 4

scorer: pure_add

scorer:
  name: pure_add
  params:
    base: 0
    least: 8

即使不需要底分或起和限制,也必须写出:

params:
  base: 0
  least: 0

scorer: group_max

每组番种只取分数最高的一项:

scorer:
  name: group_max
  params:
    groups:
      - [规则番A, 规则番B]
      - [规则番C, 规则番D]

每个 combinations.definition 必须恰好出现在一个组中,不能重复或遗漏。输出维数等于组数。

需要起和判断,并把奖励番与基础番分开时:

scorer:
  name: group_max
  params:
    groups:
      - [规则基础番A, 规则基础番B]
      - [规则奖励番A, 规则奖励番B]
    least: 8
    bonus: [规则奖励番A, 规则奖励番B]

此时输出固定为两维:

[非奖励番总分, 奖励番总分]

只有第一维参加 least 起和判断。

scorer: category_max

这是组合麻将的专用计分器:

scorer:
  name: category_max
  params:
    least: 4
    direct: [规则直属番]
    whole_groups:
      - [规则全体番A, 规则全体番B]
    combination_groups:
      - [规则组合番A, 规则组合番B]
    status: [规则状态番]
    accidental: [规则偶然番]
    no_fan: 规则无番和

settlement: standard

settlement:
  name: standard
  params:
    discard_winner: 2
    discard_loser: -2
    discard_bystander: 0
    draw_winner: 3
    draw_loser: -1

结算变化等于 score[0] × 对应倍率

参数 作用对象
discard_winner 点和者
discard_loser 放铳者
discard_bystander 点和时未参与的其他玩家
draw_winner 自摸者
draw_loser 自摸时的其他玩家

五项必须全部提供。公共分数池不会被修改。

settlement: free_count

settlement:
  name: free_count
  params:
    discard_winner: "a b + 24 +"
    discard_loser: "a b + 8 + neg"
    discard_bystander: "-8"
    draw_winner: "a b + 8 + 3 *"
    draw_loser: "a b + 8 + neg"

五种角色与 standard 相同,但值改为逆波兰式。

字母代表 scorer 输出的各维分数:

a = 第 1 维
b = 第 2 维
c = 第 3 维
……

可用操作:

类型 操作
二元运算 +-*///%**minmax
一元运算 floorceilroundabsnegsqrttanh
栈操作 dupswapdrop

示例:

a b +       将 a、b 相加,输出一维
a b         不运算,输出两维 [a, b]
a 3 * neg   输出 -(a×3)

表达式结束后,从栈底到栈顶依次作为各维分数变化。最终结果必须是有限整数,维数必须与 starting_score 每行维数相同。

settlement: hand_award

settlement:
  name: hand_award
  params: {}

组合麻将专用,必须配合 category_max 和一维分数:

end: standard

end:
  name: standard
  params:
    max_win: 1
    left_draw: 0
    left_wall: 0
参数 类型 用途
max_win 至少为 1 的整数 达到多少位和牌者后允许结束一局
left_draw 非负整数 达到 max_win 后还保留多少次普通摸牌
left_wall 非负整数 牌山剩余多少张时流局

如果所有玩家都已经和牌,一局会直接结束。

注意区分:

六、常用配置示例

康庄众娱,300 分结束

base: 康庄众娱
room_config:
  room_name: 300分房
  end_type: player_score
  end_target: 300

8 局、无计时

base: 配置模板
room_config:
  end_type: round
  end_target: 8
  main_time: 0
  reserve_time: 0

三人、禁止吃、一炮单响

base: 配置模板
room_config:
  starting_score:
    - [0]
    - [0]
    - [0]
    - [0]
  seat_orders: []

game_config:
  max_player: 3
  allow_chi: []
  multi_win: false

一局结束后公开全部手牌

base: 青雀
game_config:
  show_after_end: true

起手补花

base: 国标
game_config:
  opening_flower: true

这只开启起手补花流程;牌山本身仍需要正确的花牌牌面和 flower 位图。直接继承“国标”时这些内容已经存在。

七、容易写错的地方

  1. 修改 max_player 后,忘记把 starting_score 改成“玩家数加一”行。
  2. 密码写成 password: 1234,被 YAML 当成整数;应写 password: "1234"
  3. wall 中的 1m2m3m 缩写成 123m
  4. shuffle: false 时没有提供完整且不重复的 wallrand
  5. flowertransparent 中出现 0/1 以外的字符。
  6. combinations 中填写了程序尚未实现的番种名。
  7. 使用 free_count 后,表达式输出维数与 starting_score 不一致。
  8. pure_add.params 漏写 baseleast
  9. params 整项省略。即使某个功能没有参数,也要写 params: {}
  10. 误以为 base 补丁会合并番种列表;填写 combinations 会替换完整列表。

八、完整配置与基础规则

绝大多数玩家应使用:

base: 康庄众娱
room_config:
  room_name: 自定义房间

这种方式仍然可以修改本文列出的任何二级配置项,并且不需要复制数百行番种表。只有制作完全独立、不能继承任何现有规则的新玩法时,才需要不写 base 并提交完整的:

room_config: {}
game_config: {}
calculator_config: {}

上面的空字典只是结构示意,不能直接创建房间;不使用 base 时必须按照本指南补齐全部字段、番种和计算方法。