---
name: grid_board_layout.aicomponent
description: 格子棋盘布局计算器。根据关卡的行列数和屏幕尺寸计算最优格子大小、棋盘位置和缩放/拖拽边界约束。
triggers: 需要在屏幕上布局可变尺寸的格子棋盘、计算格子坐标或实现棋盘缩放/拖拽时触发。
---

# 格子棋盘布局（Grid Board Layout）

## 说明

**布局系数**：棋盘可用区域、cell 尺寸与边距须与 **`responsive_2d_layout.aicomponent` 第一节（Layout Canon）** 一致——使用同一套 \(W_r, H_r\)、**uiScale / vScale**，不得在棋盘模块内单独发明一套缩放比。

**纵向扣减**：顶栏 / 底栏预留高度与 **`playable_hud_layout.aicomponent`** 合同一致（`H_mid = H_r - H_top - H_bottom`）。

**职责边界**：本 skill 只做「在已给定可用矩形内的格子几何」；顶栏/底栏预留高度若来自设计稿 dp，通过 **vScale**（或 Canon 规定的等价方式）换算，与全局 UI 对齐。

`BoardLayout` 负责将 `rows × cols` 的棋盘正确布局在屏幕内：

- 根据屏幕可用高度（减去 UI 条）和 `rows × cols` 计算最优 `cellSize`
- 应用 `CELL_SPACING_MULTIPLIER`（默认 1.15）放大格子间距，提升点击体验
- 计算 `boardOffsetX / boardOffsetY`（棋盘左上角坐标）
- 计算缩放/拖拽的边界约束（`minZoom / maxZoom / panBounds`）

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|-----|
| `src/game/scenes/GameUI/BoardLayout.ts` | `ref/BoardLayout.ts` | 棋盘布局计算 |

## Imports

- `phaser.aicomponent`（硬依赖）
- `responsive_2d_layout.aicomponent`（硬依赖：屏幕尺寸参数）

## Skill Definition

```yaml
tools:
  - read_file
  - write_file
inputs:
  - source: src/game/scenes/GameUI/BoardLayout.ts
outputs:
  - boardLayout: computeBoardLayout() + BoardLayout module
```

## Recipe

| 决策 | 原因 |
|------|------|
| **纯计算，无渲染** | `computeBoardLayout()` 是纯函数，输入为行列数+屏幕尺寸，输出为几何参数；渲染器（PathRenderer/InputHandler）依赖此数据，反向依赖会造成循环 |
| **遵从 Layout Canon** | cellSize 和偏移量必须使用 `uiScale/vScale` 换算，不得另起一套缩放；保证棋盘与 UI 坐标系一致 |
| **CELL_SPACING_MULTIPLIER 放大格子间距** | 实际格子稍小于 cellSize，留出视觉间距和点击余量；1.15 是试玩广告实践中手感较好的值 |

## Adapter

- **Role**: `gridBoardLayout` — 可变尺寸格子棋盘的几何布局计算器
- **Provides**: `computeBoardLayout()` 函数、`BoardLayout` 类型（cellSize、boardOffsetX/Y、minZoom、maxZoom、panBounds）
- **Requires**: `phaser.aicomponent`、`responsive_2d_layout.aicomponent`（屏幕尺寸参数，确保坐标系一致）
- **Consumed by**: `game_scene.aicomponent`（初始化棋盘几何）、`path_renderer.aicomponent`（格子像素坐标）、`path_input_handler.aicomponent`（命中检测）、`debug_overlay.aicomponent`（格子坐标可视化）
- **Integration point**: `src/game/scenes/GameUI/BoardLayout.ts` → `Game.ts` 在 `create()` 中调用 `computeBoardLayout()` 并缓存结果

## 使用示例

```typescript
const layout = computeBoardLayout({
  rows: level.rows,
  cols: level.cols,
  screenWidth: width,
  screenHeight: height,
  topUIHeight: GAME_TOP_UI_BAR_HEIGHT,
});

this.cellSize    = layout.cellSize;
this.boardOffsetX = layout.boardOffsetX;
this.boardOffsetY = layout.boardOffsetY;

// 格子中心坐标
cellCenter(col: number, row: number) {
  return {
    x: this.boardOffsetX + col * this.cellWidth + this.cellWidth / 2,
    y: this.boardOffsetY + row * this.cellHeight + this.cellHeight / 2,
  };
}
```
