Skip to content

DoudizhuState ​

斗地主状态访问器:集中定义所有斗地主相关的 state.variables 键、zone id,以及从 GameState 读取这些字段的访问器函数。

概述 ​

所有斗地主插件状态都存储在核心 GameState 的 state.variables 下,以保持核心 GameState 形状通用。本模块提供:

  • 11 个 DDZ_VAR_* 变量键常量;
  • 3 个 DDZ_*_ZONE_ID zone id 常量;
  • 11 个 getter 函数(如 getDoudizhuPhase / getLandlordId 等);
  • 1 个聚合快照函数 getDoudizhuState;
  • 2 个语义判定函数 teamOf / isNewRound;
  • 1 个手牌读取函数 getHandCards。

变量键常量(DDZ_VAR_*) ​

所有键均以 'ddz.' 前缀存储在 state.variables 中。

常量字面值类型默认值说明
DDZ_VAR_PHASE'ddz.phase'DoudizhuPhaseDEALING当前斗地主子阶段
DDZ_VAR_LANDLORD_ID'ddz.landlordId'string | undefinedundefined最终地主玩家 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 | undefinedundefined上一手实际出牌玩家 id
DDZ_VAR_LAST_COMBINATION'ddz.lastCombination'DoudizhuCombination | undefinedundefined上一手出牌的牌型对象
DDZ_VAR_PASS_COUNT'ddz.passCount'number0本轮累计过牌次数
DDZ_VAR_MULTIPLIER'ddz.multiplier'number1当前倍率
DDZ_VAR_BIDDER_INDEX'ddz.bidderIndex'number0当前叫分人在座位顺序中的索引
DDZ_VAR_BIDDER_PASSED'ddz.bidderPassed'string[][]已选择"不叫"的玩家 id 列表
DDZ_VAR_LANDLORD_CANDIDATE_ID'ddz.landlordCandidateId'string | undefinedundefined地主候选人 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。

字段类型说明
phaseDoudizhuPhase当前阶段
landlordId?string | undefined地主玩家 id
farmerIdsstring[]农民玩家 id 列表
bottomCardIdsstring[]3 张底牌 id 列表
currentPlayerId?string | undefined当前轮到出牌的玩家 id(来自 state.currentPlayerId)
lastPlayerId?string | undefined上一手实际出牌玩家 id
lastCombination?DoudizhuCombination | undefined上一手出牌的牌型对象
passCountnumber本轮累计过牌次数
multipliernumber当前倍率
bidderIndexnumber当前叫分人在座位顺序中的索引
bidderPassedstring[]已选择"不叫"的玩家 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 — 玩家 id
  • state: 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 或 undefined

getHandCards() ​

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 对称。