/** * block_puzzle.aigameplay — reducer 接口模板 * * Agent 生成实际 reducer 时,必须导出以下函数。 * 此文件是接口约束模板,不是可执行代码。 * * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ * ⚠️ 重要:渲染层(GameScene)不应直接调用 dispatch() * * dispatch() 是一体化接口,内部完成放置、消行、生成全流程后 * 只返回最终状态,中间过程(哪些行被消除、哪些格子是新放置的)丢失。 * * 渲染层需要分步动画(放置落地 → 消行闪光 → 方块消失), * 因此必须使用下方的「分步函数」逐步驱动,每步之间插入动画。 * * dispatch() 的用途:无头测试、AI 模拟、自动求解等场景。 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ // ─── 配置类型 ───────────────────────────────────────────────────────────────── export type BlockPuzzleConfig = { /** 棋盘列数,默认 10 */ cols: number; /** 棋盘行数,默认 10 */ rows: number; /** 候选方块槽位数量,默认 3 */ pieceSlots: number; /** 方块颜色数量,默认 5 */ colorCount: number; /** 是否允许旋转,默认 false */ rotation: boolean; /** 每行/列消除基础分,默认 100 */ scorePerLine: number; /** 同时消除多行/列的倍率,默认 1.5 */ multiLineBonusMultiplier: number; }; // ─── 动作类型 ───────────────────────────────────────────────────────────────── export type BlockPuzzleAction = | { type: 'place'; pieceIndex: number; position: { col: number; row: number } } | { type: 'reset' }; // ─── 状态类型 ───────────────────────────────────────────────────────────────── /** 棋盘单格,null 表示空,number 表示颜色 ID */ export type BoardCell = number | null; /** 方块形状:相对于锚点(左上角)的格子偏移集合 */ export type PieceShape = Array<{ dc: number; dr: number }>; /** 候选方块 */ export type Piece = { id: number; cells: PieceShape; color: number; }; export type BlockPuzzleState = { /** 棋盘,board[col][row] */ board: BoardCell[][]; /** 当前 3 个(或更多)候选方块,null 表示已使用的槽位 */ pieceQueue: (Piece | null)[]; /** 当前得分 */ score: number; /** 游戏是否结束 */ gameOver: boolean; }; // ─── 分步操作返回类型 ───────────────────────────────────────────────────────── /** 放置方块的结果 */ export type PlaceResult = { /** 被放置的格子坐标列表 */ placedCells: Array<{ col: number; row: number; color: number }>; /** 新状态(放置后,消行前) */ newState: BlockPuzzleState; }; /** 消行结果 */ export type ClearResult = { /** 被消除的行索引列表 */ clearedRows: number[]; /** 被消除的列索引列表 */ clearedCols: number[]; /** 被消除的格子坐标集合(用于动画) */ clearedCells: Array<{ col: number; row: number }>; /** 本次消除获得的分数 */ score: number; /** 新状态 */ newState: BlockPuzzleState; }; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 必须导出的函数 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // ─── 初始化 ────────────────────────────────────────────────────────────────── /** * init:根据配置初始化游戏状态 * - 创建空棋盘 * - 生成初始 pieceSlots 个候选方块 */ export declare function init(config: BlockPuzzleConfig): BlockPuzzleState; // ─── 一体化接口(测试/AI 模拟用) ─────────────────────────────────────────── /** * dispatch:接收动作,返回新状态(纯函数,不得修改原 state) * - place:放置方块到指定位置,消行,更新候选 * - reset:重置到初始状态 * * ⚠️ 仅用于无头测试和 AI 模拟。渲染层请使用下方分步函数。 */ export declare function dispatch(state: BlockPuzzleState, action: BlockPuzzleAction): BlockPuzzleState; /** * getState:返回当前状态快照 */ export declare function getState(state: BlockPuzzleState): BlockPuzzleState; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 分步函数(渲染层/场景层必须使用这些函数驱动动画) // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ /** * canPlacePiece:检测方块是否可以放置到指定位置 * * 合法条件: * 1. 方块所有格子都在棋盘边界内 * 2. 方块所有格子对应的棋盘位置均为空 * * 场景层在拖拽过程中实时调用,用于高亮可放置区域。 */ export declare function canPlacePiece( state: BlockPuzzleState, piece: Piece, position: { col: number; row: number }, ): boolean; /** * placePiece:将方块放置到棋盘(不做合法性验证,调用前请先确认 canPlacePiece) * * 场景层在放置确认后调用,播放落地动画。 * 不执行消行逻辑,消行由 clearLines 单独处理。 */ export declare function placePiece( state: BlockPuzzleState, piece: Piece, position: { col: number; row: number }, ): PlaceResult; /** * clearLines:检测并消除所有完整的行和列 * * 同一次放置可能同时触发多行/多列消除,返回完整的消除信息。 * 场景层在放置落地动画结束后调用,播放消除闪光动画。 */ export declare function clearLines(state: BlockPuzzleState): ClearResult; /** * generatePieces:生成指定数量的随机方块 * * 当所有槽位的方块都用完(pieceQueue 全为 null)时调用。 * 场景层在获得新方块后播放方块滑入候选区动画。 */ export declare function generatePieces( count: number, colorCount: number, ): Piece[]; /** * canPlaceAnywhere:检测某个方块是否能放置在棋盘的任意位置 * * 场景层在每次放置后检测,若所有候选方块都无法放置则触发游戏结束。 */ export declare function canPlaceAnywhere( state: BlockPuzzleState, piece: Piece, ): boolean;