/** * screw_puzzle.aigameplay — reducer 接口模板 * * Agent 生成实际 reducer 时,必须导出以下函数。 * 此文件是接口约束模板,不是可执行代码。 * * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ * ⚠️ 重要:渲染层(GameScene)不应直接调用 dispatch() * * dispatch() 是一体化接口,内部跑完整个操作链后只返回最终状态, * 中间过程(螺丝移动轨迹、零件释放顺序、重力下落路径)全部丢失。 * * 渲染层需要分步动画(螺丝拔出 → 飞入螺孔 → 零件下落 → 重力压缩), * 因此必须使用下方的「分步函数」逐步驱动,每步之间插入 Tween 动画。 * * dispatch() 的用途:无头测试、AI 模拟、快速跳过动画等场景。 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ // ─── 配置类型 ───────────────────────────────────────────────────────────────── export type ScrewColor = 'red' | 'blue' | 'green' | 'yellow' | 'purple' | 'orange'; export type ScrewPuzzleConfig = { /** 场景层数,默认 3 */ layers: number; /** 缓冲区最大容量,默认 3 */ bufferCapacity: number; /** 初始螺丝列表 */ screws: Array<{ id: string; color: ScrewColor; itemId: string; holeId: string; }>; /** 初始零件列表 */ items: Array<{ id: string; layer: number; screwIds: string[]; }>; /** 螺孔列表 */ screwHoles: Array<{ id: string; color: ScrewColor; itemId: string; }>; }; // ─── 动作类型 ───────────────────────────────────────────────────────────────── export type ScrewPuzzleAction = | { type: 'remove_screw'; screwId: string } | { type: 'reset' }; // ─── 状态类型 ───────────────────────────────────────────────────────────────── export type ItemState = 'fixed' | 'releasing' | 'released'; export type ScrewState = { id: string; color: ScrewColor; itemId: string; /** 当前所在螺孔 id,null 表示在缓冲区 */ holeId: string | null; }; export type ItemRecord = { id: string; layer: number; screwIds: string[]; state: ItemState; }; export type ScrewHoleRecord = { id: string; color: ScrewColor; itemId: string; /** 当前插入的螺丝 id,null 表示空闲 */ screwId: string | null; }; export type ScrewPuzzleState = { screws: Record; items: Record; screwHoles: Record; /** 缓冲区中的螺丝 id 列表(先入先出) */ buffer: string[]; /** 游戏是否结束 */ gameOver: boolean; /** 是否胜利 */ win: boolean; /** 失败原因 */ loseReason?: 'buffer_overflow' | 'deadlock'; }; // ─── 分步操作返回类型 ───────────────────────────────────────────────────────── /** 螺丝移动信息(用于驱动飞行动画) */ export type ScrewMove = { screwId: string; color: ScrewColor; /** 来源螺孔 id */ fromHoleId: string; /** 目标螺孔 id,null 表示进入缓冲区 */ toHoleId: string | null; /** 是否直接入孔(true = 直接匹配;false = 先入缓冲再匹配) */ directMatch: boolean; }; /** 缓冲区自动匹配结果 */ export type BufferAutoMatch = { screwId: string; toHoleId: string; }; /** 零件释放信息(用于驱动下落动画) */ export type ReleasedItem = { itemId: string; layer: number; }; /** 重力压缩:上方零件下移 */ export type FallMove = { itemId: string; fromLayer: number; toLayer: number; }; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 必须导出的函数 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // ─── 初始化 ────────────────────────────────────────────────────────────────── /** * init:根据配置初始化游戏状态 */ export declare function init(config: ScrewPuzzleConfig): ScrewPuzzleState; // ─── 一体化接口(测试/AI 模拟用) ─────────────────────────────────────────── /** * dispatch:接收动作,返回新状态(纯函数,不得修改原 state) * - remove_screw:移除螺丝,触发匹配、零件释放、重力(一步到位) * - reset:重置到初始状态 * * ⚠️ 仅用于无头测试和 AI 模拟。渲染层请使用下方分步函数。 */ export declare function dispatch(state: ScrewPuzzleState, action: ScrewPuzzleAction): ScrewPuzzleState; /** * getState:返回当前状态快照 */ export declare function getState(state: ScrewPuzzleState): ScrewPuzzleState; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 分步函数(渲染层/场景层必须使用这些函数驱动动画) // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ /** * canRemoveScrew:检查指定螺丝是否可以被拆除 * - 螺丝必须存在且当前插在某螺孔中(不在缓冲区) * - 游戏未结束 * * 场景层在玩家点击时调用:false → 播放禁止/摇晃提示 */ export declare function canRemoveScrew(state: ScrewPuzzleState, screwId: string): boolean; /** * removeScrew:执行螺丝拆除操作 * 返回更新后的状态及螺丝移动轨迹(含缓冲区自动匹配结果) * * 场景层根据 screwMove 和 bufferAutoMatches 分别播放: * - 螺丝旋转拔出动画 * - 螺丝飞向目标螺孔或飞入缓冲区动画 * - 缓冲区螺丝自动飞入匹配螺孔动画 */ export declare function removeScrew( state: ScrewPuzzleState, screwId: string, ): { newState: ScrewPuzzleState; screwMove: ScrewMove; bufferAutoMatches: BufferAutoMatch[]; overflowed: boolean; }; /** * checkItemRelease:检查哪些零件在当前状态下满足释放条件(所有螺丝均已离开螺孔) * 返回待释放零件列表 * * 场景层根据 ReleasedItem[] 播放零件下落动画 */ export declare function checkItemRelease( state: ScrewPuzzleState, changedItemIds?: string[], ): ReleasedItem[]; /** * applyGravity:在若干零件释放后,计算上方零件向下压缩的位移 * 返回需要移动的零件列表 * * 场景层根据 FallMove[] 播放零件向下移动动画 */ export declare function applyGravity(state: ScrewPuzzleState): FallMove[]; /** * findValidMoves:返回当前所有合法可拆螺丝的 id 列表 * 场景层可用此函数高亮可操作螺丝(引导提示) * 若返回空数组且游戏未结束,则为死锁 */ export declare function findValidMoves(state: ScrewPuzzleState): string[];