anvilsign in

collin/mahjong

1import type { Tile } from './tiles';
2
3export type SeatId = 0 | 1 | 2 | 3;
4
5/** Placeholder names, until somebody types their own on the settings screen. */
6export const DEFAULT_NAMES = ['玩家 1', '玩家 2', '玩家 3', '玩家 4'];
7
8export type MeldKind =
9 | 'chow' // 吃
10 | 'pung' // 碰
11 | 'kong' // 明槓 (claimed from a discard)
12 | 'ankong' // 暗槓 (four from hand)
13 | 'addkong'; // 加槓 (fourth tile added to an exposed pung)
14
15export interface Meld {
16 kind: MeldKind;
17 /** Sorted tiles making up the meld. */
18 tiles: Tile[];
19 /** Whose discard it came from, if any. */
20 from?: SeatId;
21}
22
23export const meldIsConcealed = (m: Meld) => m.kind === 'ankong';
24export const meldIsKong = (m: Meld) => m.kind === 'kong' || m.kind === 'ankong' || m.kind === 'addkong';
25
26export interface Player {
27 name: string;
28 hand: Tile[]; // concealed, sorted
29 melds: Meld[];
30 flowers: Tile[];
31 discards: Tile[];
32 score: number;
33}
34
35export interface Rules {
36 /** 底 — flat amount every payer contributes. */
37 base: number;
38 /** 台 — value of one tai. */
39 taiValue: number;
40 /** Tiles left in the wall when the hand is declared a draw (流局). */
41 wallReserve: number;
42 /** Starting chips per player. */
43 startingScore: number;
44 /**
45 * 過水 — pass on a tile you could have won on and it is dead to you until
46 * your own next draw.
47 */
48 sacredDiscard: boolean;
49 /**
50 * Whether taking a 碰/吃/槓 also lifts a 過水 lock, or only drawing does.
51 * Tables genuinely differ, hence the flag.
52 */
53 sacredClearedByClaim: boolean;
54 /** 一炮多響 — one discard pays out to every seat that declares on it. */
55 multipleWinners: boolean;
56 /**
57 * 包牌 — feed the third dragon or wind pung to an obvious 大三元 / 大四喜
58 * and you answer for the whole hand yourself.
59 */
60 liability: boolean;
61}
62
63export const DEFAULT_RULES: Rules = {
64 base: 3,
65 taiValue: 1,
66 wallReserve: 16,
67 startingScore: 100,
68 sacredDiscard: true,
69 sacredClearedByClaim: false,
70 multipleWinners: false,
71 liability: true,
72};