跳转至

规则构建总览

本章面向规则创作者,介绍图形化规则语言的核心概念。后端 JSON 字段与代码细节请参阅「开发者参考」栏目,本章不涉及。

阅读本章后,请继续阅读三个示例,通过具体例子掌握构建步骤。

工作流概览

在规则构建器中创建一套规则需要完成三件事。

第一,定义玩家、牌、牌桌三个固有类,为它们设置属性,必要时定义方法。

第二,定义若干牌型。每个牌型由一段流程图描述识别方式,再由另一段流程图描述同牌型之间的比较方式。

第三,绘制主流程图与结算流程图。主流程图描述一局游戏如何开始、谁先出牌、何时结束;结算流程图描述胜负的判定方式。

完成后点击「完成并上传规则」,玩家就可以在房间界面选择该规则联机游玩。

三个核心概念

固有类

任何规则都必须包含三个类。

玩家类用于存储玩家身份与状态,常见属性包括手牌数、身份、分数。

牌类用于描述一张牌的属性,例如点数与花色。

牌桌类用于存储全局共享状态,例如当前出牌者(系统已默认提供)、上一手出牌、轮次序号。

属性类型只有整数与枚举两种。枚举本质是整数,只是允许为每个值另起一个用于显示的名字(例如点数 1 显示为 A,13 显示为 K)。牌桌的卡牌池与玩家的手牌由平台维护,创作者不需要自行设计数据结构。平台不支持任意大小的对象集合,只支持平台预定义的几个集合(玩家集、手牌、弃牌等);这一限制用于减少边界条件,避免规则陷入难以调试的状态。

牌堆由平台自动生成。生成方式是取牌类所有属性值的笛卡尔积。例如点数 13 种、花色 4 种,合计 52 张。因此创作者只需要定义牌的属性,无需手工列出每张牌。

牌型

牌型描述「一组牌的合法出牌组合」。斗地主中常见的牌型有单张、对子、三张、三带一、顺子、连对、飞机、炸弹等。

每个牌型由以下三部分组成。

属性用于描述该牌型的可比较特征。例如炸弹的属性是点数(4 个几),顺子的属性是起始点数与长度。

build_flow 是识别流程。流程接收一组牌,判定其是否构成该牌型;若构成,顺便计算该牌型的属性值。

compare_flow 是同型比较流程。流程接收 A 与 B 两组同牌型的牌,返回谁优先级更高。运行时 A 指代当前出牌,B 指代上一手成功出牌。

牌型之间的压制关系通过有向无环图表达。边 A → B 表示 A 可以压过 B。例如炸弹可以压过单张、对子等。创作者在每个牌型的「可压过」列表中勾选自己能压过的对手即可。

流程图

平台有五种流程图,起点节点不同,但内部可用的组件大同小异。

流程 起点 用途
主流程 对局开始 整盘游戏的执行流:发牌、轮转出牌、判定结束条件
结算流程 结算开始 决定胜负;平台会对每个玩家执行一次该流程
牌型 build_flow 牌型开始 接收牌组,判定并返回匹配结果与牌型属性
牌型 compare_flow 比较开始 接收同牌型的 A、B 两组牌,返回谁优先级更高
方法流程 方法开始 类方法的实现,可接受参数,可返回值

组件按用途分为四类。控制流组件决定流程走向,例如条件转移、结束对局、结算结束;它们有 next 字段,串成执行链。执行组件做一件事但不分支,例如赋值、方法调用、洗牌、发牌;同样有 next。用户操作组件会暂停流程并等待客户端响应,例如出牌、动作选择;同样有 next。逻辑/取值组件没有 next,只能作为前三类组件的输入插槽存在,例如整数常量、属性访问、比较、算数、双目逻辑。

简单的判断方式是:有 next 的节点连成执行链,没有 next 的节点是组合表达式用的子组件。唯一的例外是条件转移,它有 next_truenext_false 两个出口。

下一步

请按顺序阅读三个示例。

每个组件的具体用法见组件总览