import type { Chessman } from './chessman'; export type PlaneCell = { id: number; x: number; y: number; /** UI에 보이는 이름 */ type: string; /** 효과가 있을 때만 설정. 없으면 착지 시 아무 일도 없음 */ eventId?: string | null; /** 칸 이미지 (없으면 텍스트만) */ imageSrc?: string | null; }; export type TurnContext = { chessman: Chessman; board: PlaneCell[]; roll: number; landIndex: number; }; export type TurnResult = { message: string; /** 비행기 등: 즉시 이동할 칸 */ teleportTo?: number; }; export interface CellEvent { readonly id: string; apply(ctx: TurnContext): TurnResult; } /** 무인도: 최대 3턴 대기, 주사위 6이면 즉시 탈출 가능 */ export class IslandEvent implements CellEvent { readonly id = 'island'; apply(ctx: TurnContext): TurnResult { ctx.chessman.enterIsland(3, 6); return { message: '무인도! 3턴 대기 (6이면 탈출)' }; } } /** 역방향: 진행 방향을 반대로 */ export class ReverseEvent implements CellEvent { readonly id = 'reverse'; apply(ctx: TurnContext): TurnResult { const dir = ctx.chessman.reverseDirection(); return { message: dir === 1 ? '역방향! 다시 시계방향' : '역방향! 반시계로 진행', }; } } /** 비행기: 지정한 칸으로 즉시 이동 */ export class AirplaneEvent implements CellEvent { readonly id = 'airplane'; constructor(private readonly targetIndex: number) {} apply(ctx: TurnContext): TurnResult { const target = ((this.targetIndex % ctx.board.length) + ctx.board.length) % ctx.board.length; ctx.chessman.teleport(target); const dest = ctx.board[target]; return { message: `비행기! → ${dest?.type ?? target}`, teleportTo: target, }; } } export const CELL_EVENTS: Record = { island: new IslandEvent(), reverse: new ReverseEvent(), // 기본 도착지는 시작(0). 판 생성 시 덮어쓸 수 있다. airplane: new AirplaneEvent(0), }; export function getCellEvent(eventId: string | null | undefined): CellEvent | null { if (!eventId) return null; return CELL_EVENTS[eventId] ?? null; } export function applyLandEvent(ctx: TurnContext): TurnResult | null { const cell = ctx.board[ctx.landIndex]; const event = getCellEvent(cell?.eventId); if (!event) return null; return event.apply(ctx); }