158 lines
3.8 KiB
TypeScript
158 lines
3.8 KiB
TypeScript
import { ref } from 'vue'
|
|
|
|
export const DEFAULT_MAX_PLAYERS = 4
|
|
export type RoomStatus = 'waiting' | 'playing' | 'finished'
|
|
|
|
export interface RoomPlayerState {
|
|
index: number
|
|
playerId: string
|
|
displayName?: string
|
|
ready: boolean
|
|
handCount?: number
|
|
melds?: string[]
|
|
outTiles?: string[]
|
|
hasHu?: boolean
|
|
missingSuit?: string | null
|
|
}
|
|
|
|
export interface RuleState {
|
|
name: string
|
|
isBloodFlow: boolean
|
|
hasHongZhong: boolean
|
|
}
|
|
|
|
export interface GamePlayerState {
|
|
playerId: string
|
|
index: number
|
|
ready: boolean
|
|
}
|
|
|
|
export interface EngineState {
|
|
phase: string
|
|
dealerIndex: number
|
|
currentTurn: number
|
|
needDraw: boolean
|
|
players: GamePlayerState[]
|
|
wall: string[]
|
|
lastDiscardTile: string | null
|
|
lastDiscardBy: string
|
|
pendingClaim: Record<string, unknown> | null
|
|
winners: string[]
|
|
scores: Record<string, number>
|
|
lastDrawPlayerId: string
|
|
lastDrawFromGang: boolean
|
|
lastDrawIsLastTile: boolean
|
|
huWay: string
|
|
}
|
|
|
|
export interface GameState {
|
|
rule: RuleState | null
|
|
state: EngineState | null
|
|
}
|
|
|
|
export interface RoomState {
|
|
id: string
|
|
name: string
|
|
gameType: string
|
|
ownerId: string
|
|
maxPlayers: number
|
|
playerCount: number
|
|
status: RoomStatus | string
|
|
createdAt: string
|
|
updatedAt: string
|
|
game: GameState | null
|
|
players: RoomPlayerState[]
|
|
currentTurnIndex: number | null
|
|
myHand: string[]
|
|
}
|
|
|
|
function createInitialRoomState(): RoomState {
|
|
return {
|
|
id: '',
|
|
name: '',
|
|
gameType: 'chengdu',
|
|
ownerId: '',
|
|
maxPlayers: DEFAULT_MAX_PLAYERS,
|
|
playerCount: 0,
|
|
status: 'waiting',
|
|
createdAt: '',
|
|
updatedAt: '',
|
|
game: null,
|
|
players: [],
|
|
currentTurnIndex: null,
|
|
myHand: [],
|
|
}
|
|
}
|
|
|
|
export const activeRoomState = ref<RoomState>(createInitialRoomState())
|
|
|
|
export function destroyActiveRoomState(): void {
|
|
activeRoomState.value = createInitialRoomState()
|
|
}
|
|
|
|
export function resetActiveRoomState(seed?: Partial<RoomState>): void {
|
|
destroyActiveRoomState()
|
|
if (!seed) {
|
|
return
|
|
}
|
|
|
|
activeRoomState.value = {
|
|
...activeRoomState.value,
|
|
...seed,
|
|
players: seed.players ?? [],
|
|
myHand: seed.myHand ?? [],
|
|
}
|
|
}
|
|
|
|
export function mergeActiveRoomState(next: RoomState): void {
|
|
if (activeRoomState.value.id && next.id && next.id !== activeRoomState.value.id) {
|
|
return
|
|
}
|
|
|
|
activeRoomState.value = {
|
|
...activeRoomState.value,
|
|
...next,
|
|
name: next.name || activeRoomState.value.name,
|
|
gameType: next.gameType || activeRoomState.value.gameType,
|
|
ownerId: next.ownerId || activeRoomState.value.ownerId,
|
|
status: next.status || activeRoomState.value.status,
|
|
createdAt: next.createdAt || activeRoomState.value.createdAt,
|
|
updatedAt: next.updatedAt || activeRoomState.value.updatedAt,
|
|
game: next.game ?? activeRoomState.value.game,
|
|
players: next.players.length > 0 ? next.players : activeRoomState.value.players,
|
|
currentTurnIndex:
|
|
next.currentTurnIndex !== null ? next.currentTurnIndex : activeRoomState.value.currentTurnIndex,
|
|
myHand: next.myHand.length > 0 ? next.myHand : activeRoomState.value.myHand,
|
|
}
|
|
}
|
|
|
|
export function hydrateActiveRoomFromSelection(input: {
|
|
roomId: string
|
|
roomName?: string
|
|
gameType?: string
|
|
ownerId?: string
|
|
maxPlayers?: number
|
|
playerCount?: number
|
|
status?: string
|
|
createdAt?: string
|
|
updatedAt?: string
|
|
players?: RoomPlayerState[]
|
|
currentTurnIndex?: number | null
|
|
myHand?: string[]
|
|
}): void {
|
|
resetActiveRoomState({
|
|
id: input.roomId,
|
|
name: input.roomName ?? '',
|
|
gameType: input.gameType ?? 'chengdu',
|
|
ownerId: input.ownerId ?? '',
|
|
maxPlayers: input.maxPlayers ?? DEFAULT_MAX_PLAYERS,
|
|
playerCount: input.playerCount ?? 0,
|
|
status: input.status ?? 'waiting',
|
|
createdAt: input.createdAt ?? '',
|
|
updatedAt: input.updatedAt ?? '',
|
|
players: input.players ?? [],
|
|
currentTurnIndex: input.currentTurnIndex ?? null,
|
|
myHand: input.myHand ?? [],
|
|
})
|
|
}
|