texas-poker-core 1.4.31 → 1.4.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +4 -2
  2. package/dist/Controller/index.js +9 -7
  3. package/dist/Texas/index.js +1 -1
  4. package/package.json +1 -1
  5. package/types/Controller/HandSettlement.d.ts +0 -28
  6. package/types/Controller/constants.d.ts +0 -2
  7. package/types/Controller/index.d.ts +0 -146
  8. package/types/Controller/index.test.d.ts +0 -1
  9. package/types/Controller/stage.d.ts +0 -9
  10. package/types/Dealer/DealerService.d.ts +0 -47
  11. package/types/Dealer/Table.d.ts +0 -38
  12. package/types/Dealer/index.d.ts +0 -74
  13. package/types/Dealer/index.test.d.ts +0 -1
  14. package/types/Deck/DealtBoard.d.ts +0 -15
  15. package/types/Deck/constant.d.ts +0 -30
  16. package/types/Deck/core.d.ts +0 -9
  17. package/types/Deck/core.test.d.ts +0 -1
  18. package/types/Deck/format.d.ts +0 -5
  19. package/types/Deck/handCombinations.d.ts +0 -6
  20. package/types/Deck/handCompare.d.ts +0 -21
  21. package/types/Deck/handEvaluation.d.ts +0 -11
  22. package/types/Deck/index.d.ts +0 -20
  23. package/types/Deck/index.test.d.ts +0 -1
  24. package/types/Deck/standardDeck.d.ts +0 -6
  25. package/types/Deck/standardDeck.test.d.ts +0 -1
  26. package/types/Hand/CurrentHand.d.ts +0 -28
  27. package/types/Player/allowedActions.d.ts +0 -28
  28. package/types/Player/allowedActions.test.d.ts +0 -1
  29. package/types/Player/constant.d.ts +0 -36
  30. package/types/Player/handBettingActions.d.ts +0 -12
  31. package/types/Player/index.d.ts +0 -176
  32. package/types/Player/index.test.d.ts +0 -1
  33. package/types/Player/resolveAllInChipsOrError.d.ts +0 -16
  34. package/types/Player/resolveAllInChipsOrError.test.d.ts +0 -1
  35. package/types/Player/resolveCallChipsOrError.d.ts +0 -21
  36. package/types/Player/resolveCallChipsOrError.test.d.ts +0 -1
  37. package/types/Player/resolveRaiseAdditionalOrError.d.ts +0 -20
  38. package/types/Player/resolveRaiseAdditionalOrError.test.d.ts +0 -1
  39. package/types/Player/resolveVoluntaryBetChipOrError.d.ts +0 -20
  40. package/types/Player/resolveVoluntaryBetChipOrError.test.d.ts +0 -1
  41. package/types/Pool/StreetBetLedger.d.ts +0 -16
  42. package/types/Pool/allocatePoolByInt.d.ts +0 -10
  43. package/types/Pool/getWinners.d.ts +0 -6
  44. package/types/Pool/getWinners.test.d.ts +0 -1
  45. package/types/Pool/index.d.ts +0 -47
  46. package/types/Pool/index.test.d.ts +0 -1
  47. package/types/Room/index.d.ts +0 -110
  48. package/types/Room/index.test.d.ts +0 -1
  49. package/types/TableStakes.d.ts +0 -14
  50. package/types/Texas/index.d.ts +0 -125
  51. package/types/Texas/index.test.d.ts +0 -1
  52. package/types/TexasEngineContext.d.ts +0 -29
  53. package/types/TexasError/codes.d.ts +0 -128
  54. package/types/TexasError/constant.d.ts +0 -7
  55. package/types/TexasError/index.d.ts +0 -12
  56. package/types/domain/handDomainEvents.d.ts +0 -156
  57. package/types/domain/tableCommand.d.ts +0 -60
  58. package/types/domain/tableCommandParse.d.ts +0 -7
  59. package/types/domain/tableCommandParse.test.d.ts +0 -1
  60. package/types/engine/applyTableCommand.d.ts +0 -20
  61. package/types/engine/applyTableCommand.test.d.ts +0 -1
  62. package/types/engine/applyVoluntaryTableCommand.test.d.ts +0 -1
  63. package/types/engine/canonicalTableSession.d.ts +0 -94
  64. package/types/engine/canonicalTableSession.test.d.ts +0 -1
  65. package/types/engine/dealerRingReadModel.d.ts +0 -6
  66. package/types/engine/dealerRingReadModel.test.d.ts +0 -1
  67. package/types/engine/domainEventReadModel.d.ts +0 -142
  68. package/types/engine/domainEventReadModel.test.d.ts +0 -1
  69. package/types/engine/handReducer.d.ts +0 -55
  70. package/types/engine/handReducer.test.d.ts +0 -1
  71. package/types/engine/index.d.ts +0 -15
  72. package/types/engine/pendingFlowReadModel.d.ts +0 -15
  73. package/types/engine/pendingFlowReadModel.test.d.ts +0 -1
  74. package/types/engine/runOrchestration.d.ts +0 -13
  75. package/types/engine/tableSnapshot.d.ts +0 -36
  76. package/types/engine/tableSnapshot.test.d.ts +0 -1
  77. package/types/engine/tableStateV1.d.ts +0 -35
  78. package/types/engine/tableStateV1.test.d.ts +0 -1
  79. package/types/gameContracts.d.ts +0 -26
  80. package/types/index.d.ts +0 -34
  81. package/types/integration_test.d.ts +0 -1
  82. package/types/orchestration/defaultPipeline.d.ts +0 -12
  83. package/types/orchestration/interpret.d.ts +0 -16
  84. package/types/orchestration/interpret.test.d.ts +0 -1
  85. package/types/playerSessionPorts.d.ts +0 -60
  86. package/types/replay/appendDomainEventsInterpretHandler.d.ts +0 -10
  87. package/types/replay/appendDomainEventsInterpretHandler.test.d.ts +0 -1
  88. package/types/replay/compositeFromNdjson.test.d.ts +0 -1
  89. package/types/replay/domainEventPersistence.d.ts +0 -35
  90. package/types/replay/domainEventPersistence.test.d.ts +0 -1
  91. package/types/replay/domainEventTapeValidation.d.ts +0 -15
  92. package/types/replay/domainEventTapeValidation.test.d.ts +0 -1
  93. package/types/replay/index.d.ts +0 -9
  94. package/types/replay/jsonlAppendOnlyStore.test.d.ts +0 -1
  95. package/types/replay/node/compositeFromNdjson.d.ts +0 -7
  96. package/types/replay/node/index.d.ts +0 -7
  97. package/types/replay/node/jsonlAppendOnlyStore.d.ts +0 -14
  98. package/types/replay/projectCompositeReadModel.d.ts +0 -24
  99. package/types/replay/projectCompositeReadModel.test.d.ts +0 -1
  100. package/types/replay/replayCanonicalCli.d.ts +0 -1
  101. package/types/replay/replayCompositeCli.d.ts +0 -1
  102. package/types/replay/replayCompositeGolden.test.d.ts +0 -1
  103. package/types/replay/replayValidateCli.d.ts +0 -1
  104. package/types/replay/replayVerifyCli.d.ts +0 -1
  105. package/types/replay/verifyCanonicalAgainstTape.d.ts +0 -51
  106. package/types/replay/verifyCanonicalAgainstTape.test.d.ts +0 -1
  107. package/types/simulateFiftyDealsReport.d.ts +0 -1
  108. package/types/simulator_game_run.d.ts +0 -1
  109. package/types/utils/index.d.ts +0 -6
package/README.md CHANGED
@@ -182,7 +182,7 @@ async function drainAndConsumePendingFlow(
182
182
  | `RolesAssigned` | `setPlayerRoles` |
183
183
  | `HoleCardsDealt` | `dealCards` |
184
184
  | `HandStarted` | `start` / `startPreflopWithJoiningBigBlinds` |
185
- | `PostedJoiningBigBlinds` | 入座大盲汇总(`startPreflopWithJoiningBigBlinds` 恒一条;`PostBigBlind` 每次一条) |
185
+ | `PostedJoiningBigBlinds` | 入座大盲汇总(`startPreflopWithJoiningBigBlinds` 至少一人入账时;`PostBigBlind` 每次一条) |
186
186
  | `BlindsPosted` | 桌 SB/BB 贴盲后 |
187
187
  | `PlayerActed` | 自愿行动 / 超时行动(盲注路径不发) |
188
188
  | `PotUpdated` | 每次入池后(紧跟对应 `PlayerActed` 或盲注行) |
@@ -724,4 +724,6 @@ reject modulo bias
724
724
  同步 README 接入文档
725
725
 
726
726
  ## 1.4.31
727
- 增加跑马摊牌事件
727
+ 增加跑马摊牌事件
728
+ ## 1.4.32
729
+ 增加 RunoutHandsRevealed 跑马亮底牌事件;无人须贴入座大盲时不发 PostedJoiningBigBlinds 空事件
@@ -497,7 +497,7 @@ var Controller = /*#__PURE__*/function () {
497
497
  /**
498
498
  * 与 {@link start} 同属一手开局原子路径:先进入翻前帧并 `HandStarted`,再对 `joiningBigBlindUserIds`
499
499
  * 依次入账(跳过 SB/BB、环上不存在 id 忽略),其间每条入池后各一条 `PotUpdated`;
500
- * 最后 **恒** 缓冲一条 {@link PostedJoiningBigBlinds},`posts` 为本次所有入座大盲(无人须贴时为空数组);
500
+ * 若至少一人入账则缓冲一条 {@link PostedJoiningBigBlinds}(`posts` 非空);无人须贴则**不发**(与 {@link start} 事件序列一致)。
501
501
  * 再贴桌盲并 `transferControlTo(BB.getNext())`。
502
502
  * 业务应仅此入口处理「待贴入座大盲」,勿在 `start()` 后再穿插 `PostBigBlind`。
503
503
  */
@@ -523,12 +523,14 @@ var Controller = /*#__PURE__*/function () {
523
523
  } finally {
524
524
  _iterator.f();
525
525
  }
526
- _classPrivateFieldGet(_handEvents, this).push({
527
- type: 'PostedJoiningBigBlinds',
528
- payload: _objectSpread(_objectSpread({}, _assertClassBrand(_Controller_brand, this, _eventMeta).call(this)), {}, {
529
- posts: joiningPosts
530
- })
531
- });
526
+ if (joiningPosts.length > 0) {
527
+ _classPrivateFieldGet(_handEvents, this).push({
528
+ type: 'PostedJoiningBigBlinds',
529
+ payload: _objectSpread(_objectSpread({}, _assertClassBrand(_Controller_brand, this, _eventMeta).call(this)), {}, {
530
+ posts: joiningPosts
531
+ })
532
+ });
533
+ }
532
534
  _assertClassBrand(_Controller_brand, this, _postTableBlindsAndFirstPreflopActor).call(this);
533
535
  }
534
536
  }, {
@@ -253,7 +253,7 @@ var Texas = /*#__PURE__*/function () {
253
253
 
254
254
  /**
255
255
  * 开始本手(含「入座大盲」):与 {@link start} 相同前置条件;由 Core 原子完成
256
- * `HandStarted` → 对 `joiningBigBlindUserIds` 贴入座大盲(跳过 SB/BB、未知 id 忽略)→ **恒** 一条 `PostedJoiningBigBlinds`(`posts` 汇总,无人须贴时为空数组)→ 桌盲 → `transferControlTo(BB.getNext())`。
256
+ * `HandStarted` → 对 `joiningBigBlindUserIds` 贴入座大盲(跳过 SB/BB、未知 id 忽略)→ 有人入账则 `PostedJoiningBigBlinds` 桌盲 → `transferControlTo(BB.getNext())`。
257
257
  * 业务应消费本批领域事件并驱动 `pendingFlowOps`;勿再于 `start()` 后自行 `dispatchCommand(PostBigBlind)`。
258
258
  */
259
259
  }, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "texas-poker-core",
3
- "version": "1.4.31",
3
+ "version": "1.4.32",
4
4
  "description": "德州扑克核心功能",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -1,28 +0,0 @@
1
- import { Player } from '../Player';
2
- import { Poke, RankCategory, RankSignature } from '../Deck/constant';
3
- export type RankSettlementSnapshot = {
4
- rankCategory?: RankCategory;
5
- pokes: Poke[][];
6
- rankStrength: number;
7
- /** 与 `pokes[0]` 一致的最强牌签名(多人平分牌型时各赢家 bestFive 的签名相同)。 */
8
- rankSignature?: RankSignature;
9
- };
10
- /** 单座摊牌评估(唯一数据源;`Player` 经 `Controller.getShowdownEvalForPlayer` 只读) */
11
- export type ShowdownPlayerEval = {
12
- bestFiveCards: Poke[];
13
- rankSignature: RankSignature;
14
- rankStrength: number;
15
- rankCategory: RankCategory;
16
- };
17
- /**
18
- * 摊牌结算:按 userId 存评估表,并汇总桌上最强牌型。
19
- * 与阶段机、控制权移交无关。
20
- */
21
- export declare class HandSettlement {
22
- #private;
23
- get snapshot(): RankSettlementSnapshot;
24
- getPlayerEval(userId: number): ShowdownPlayerEval | undefined;
25
- setPlayerEval(userId: number, evalData: ShowdownPlayerEval): void;
26
- reset(): void;
27
- settleFromCommonBoard(allSeatedPlayers: Player[], playersStillInShowdown: Player[], commonPokes: Poke[]): void;
28
- }
@@ -1,2 +0,0 @@
1
- import { StageEnum } from '.';
2
- export declare const stageMap: Map<StageEnum, string>;
@@ -1,146 +0,0 @@
1
- /**
2
- * 控制本手阶段、奖池结算与领域事件缓冲。
3
- * 进街与下一位思考权不立即生效:写入 {@link Controller.#pendingFlowOps},由业务调用
4
- * {@link applyPendingStageAdvance} / {@link flushPendingTurnHandoff}(或 {@link drainPendingFlowOpsSync})消费。
5
- */
6
- import type { Role } from '../Player/constant';
7
- import type { ShowdownPlayerEval } from './HandSettlement';
8
- import type { PlayerHandSession } from '../playerSessionPorts';
9
- import type { HandDomainEvent, TurnEndedReason } from '../domain/handDomainEvents';
10
- import type { GameComponent, HandLifecycle, TexasErrorCallback } from '../gameContracts';
11
- import Pool from '../Pool';
12
- import Dealer from '../Dealer';
13
- import { Poke } from '../Deck/constant';
14
- import { Player } from '../Player';
15
- import { StageEnum, type Stage } from './stage';
16
- export { StageEnum, type Stage } from './stage';
17
- export type { HandLifecycle };
18
- /**
19
- * 流程队列项(FIFO)。
20
- * - `stage_advance`:一轮下注已结束,须再执行一条进街(含 `betting_round_complete` 或跑马路 `runout_reveal`)。
21
- * - `turn_handoff`:记录待交权目标;消费时才设置 `activePlayer` 并缓冲 `TurnOffered`。
22
- */
23
- export type PendingFlowOp = {
24
- kind: 'stage_advance';
25
- } | {
26
- kind: 'turn_handoff';
27
- toUserId: number;
28
- };
29
- export type PendingFlowOpKind = PendingFlowOp['kind'];
30
- declare class Controller implements GameComponent, PlayerHandSession<Player> {
31
- #private;
32
- fail: TexasErrorCallback;
33
- constructor(dealer: Dealer, pool: Pool, fail?: TexasErrorCallback);
34
- /** 当前本手 id;未经过 `prepareHandTape` 时为 `null` */
35
- get currentHandId(): string | null;
36
- /**
37
- * 为本手分配 `handId`、重置本手 `seq` 与事件缓冲;同一物理手上再次调用(如仅 `rearrange`)时为 no-op。
38
- * 由 {@link Texas#setPlayerRoles} / {@link Texas#dealCards} 在写磁带前调用。
39
- */
40
- prepareHandTape(): void;
41
- recordRolesAssigned(players: ReadonlyArray<{
42
- userId: number;
43
- name: string;
44
- role: Role;
45
- actionIndex: number;
46
- }>): void;
47
- recordHoleCardsDealt(byUserId: Record<number, Poke[]>): void;
48
- /** 自上次 drain 以来本手产生的事件(取出后清空本手缓冲) */
49
- drainHandEvents(): HandDomainEvent[];
50
- get status(): HandLifecycle;
51
- get defaultBets(): {
52
- userId: number;
53
- balance: number;
54
- amount: number;
55
- }[];
56
- get stage(): StageEnum;
57
- getShowdownEvalForPlayer(player: Player): ShowdownPlayerEval | undefined;
58
- setShowdownEvalForPlayer(player: Player, evalData: ShowdownPlayerEval): void;
59
- get activePlayer(): Player | null;
60
- recordPlayerAction(player: Player, options: {
61
- emitPot: boolean;
62
- }): void;
63
- recordPotUpdated(): void;
64
- recordTurnOffered(player: Player): void;
65
- recordTurnEnded(userId: number, reason: TurnEndedReason): void;
66
- setPendingTurnEndedReason(reason: TurnEndedReason): void;
67
- consumePendingTurnEndedReason(): TurnEndedReason | null;
68
- recordPotAwarded(potTotal: number, allocations: Array<{
69
- userId: number;
70
- amount: number;
71
- }>): void;
72
- /**
73
- * ② 结束条件(没人还能操作):
74
- * - 场上只剩 out / allIn(无 eligible)=> 直接结束(可能发生在任意街:多人全下)
75
- * - 河牌圈且所有仍可行动玩家都不可 actionable(即便 status 仍为 eligible)=> 结束
76
- */
77
- shouldShowDown(): boolean;
78
- /**
79
- * 仅入队 `turn_handoff`,**不**设置 `activePlayer`、不调用 `getControl()`。
80
- * 下一家的 `TurnOffered` 在 {@link flushPendingTurnHandoff} 消费队头时进入缓冲。
81
- */
82
- transferControlTo(player: Player | null): undefined;
83
- clearActivePlayerAfterAction(player: Player): void;
84
- /**
85
- * 循环:队头为 `stage_advance` 则 {@link applyPendingStageAdvance},否则 {@link flushPendingTurnHandoff},直至队列为空。
86
- * 单测 / 模拟器「零节拍」跑通一手时使用;生产环境通常由业务在 sleep 之间逐步消费。
87
- */
88
- drainPendingFlowOpsSync(): void;
89
- /** 返回队列快照,不修改队列。 */
90
- getPendingFlowOps(): PendingFlowOp[];
91
- /**
92
- * 当且仅当:全员本轮不可再行动 **且** 当前街仍可进到下一街(未到河牌)。
93
- * 为 true 时 {@link Player.transferControl} 会 {@link requestDeferredStageAdvance} 而非同步进街。
94
- */
95
- canDeferBettingRoundStageAdvance(): boolean;
96
- /** 将「待进街」入队;实际推进由 {@link applyPendingStageAdvance} 执行。 */
97
- requestDeferredStageAdvance(): void;
98
- /**
99
- * 消费队头 `stage_advance`(否则抛 `CTRL_FLOW_PENDING_MISMATCH`)。
100
- * - 非跑马路:`#performBettingRoundStageAdvance` → `StageAdvanced(betting_round_complete)` → 再入队首位行动者的 `turn_handoff`。
101
- * - `#runoutMode`:`#applyOneRunoutRevealStep` → `StageAdvanced(runout_reveal)`;到河牌时顺带 settle、`HandEnded(showdown)`。
102
- */
103
- applyPendingStageAdvance(): void;
104
- /**
105
- * 队头为 `turn_handoff` 时 shift,并在此刻真正设置 `activePlayer` 与发出 `TurnOffered`。
106
- * 队头类型不符、或目标玩家缺失时 **静默 return**(不抛错)。
107
- */
108
- flushPendingTurnHandoff(): void;
109
- /**
110
- * 尝试收局。返回 `true` 表示本方法已处理终局逻辑(或已入队跑马路,不再向下传递控制权)。
111
- * - 独赢弃牌:同步 settle + `HandEnded(fold_win)`。
112
- * - 摊牌且 **非河牌**:`#runoutMode`、多条 `stage_advance` 入队、`resetActivePlayer`,**无**当场 `HandEnded`。
113
- * - 摊牌且 **已在河牌**:同步 settle + `HandEnded(showdown)`。
114
- */
115
- tryToEndGame(): boolean;
116
- getCommonPokes(currentStage: Stage, endStage: Stage): Poke[];
117
- /** 当前手牌阶段下已发出的公牌(翻前 → `#hand.stage`)。 */
118
- getRevealedPokes(): Poke[];
119
- /**
120
- * 中途入座贴大盲:翻前、非当前 `activePlayer`、本街 `currentStageTotalAmount === 0`、且玩家仍为 `eligible`。
121
- * 入池额 `min(桌大盲, 余额)`,与开局盲注路径一致;**不**调用 `completeBettingTurn`、不改变当前思考权。
122
- */
123
- postBigBlindForJoiningPlayer(player: Player): void;
124
- takeActionInPreFlop(): void;
125
- /**
126
- * 进入本手街道阶段:须在 {@link prepareHandTape} 之后调用;不清空已缓冲的 `RolesAssigned` / `HoleCardsDealt`。
127
- * 写入 `HandStarted`、贴盲与 **`pendingFlowOps` / 跑马路状态**,再 `transferControlTo`(首人思考权先入队,待业务 flush)。
128
- */
129
- start(): void;
130
- /**
131
- * 与 {@link start} 同属一手开局原子路径:先进入翻前帧并 `HandStarted`,再对 `joiningBigBlindUserIds`
132
- * 依次入账(跳过 SB/BB、环上不存在 id 忽略),其间每条入池后各一条 `PotUpdated`;
133
- * 最后 **恒** 缓冲一条 {@link PostedJoiningBigBlinds},`posts` 为本次所有入座大盲(无人须贴时为空数组);
134
- * 再贴桌盲并 `transferControlTo(BB.getNext())`。
135
- * 业务应仅此入口处理「待贴入座大盲」,勿在 `start()` 后再穿插 `PostBigBlind`。
136
- */
137
- startPreflopWithJoiningBigBlinds(joiningBigBlindUserIds: ReadonlyArray<number>): void;
138
- continue(): undefined;
139
- settleRankingsThroughStage(throughStage: Stage): void;
140
- end(): undefined;
141
- resetActivePlayer(): void;
142
- reset(): void;
143
- pause(): void;
144
- }
145
- export type { ShowdownPlayerEval } from './HandSettlement';
146
- export default Controller;
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- /** 公共牌推进阶段;独立文件避免 Player ↔ Controller 循环依赖 */
2
- export declare enum StageEnum {
3
- PRE_FLOP = "pre_flop",
4
- FLOP = "flop",
5
- TURN = "turn",
6
- RIVER = "river"
7
- }
8
- export type Stage = StageEnum;
9
- export declare const STAGE_ORDER: Stage[];
@@ -1,47 +0,0 @@
1
- import type { Table } from './Table';
2
- import type { Poke } from '../Deck/constant';
3
- import type { TableStakes } from '../TableStakes';
4
- import type { GameComponent, TexasErrorCallback } from '../gameContracts';
5
- import Deck from '../Deck';
6
- import { Player } from '../Player';
7
- /**
8
- * 荷官侧流程:牌堆、角色分配、发牌、行动历史、桌面日志;依赖 {@link Table} 提供座位环与遍历。
9
- */
10
- export declare class DealerService implements GameComponent {
11
- #private;
12
- fail: TexasErrorCallback;
13
- constructor(table: Table, deck: Deck, stakes: TableStakes, fail?: TexasErrorCallback, options?: {
14
- maxTablePlayers?: number;
15
- });
16
- get actionHistory(): Player[];
17
- get deck(): Deck;
18
- /** 当前已发手牌与公牌快照(与牌堆对象分离) */
19
- getPokes(): import("../Deck/DealtBoard").DealSnapshot;
20
- get stakes(): TableStakes;
21
- get lowestBetAmount(): number;
22
- dealCards(): undefined;
23
- /**
24
- * 手牌唯一数据源为 {@link DealtBoard};下标与发牌顺序一致(从庄家下家起绕桌一圈)。
25
- */
26
- getHoleCardsForPlayer(player: Player): Poke[];
27
- setHoleCardsForPlayer(player: Player, pokes: readonly Poke[]): void;
28
- addAction(player: Player): void;
29
- initialRoles(buttonPlayer?: Player): undefined;
30
- reArrangeRoles(): undefined;
31
- rotateRolesForNewHand(): void;
32
- /** @deprecated 请使用 {@link DealerService.initialRoles} */
33
- setRoles(): void;
34
- log(): void;
35
- getPlayersStillInGame(): Player[];
36
- changeButtonToNextPlayer(): undefined;
37
- setButton(player: Player): void;
38
- setOthers(): undefined;
39
- /** 从庄家下家起绕桌一圈的玩家顺序(与行动序一致) */
40
- getPlayersByActionSequence(): Player[];
41
- resetCurrentStageTotalAmount(): void;
42
- resetActionsOfPlayers(): void;
43
- resetActionsHistory(): void;
44
- reset(): void;
45
- getTheFirstPlayerToAct(): Player | null;
46
- getPlayersCanAct(): Player[];
47
- }
@@ -1,38 +0,0 @@
1
- import type { TexasErrorCallback } from '../gameContracts';
2
- import { Player } from '../Player';
3
- /**
4
- * 环形座位:入座/离座、head/last、庄家位标记(仅引用,不负责 BTN/SB/BB 语义分配)。
5
- * 非法入座/离座通过 `fail` 抛出 {@link TexasError},与 Room / Dealer 层 fail-fast 一致。
6
- */
7
- export declare class Table {
8
- #private;
9
- constructor(fail: TexasErrorCallback);
10
- get count(): number;
11
- get button(): Player | null;
12
- /**
13
- * 设置庄家位标记(仅引用,不写角色枚举)。
14
- * 清空请用 {@link clearButtonSeat},避免 `setButtonSeat(null)` 语义含糊。
15
- */
16
- setButtonSeat(player: Player): void;
17
- /** 清空庄家位标记(例如桌上已无玩家) */
18
- clearButtonSeat(): void;
19
- get players(): Player[];
20
- join(player: Player): void;
21
- /**
22
- * 将 `player` 顺时针插在 `predecessor` 与其原 `next` 之间(用于新玩家插在 **大盲下家** 一侧,与 post BB 叙事一致)。
23
- * `predecessor` 须在环上且已有合法 `next`(至少两人环)。
24
- */
25
- joinAfter(predecessor: Player, player: Player): void;
26
- remove(player: Player): void;
27
- has(player: Player): boolean;
28
- hasById(userId: number): boolean;
29
- get(player: Player): Player | null;
30
- getById(userId: number): Player | null;
31
- forEach(callback: (p: Player, i: number) => void): void;
32
- map<T>(callback: (p: Player, i: number) => T): T[];
33
- every(callback: (p: Player, i: number) => boolean): boolean;
34
- findReverse(callback: (p: Player) => boolean, from: Player | null): Player | null;
35
- filter(callback: (p: Player, i: number) => boolean): Player[];
36
- find(callback: (p: Player) => boolean): Player | null;
37
- loop(callback: (p: Player, i: number) => void, startFrom?: Player | null | undefined): void;
38
- }
@@ -1,74 +0,0 @@
1
- import type { Poke } from '../Deck/constant';
2
- import type { PlayerDealerRing } from '../playerSessionPorts';
3
- import type { GameComponent, TexasErrorCallback } from '../gameContracts';
4
- import Deck from '../Deck';
5
- import { Table } from './Table';
6
- import { Player } from '../Player';
7
- import { TableStakes } from '../TableStakes';
8
- import { DealerService } from './DealerService';
9
- export { Table } from './Table';
10
- export { DealerService } from './DealerService';
11
- /**
12
- * 对外门面:组合 {@link Table}(座位环)与 {@link DealerService}(发牌与角色流程),保持原有 API。
13
- * 需要单独扩展座位逻辑或荷官逻辑时,可访问 `table` / `service`。
14
- */
15
- declare class Dealer implements GameComponent, PlayerDealerRing<Player> {
16
- #private;
17
- fail: TexasErrorCallback;
18
- constructor(stakes: TableStakes | number, fail?: TexasErrorCallback, options?: {
19
- maxTablePlayers?: number;
20
- });
21
- /** 环形座位与遍历;不含发牌与角色业务规则 */
22
- get table(): Table;
23
- /** 牌堆、角色、发牌、行动历史等 */
24
- get service(): DealerService;
25
- get actionHistory(): Player[];
26
- get count(): number;
27
- get button(): Player | null;
28
- get deck(): Deck;
29
- /** 已发手牌与公牌(由 DealerService 内 DealtBoard 持有,与 52 张牌堆分离) */
30
- getPokes(): import("..").DealSnapshot;
31
- /** 该玩家在 {@link DealtBoard} 中对应座位的手牌(Player 不再私有缓存) */
32
- getHoleCardsForPlayer(player: Player): ("hj" | "h2" | "h3" | "h4" | "h5" | "h6" | "h7" | "h8" | "h9" | "ht" | "hq" | "hk" | "ha" | "s2" | "s3" | "s4" | "s5" | "s6" | "s7" | "s8" | "s9" | "st" | "sj" | "sq" | "sk" | "sa" | "d2" | "d3" | "d4" | "d5" | "d6" | "d7" | "d8" | "d9" | "dt" | "dj" | "dq" | "dk" | "da" | "c2" | "c3" | "c4" | "c5" | "c6" | "c7" | "c8" | "c9" | "ct" | "cj" | "cq" | "ck" | "ca")[];
33
- setHoleCardsForPlayer(player: Player, pokes: readonly Poke[]): void;
34
- get players(): Player[];
35
- get stakes(): TableStakes;
36
- /** 大盲注额;与 `stakes.bigBlind` 同义 */
37
- get lowestBetAmount(): number;
38
- dealCards(): void;
39
- addAction(player: Player): void;
40
- initialRoles(buttonPlayer?: Player): void;
41
- reArrangeRoles(): void;
42
- rotateRolesForNewHand(): void;
43
- remove(player: Player): void;
44
- /**
45
- * @param options.insertAfter 若给定,则新座位插在**该玩家顺时针下家**一侧(房规:插在 **BB 之后** 时传大盲位玩家)。
46
- */
47
- join(player: Player, options?: {
48
- insertAfter: Player;
49
- }): void;
50
- has(player: Player): boolean;
51
- hasById(userId: number): boolean;
52
- get(player: Player): Player | null;
53
- getById(userId: number): Player | null;
54
- log(): void;
55
- getPlayersStillInGame(): Player[];
56
- changeButtonToNextPlayer(): void;
57
- setButton(player: Player): void;
58
- setOthers(): void;
59
- getPlayersByActionSequence(): Player[];
60
- forEach(callback: (p: Player, i: number) => void): void;
61
- map<T>(callback: (p: Player, i: number) => T): T[];
62
- every(callback: (p: Player, i: number) => boolean): boolean;
63
- resetCurrentStageTotalAmount(): void;
64
- resetActionsOfPlayers(): void;
65
- resetActionsHistory(): void;
66
- reset(): void;
67
- findReverse(callback: (p: Player) => boolean, from: Player | null): Player | null;
68
- filter(callback: (p: Player, i: number) => boolean): Player[];
69
- find(callback: (p: Player) => boolean): Player | null;
70
- loop(callback: (p: Player, i: number) => void, startFrom?: Player | null): void;
71
- getTheFirstPlayerToAct(): Player | null;
72
- getPlayersCanAct(): Player[];
73
- }
74
- export default Dealer;
@@ -1 +0,0 @@
1
- export {};
@@ -1,15 +0,0 @@
1
- import type { Poke } from './constant';
2
- export type DealSnapshot = {
3
- handPokes: Poke[][];
4
- commonPokes: Poke[];
5
- };
6
- /**
7
- * 上一手发牌结果(手牌矩阵 + 公牌),与 52 张牌堆 {@link Deck} 解耦。
8
- */
9
- export declare class DealtBoard {
10
- #private;
11
- capture(snapshot: DealSnapshot): void;
12
- reset(): void;
13
- getPokes(): DealSnapshot;
14
- setHoleCardsAt(index: number, pokes: readonly Poke[]): void;
15
- }
@@ -1,30 +0,0 @@
1
- export declare const suits: readonly ["h", "s", "d", "c"];
2
- export declare const ranks: readonly ["2", "3", "4", "5", "6", "7", "8", "9", "t", "j", "q", "k", "a"];
3
- /**
4
- * h: 红心
5
- * s: 黑桃
6
- * d: 方块
7
- * c: 梅花
8
- */
9
- export type Suit = (typeof suits)[number];
10
- export type Rank = (typeof ranks)[number];
11
- /**
12
- * 扑克牌的存储 比如h2, h8
13
- */
14
- export type Poke = `${Suit}${Rank}`;
15
- /**
16
- * 2张手牌
17
- */
18
- export type HandPoke = Poke[];
19
- /** 牌型枚举(五张牌型的类型:高牌/一对/顺子…) */
20
- export type RankCategory = 'z' | 'y' | 'x' | 'w' | 'v' | 'u' | 't' | 's' | 'r' | 'q';
21
- /**
22
- * 牌力签名:首字符为牌型 (RankCategory),后接可选数字段,如 "z" | "q14+13+12+11+9" | "w13+r7"
23
- */
24
- export type RankSignature = `${RankCategory}${string}`;
25
- /**
26
- * 花色format map
27
- */
28
- export declare const suitsMap: Map<"h" | "s" | "d" | "c", string>;
29
- export declare const rankCategoryMap: Map<RankCategory, string>;
30
- export declare const rankMap: (input: Rank) => number;
@@ -1,9 +0,0 @@
1
- /**
2
- * 牌力相关入口:按职责拆分为 `format` / `handEvaluation` / `handCompare` / `handCombinations`,本文件保持向后兼容的聚合导出。
3
- */
4
- export { createStandardDeckPokes } from './standardDeck';
5
- export { formatterPoke } from './format';
6
- export { isStraight, getFiveCardCombinationIndices, allFiveCardHandsFromPool, getFiveCardsRankSignature } from './handEvaluation';
7
- export { compareFn, compareRankSignature, getStrengthFromRankSignature, getFiveCardsStrength, rankSignatureToRanks, rankSignatureToDisplayGroups } from './handCompare';
8
- export type { RankSignatureDisplayGroup } from './handCompare';
9
- export { getBestFiveCards, getBestPokesRankSignature } from './handCombinations';
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- import { Poke } from './constant';
2
- /**
3
- * 展示用:将 Poke 格式化为可读字符串(与牌力计算无关)。
4
- */
5
- export declare const formatterPoke: (input: Poke[]) => string;
@@ -1,6 +0,0 @@
1
- import { Poke } from './constant';
2
- /**
3
- * 手牌 + 公牌 → 最优五张、多人比较、最佳牌型信息(依赖 evaluation + compare)。
4
- */
5
- export declare function getBestFiveCards(handPokes: Poke[], commonPokes: Poke[]): Poke[];
6
- export declare function getBestPokesRankSignature(handPokes: Poke[][], commonPokes: Poke[]): `s${string}` | `t${string}` | `q${string}` | `z${string}` | `y${string}` | `x${string}` | `w${string}` | `v${string}` | `u${string}` | `r${string}`;
@@ -1,21 +0,0 @@
1
- import { Poke, Rank, RankSignature } from './constant';
2
- /**
3
- * 将 `RankSignature` 展开为五张牌的点数(`Rank`),与 `getFiveCardsRankSignature` 编码对称。
4
- * 顺子 wheel(`u5`/`y5`)为 5→A 展示顺序,A 在末位;Broadway 仍为 A→T。
5
- * `x`(四条)当前签名仅含四条点数,踢脚未编码,第五位为 `null`。
6
- */
7
- export declare function rankSignatureToRanks(rankSignature: RankSignature): (Rank | null)[];
8
- /** 供 UI 分组渲染:每组 `ranks` 为从左到右、已合并同点的连续张(与 `rankSignatureToRanks` 顺序一致)。 */
9
- export type RankSignatureDisplayGroup = {
10
- ranks: Rank[];
11
- };
12
- /**
13
- * 将牌力签名映射为展示用分组(间距与样式由应用层决定)。
14
- * - `q`/`v`/`u`/`y`/`z`:每张一组;顺子 wheel 时 A 已在末位(见 `straightRanksFromMax`)。
15
- * - `r`/`s`/`t`/`w`/`x`:连续同点合并为一组。
16
- */
17
- export declare function rankSignatureToDisplayGroups(rankSignature: RankSignature): RankSignatureDisplayGroup[];
18
- export declare const compareFn: (a: Poke[], b: Poke[]) => number;
19
- export declare const compareRankSignature: (p1: string, p2: string) => number;
20
- export declare function getStrengthFromRankSignature(rankSignature: RankSignature): number;
21
- export declare function getFiveCardsStrength(input: Poke[]): number;
@@ -1,11 +0,0 @@
1
- import { Poke, Rank, RankSignature } from './constant';
2
- /**
3
- * 单副牌组合、顺子判定、五张牌型签名生成(不含两副牌之间的 compare)。
4
- */
5
- export declare const isStraight: (values: Rank[]) => {
6
- result: boolean;
7
- max: number;
8
- };
9
- export declare function getFiveCardCombinationIndices(n: number, k?: number): number[][];
10
- export declare function allFiveCardHandsFromPool(cards: Poke[]): Poke[][];
11
- export declare function getFiveCardsRankSignature(input: Poke[]): RankSignature;
@@ -1,20 +0,0 @@
1
- import { type Poke } from './constant';
2
- /**
3
- * 52 张牌堆:生成、洗牌、按德州规则发手牌与公牌(含烧牌)。
4
- * 发牌结果由调用方写入 {@link DealtBoard},本类不缓存手牌/公牌。
5
- */
6
- declare class Deck {
7
- #private;
8
- constructor();
9
- shuffle(): void;
10
- /**
11
- * @description 给玩家发牌
12
- * @param count 玩家数量
13
- */
14
- dealCards(count: number): {
15
- handPokes: Poke[][];
16
- commonPokes: Poke[];
17
- };
18
- getCards(): ("hj" | "h2" | "h3" | "h4" | "h5" | "h6" | "h7" | "h8" | "h9" | "ht" | "hq" | "hk" | "ha" | "s2" | "s3" | "s4" | "s5" | "s6" | "s7" | "s8" | "s9" | "st" | "sj" | "sq" | "sk" | "sa" | "d2" | "d3" | "d4" | "d5" | "d6" | "d7" | "d8" | "d9" | "dt" | "dj" | "dq" | "dk" | "da" | "c2" | "c3" | "c4" | "c5" | "c6" | "c7" | "c8" | "c9" | "ct" | "cj" | "cq" | "ck" | "ca")[];
19
- }
20
- export default Deck;
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- import { type Poke } from './constant';
2
- /**
3
- * 生成标准 52 张牌(无洗牌)。
4
- * 顺序与 `Deck` 内部建牌一致:按 `suits` 顺序,每种花色内 `ranks` 从 2 到 a(如 `h2`…`ha`,再 `s2`…)。
5
- */
6
- export declare function createStandardDeckPokes(): Poke[];
@@ -1 +0,0 @@
1
- export {};
@@ -1,28 +0,0 @@
1
- import type { Player } from '../Player';
2
- import type { HandLifecycle } from '../gameContracts';
3
- import { type Stage } from '../Controller/stage';
4
- import { HandSettlement } from '../Controller/HandSettlement';
5
- /**
6
- * 单桌「当前一手」的聚合状态:生命周期、街、控制权、盲注记录、摊牌评估。
7
- * 公牌进度与下注圈一致,由 {@link Controller} 维护的 `stage` 表示。
8
- * {@link Controller} 负责编排流程;本类只持有数据与 `HandSettlement`。
9
- */
10
- export declare class CurrentHand {
11
- /** 一手在控制器中的生命周期 */
12
- status: HandLifecycle;
13
- /** 当前下注圈(与已发公牌条数一致) */
14
- stage: Stage;
15
- /** 当前轮到行动的玩家 */
16
- activePlayer: Player | null;
17
- /** 翻牌前自动下的盲注记录(展示/回放) */
18
- defaultBets: Array<{
19
- userId: number;
20
- balance: number;
21
- amount: number;
22
- }>;
23
- /** 本手摊牌评估(按 userId) */
24
- readonly settlement: HandSettlement;
25
- constructor();
26
- /** 局间清理:与 `Controller.reset` 中对手牌的期望一致 */
27
- reset(): void;
28
- }
@@ -1,28 +0,0 @@
1
- import { ActionTypeEnum } from './constant';
2
- import TexasError, { type TexasErrorCode } from '../TexasError';
3
- /**
4
- * 纯函数:根据桌面公开状态推导当前玩家允许的行动列表(与倒计时、回调无关)。
5
- * 输入可由 {@link Player#getAllowedActionsContext} 构造,便于单测与机器人与 `Player` 解耦。
6
- */
7
- export type AllowedActionsContext = {
8
- /** 仍在底池争胜且可参与下注轮(思考权以 `Controller.activePlayer` 为准,不由状态位表达) */
9
- selfStatus: 'allIn' | 'eligible' | 'out';
10
- selfBalance: number;
11
- selfCurrentStageTotal: number;
12
- dealerActionHistory: readonly {
13
- getAction(): {
14
- type: ActionTypeEnum;
15
- } | undefined;
16
- getStatus(): string;
17
- readonly currentStageTotalAmount: number;
18
- }[];
19
- maxOthersStageBet: number;
20
- isBigBlindPreFlopOption: boolean;
21
- isJoiningBlindPreFlopOption: boolean;
22
- };
23
- export declare function resolveAllowedActions(ctx: AllowedActionsContext): ActionTypeEnum[];
24
- /**
25
- * 自愿动作是否被当前允许列表接纳(纯函数)。
26
- * 返回 `TexasError` 供调用方 `player.fail(err)`;通过则返回 `null`。
27
- */
28
- export declare function voluntaryActionDisallowError(allowed: readonly ActionTypeEnum[], required: ActionTypeEnum, disallowCode: TexasErrorCode): TexasError | null;
@@ -1 +0,0 @@
1
- export {};