DoudizhuState
斗地主状态访问器:集中定义所有斗地主相关的 state.variables 键、zone id,以及从 GameState 读取这些字段的访问器函数。
概述
所有斗地主插件状态都存储在核心 GameState 的 state.variables 下,以保持核心 GameState 形状通用。本模块提供:
- 11 个
DDZ_VAR_*变量键常量; - 3 个
DDZ_*_ZONE_IDzone id 常量; - 11 个 getter 函数(如
getDoudizhuPhase/getLandlordId等); - 1 个聚合快照函数
getDoudizhuState; - 2 个语义判定函数
teamOf/isNewRound; - 1 个手牌读取函数
getHandCards。
变量键常量(DDZ_VAR_*)
所有键均以 'ddz.' 前缀存储在 state.variables 中。
| 常量 | 字面值 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
DDZ_VAR_PHASE | 'ddz.phase' | DoudizhuPhase | DEALING | 当前斗地主子阶段 |
DDZ_VAR_LANDLORD_ID | 'ddz.landlordId' | string | undefined | undefined | 最终地主玩家 id(PLAYING 阶段起设置) |
DDZ_VAR_FARMER_IDS | 'ddz.farmerIds' | string[] | [] | 农民玩家 id 列表(2 位) |
DDZ_VAR_BOTTOM_CARD_IDS | 'ddz.bottomCardIds' | string[] | [] | 3 张底牌 id 列表(供 REVEAL_BOTTOM_CARDS 使用) |
DDZ_VAR_LAST_PLAYER_ID | 'ddz.lastPlayerId' | string | undefined | undefined | 上一手实际出牌玩家 id |
DDZ_VAR_LAST_COMBINATION | 'ddz.lastCombination' | DoudizhuCombination | undefined | undefined | 上一手出牌的牌型对象 |
DDZ_VAR_PASS_COUNT | 'ddz.passCount' | number | 0 | 本轮累计过牌次数 |
DDZ_VAR_MULTIPLIER | 'ddz.multiplier' | number | 1 | 当前倍率 |
DDZ_VAR_BIDDER_INDEX | 'ddz.bidderIndex' | number | 0 | 当前叫分人在座位顺序中的索引 |
DDZ_VAR_BIDDER_PASSED | 'ddz.bidderPassed' | string[] | [] | 已选择"不叫"的玩家 id 列表 |
DDZ_VAR_LANDLORD_CANDIDATE_ID | 'ddz.landlordCandidateId' | string | undefined | undefined | 地主候选人 id(终局前) |
Zone ID 常量
| 常量 | 字面值 | zone type | 说明 |
|---|---|---|---|
DDZ_DECK_ZONE_ID | 'ddz-deck' | 'deck' | 牌堆 zone,初始存放洗好的 54 张牌 |
DDZ_BOTTOM_ZONE_ID | 'ddz-bottom' | 'custom' | 底牌 zone,发牌后存 3 张底牌;PLAYING 阶段为空 |
DDZ_DISCARD_ZONE_ID | 'ddz-discard' | 'discard' | 弃牌堆 zone,存放已打出的牌 |
DoudizhuPhase
ts
enum DoudizhuPhase {
DEALING = 'DEALING',
BIDDING = 'BIDDING',
PLAYING = 'PLAYING',
FINISHED = 'FINISHED'
}斗地主游戏阶段。Engine 核心的 GameStatus('waiting' | 'playing' | 'finished')跟踪顶层生命周期,而此枚举将 'playing' 阶段细化为斗地主专用的子阶段。
| 枚举值 | 说明 |
|---|---|
DEALING | 已洗牌 / 发牌但尚未确定地主(setup 完成后的初始阶段) |
BIDDING | 玩家按座位顺序叫地主 / 抢地主 |
PLAYING | 地主已确定、底牌已亮,玩家轮流出牌 |
FINISHED | 有玩家清空手牌;已记录胜者 |
phaseLabel()
ts
function phaseLabel(p: DoudizhuPhase): string阶段的人类可读标签(用于日志与测试)。当前实现为恒等函数(直接返回入参)。
参数
p: DoudizhuPhase— 阶段枚举值
返回值
string— 阶段名称(与入参相同)
DoudizhuTeam
ts
enum DoudizhuTeam {
LANDLORD = 'LANDLORD',
FARMERS = 'FARMERS'
}斗地主队伍。地主单独对抗两位农民;两位农民在胜负计算时视为同一队伍(任一农民清空手牌即视为 FARMERS 队获胜)。
| 枚举值 | 说明 |
|---|---|
LANDLORD | 地主队(仅地主一人) |
FARMERS | 农民队(两位农民) |
teamLabel()
ts
function teamLabel(t: DoudizhuTeam): string队伍的人类可读标签。当前实现为恒等函数(直接返回入参)。
DoudizhuState(聚合快照)
ts
interface DoudizhuState {
phase: DoudizhuPhase
landlordId?: string
farmerIds: string[]
bottomCardIds: string[]
currentPlayerId?: string
lastPlayerId?: string
lastCombination?: DoudizhuCombination
passCount: number
multiplier: number
bidderIndex: number
bidderPassed: string[]
landlordCandidateId?: string
}由 GameState 推导出的所有斗地主专用状态快照。所有字段均为防御性拷贝,调用方无法修改底层 state。
| 字段 | 类型 | 说明 |
|---|---|---|
phase | DoudizhuPhase | 当前阶段 |
landlordId? | string | undefined | 地主玩家 id |
farmerIds | string[] | 农民玩家 id 列表 |
bottomCardIds | string[] | 3 张底牌 id 列表 |
currentPlayerId? | string | undefined | 当前轮到出牌的玩家 id(来自 state.currentPlayerId) |
lastPlayerId? | string | undefined | 上一手实际出牌玩家 id |
lastCombination? | DoudizhuCombination | undefined | 上一手出牌的牌型对象 |
passCount | number | 本轮累计过牌次数 |
multiplier | number | 当前倍率 |
bidderIndex | number | 当前叫分人在座位顺序中的索引 |
bidderPassed | string[] | 已选择"不叫"的玩家 id 列表 |
landlordCandidateId? | string | undefined | 地主候选人 id |
访问器函数
getDoudizhuPhase()
ts
function getDoudizhuPhase(state: GameState): DoudizhuPhase参数
state: GameState— 游戏状态
返回值
DoudizhuPhase— 当前斗地主阶段。未设置时默认为DoudizhuPhase.DEALING(与 Plugin 的初始状态一致)。
getLandlordId()
ts
function getLandlordId(state: GameState): string | undefined返回值
string | undefined— 地主玩家 id。PLAYING 阶段前为undefined。
getFarmerIds()
ts
function getFarmerIds(state: GameState): string[]返回值
string[]— 农民玩家 id 列表。未设置时返回[](空数组)。
getBottomCardIds()
ts
function getBottomCardIds(state: GameState): string[]返回值
string[]— 3 张底牌 id 列表。未设置时返回[]。
getLastPlayerId()
ts
function getLastPlayerId(state: GameState): string | undefined返回值
string | undefined— 上一手实际出牌玩家 id。新一轮开始时为undefined。
getLastCombination()
ts
function getLastCombination(state: GameState): DoudizhuCombination | undefined返回值
DoudizhuCombination | undefined— 上一手出牌的牌型对象。新一轮开始时为undefined。
getPassCount()
ts
function getPassCount(state: GameState): number返回值
number— 本轮累计过牌次数。未设置时返回0。
getMultiplier()
ts
function getMultiplier(state: GameState): number返回值
number— 当前倍率。未设置时返回1。
teamOf()
ts
function teamOf(playerId: string, state: GameState): DoudizhuTeam | undefined解析玩家所属队伍。当玩家是当前地主时属于 LANDLORD 队;其余玩家属于 FARMERS 队。在地主确定前(DEALING 与 BIDDING 阶段)返回 undefined。
参数
playerId: string— 玩家 idstate: GameState— 游戏状态
返回值
DoudizhuTeam | undefined— 玩家队伍;地主未确定时为undefined
示例
ts
import { teamOf, DoudizhuTeam, getLandlordId } from 'decklet/doudizhu'
const state = engine.getState()
const landlordId = getLandlordId(state)
if (landlordId) {
console.log(teamOf(landlordId, state) === DoudizhuTeam.LANDLORD) // true
// 其他玩家
for (const pid of Object.keys(state.players)) {
if (pid !== landlordId) {
console.log(teamOf(pid, state) === DoudizhuTeam.FARMERS) // true
}
}
}isNewRound()
ts
function isNewRound(state: GameState): boolean是否为新轮次的首出(无上一手牌型)时为 true。
返回值
boolean—getLastCombination(state) === undefined的结果
getDoudizhuState()
ts
function getDoudizhuState(state: GameState): DoudizhuState从 GameState 推导出一份斗地主状态快照,供测试 / 日志使用。所有数组成员均为防御性拷贝,调用方修改不会影响底层 state。
返回值
DoudizhuState— 聚合快照对象
示例
ts
import { getDoudizhuState } from 'decklet/doudizhu'
const ddz = getDoudizhuState(engine.getState())
console.log(ddz.phase) // 'BIDDING' | 'PLAYING' | ...
console.log(ddz.bidderPassed) // ['p2'] 之类的已"不叫"列表
console.log(ddz.landlordCandidateId) // 候选人 id 或 undefinedgetHandCards()
ts
function getHandCards(state: GameState, playerId: string): Card[]返回玩家手牌 zone 中当前持有的卡牌。供 Rule 与示例运行器使用的辅助函数。
参数
state: GameState— 游戏状态playerId: string— 玩家 id
返回值
Card[]— 玩家手牌 zone(player:{playerId}:hand)中的全部卡牌。zone 不存在时返回[]。
示例
ts
import {
GameEngine,
TurnPlugin,
DrawPlugin,
DoudizhuPlugin,
createCallLandlordAction,
getDoudizhuState,
getDoudizhuPhase,
getLandlordId,
getFarmerIds,
getMultiplier,
getPassCount,
isNewRound,
getHandCards,
DDZ_VAR_MULTIPLIER
} from 'decklet/doudizhu'
const engine = new GameEngine({ seed: 7 })
engine.use(TurnPlugin).use(DrawPlugin).use(DoudizhuPlugin)
engine.createGame({
players: [
{ id: 'p1', name: 'Alice', seat: 1 },
{ id: 'p2', name: 'Bob', seat: 2 },
{ id: 'p3', name: 'Carol', seat: 3 }
]
})
engine.start()
// BIDDING 阶段快照
const s1 = getDoudizhuState(engine.getState())
console.log(s1.phase) // 'BIDDING'
console.log(s1.landlordId) // undefined
console.log(s1.bidderPassed) // []
console.log(isNewRound(engine.getState())) // true(首出无 lastCombination)
engine.dispatch(createCallLandlordAction('p1', true))
// PLAYING 阶段快照
const s2 = getDoudizhuState(engine.getState())
console.log(s2.phase) // 'PLAYING'
console.log(s2.landlordId) // 'p1'
console.log(s2.farmerIds) // ['p2', 'p3']
console.log(s2.multiplier) // 1
console.log(getHandCards(engine.getState(), 'p1').length) // 20(17 + 3 底牌)注意事项
- 所有 getter 函数对未设置的变量均返回安全默认值(
undefined/0/1/[]),不会抛错。 getDoudizhuState返回的数组(farmerIds/bottomCardIds/bidderPassed)为防御性拷贝,修改不影响底层 state;但lastCombination等对象引用直接返回原对象,不应被调用方修改。phaseLabel/teamLabel当前均为恒等函数,保留是为了与扑克 / UNO 插件的 API 对称。