/** * tap_blast.aigameplay — reducer 接口模板 * * Agent 生成实际 reducer 时,必须导出以下函数。 * 此文件是接口约束模板,不是可执行代码。 * * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ * ⚠️ 重要:渲染层(GameScene)不应直接调用 dispatch() * * dispatch() 是一体化接口,内部跑完整个 tap → remove → gravity → refill * 流程后只返回最终状态,中间过程(哪些格子被消除、哪些格子下落了、 * 新补充了什么)全部丢失。 * * 渲染层需要分步动画(消除爆炸 → 下落 Tween → 顶部补充滑入), * 因此必须使用下方的「分步函数」逐步驱动,每步之间插入 Tween 动画。 * * dispatch() 的用途:无头测试、AI 模拟、快速跳过动画等场景。 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ // ─── 配置类型 ───────────────────────────────────────────────────────────────── export type TapBlastConfig = { /** 棋盘列数,默认 8 */ cols: number; /** 棋盘行数,默认 8 */ rows: number; /** 格子颜色数量,默认 5 */ colorCount: number; /** 消除连通区的最小格子数,默认 2 */ minConnectedCount: number; /** 游戏模式:限步数或限时 */ mode: 'moves' | 'timer'; /** 初始步数(mode='moves' 时有效) */ initialMoves?: number; /** 倒计时秒数(mode='timer' 时有效) */ timeLimitSeconds?: number; /** 目标分数 */ goalScore: number; /** 每格基础得分 */ baseScorePerTile: number; }; // ─── 动作类型 ───────────────────────────────────────────────────────────────── export type TapBlastAction = | { type: 'tap'; col: number; row: number } | { type: 'tick'; deltaMs: number } // 倒计时模式下每帧调用 | { type: 'reset' }; // ─── 状态类型 ───────────────────────────────────────────────────────────────── /** 格子颜色,0 ~ colorCount-1,null 表示空格 */ export type TileColor = number | null; export type TapBlastState = { /** 棋盘格子,board[col][row],0 = 顶部,rows-1 = 底部 */ board: TileColor[][]; /** 当前得分 */ score: number; /** 剩余步数(moves 模式) */ movesLeft: number; /** 剩余时间(毫秒,timer 模式) */ timeLeftMs?: number; /** 游戏是否结束 */ gameOver: boolean; /** 是否胜利 */ win: boolean; /** 上一次 tap 是否因连通区太小被拒绝 */ lastTapRejected: boolean; }; // ─── 分步操作返回类型 ───────────────────────────────────────────────────────── /** 格子坐标 */ export type Cell = { col: number; row: number }; /** 重力下落:某格子从 fromRow 下落到 toRow */ export type FallMove = { col: number; fromRow: number; toRow: number; }; /** 新补充的格子 */ export type RefillTile = { col: number; row: number; color: number; }; /** 消除结果 */ export type RemoveResult = { /** 被消除的格子列表 */ removedCells: Cell[]; /** 本次消除获得的得分 */ score: number; /** 得分倍率 */ multiplier: number; }; /** 得分计算结果 */ export type ScoreResult = { score: number; multiplier: number; }; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 必须导出的函数 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // ─── 初始化 ────────────────────────────────────────────────────────────────── /** * init:根据配置初始化游戏状态,随机填满棋盘 */ export declare function init(config: TapBlastConfig): TapBlastState; // ─── 一体化接口(测试/AI 模拟用) ─────────────────────────────────────────── /** * dispatch:接收动作,返回新状态(纯函数,不得修改原 state) * - tap:查找连通区,消除,下落,补充(一步到位) * - tick:更新倒计时(timer 模式) * - reset:重置到初始状态 * * ⚠️ 仅用于无头测试和 AI 模拟。渲染层请使用下方分步函数。 */ export declare function dispatch(state: TapBlastState, action: TapBlastAction): TapBlastState; /** * getState:返回当前状态快照 */ export declare function getState(state: TapBlastState): TapBlastState; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 分步函数(渲染层/场景层必须使用这些函数驱动动画) // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ /** * findConnectedRegion:从 (col, row) 出发进行 BFS/DFS 洪水填充, * 返回所有与该格子同色且正交相连的格子坐标列表。 * * 场景层在鼠标悬停时调用,用于高亮连通区轮廓预览。 * 若返回长度 < config.minConnectedCount,显示红色禁止提示。 */ export declare function findConnectedRegion( board: TileColor[][], col: number, row: number, ): Cell[]; /** * removeTiles:从棋盘移除指定格子列表(置为 null),计算得分 * * 场景层在连通区确认后调用,播放格子爆炸消失动画。 * cells 通常来自 findConnectedRegion 的结果。 */ export declare function removeTiles( state: TapBlastState, cells: Cell[], config: TapBlastConfig, ): RemoveResult; /** * applyGravity:执行重力下落,每列中空格上方的格子向下补位。 * 返回每个移动格子的下落信息。 * * 场景层根据 FallMove[] 对每个格子精灵播放 y-tween 动画。 */ export declare function applyGravity( board: TileColor[][], cols: number, rows: number, ): FallMove[]; /** * refillBoard:从顶部补充随机颜色格子填满空位。 * 返回新补充的格子信息。 * * 场景层根据 RefillTile[] 创建新精灵并从 y=-cellSize 处 tween 滑入。 */ export declare function refillBoard( board: TileColor[][], cols: number, rows: number, colorCount: number, ): RefillTile[]; /** * calculateScore:根据消除格子数量和配置计算得分与倍率 * * 倍率规则(默认): * - 2-3 格:×1 * - 4-6 格:×2 * - 7-9 格:×3 * - 10+ 格:×5 */ export declare function calculateScore( cellCount: number, config: TapBlastConfig, ): ScoreResult;