---
name: level_solvability_validator.aivalidator
description: 关卡可解性验证器。验证箭头推出三消关卡数据的正确性：无格子冲突、无推出阻挡（或存在合法序列）、颜色分组约束、篮子不溢出。纯逻辑，可在构建时或运行时调用。
triggers: 需要验证关卡数据正确性、检查可解性、调试关卡设计时触发。
---

# 关卡可解性验证器（Level Solvability Validator）

## 说明

验证 `arrow_pick_match` 玩法的关卡数据，确保：

1. **无格子冲突**：任意两条路径不共享格子
2. **推出可达**：每条路径到边界方向上无其他路径占据（或存在合法序列）
3. **颜色约束**：每种颜色恰好 matchCount(3) 条路径
4. **篮子不溢出**：存在一个推出顺序使篮子永不超过 capacity

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|------|
| `src/game/logic/LevelValidator.ts` | `ref/LevelValidator.ts` | 验证器 |

## 关键接口

```typescript
interface ValidationResult {
  valid: boolean;
  errors: string[];
  warnings: string[];
}

class LevelValidator {
  static validate(level: ParsedLevel, matchCount?: number, trayCapacity?: number): ValidationResult;
  static checkNoOverlap(level: ParsedLevel): string[];
  static checkAllUnblocked(level: ParsedLevel): string[];
  static checkColorConstraint(level: ParsedLevel, matchCount: number): string[];
  static checkSolvability(level: ParsedLevel, matchCount: number, trayCapacity: number): string[];
}
```

## Recipe

| 决策 | 原因 |
|------|------|
| **静态方法类** | 验证器是无状态纯函数，不需要实例化；静态方法使调用更简洁，且允许独立调用单项检查 |
| **与 level_data_validator 分离** | `level_data_validator` 检查格式正确性（适用所有玩法），本 skill 检查 arrow_pick_match 的玩法可解性（特定玩法约束）；分离后非此玩法的 Remix 不需要加载本 skill |
| **支持构建时和运行时两个调用点** | 构建时批量验证关卡包；运行时在加载关卡时即时校验；同一个 `validate()` 函数满足两个场景 |

## Adapter

- **Role**: `levelSolvabilityValidator` — Arrow pick-match 玩法关卡可解性验证器
- **Provides**: `LevelValidator` 类（`validate()`、`checkNoOverlap()`、`checkAllUnblocked()`、`checkColorConstraint()`、`checkSolvability()`），`ValidationResult` 类型
- **Requires**: `arrow_path_data_format.aicomponent`（ParsedLevel 类型）
- **Consumed by**: `gameplay_unit_test.aivalidator`（集成可解性测试）；Agent 在生成新关卡数据后调用验证
- **Integration point**: `src/game/logic/LevelValidator.ts` —— 构建时批量验证 `LEVELS` 数组，或运行时关卡加载前验证

## Imports

- `arrow_path_data_format.aicomponent`（硬依赖：ParsedLevel 类型）

## 使用方式

```typescript
// 构建时验证
import { LevelValidator } from "./logic/LevelValidator";
for (const raw of LEVELS) {
  const level = parseLevelJson(raw);
  const result = LevelValidator.validate(level);
  if (!result.valid) {
    console.error(`Level ${level.index} invalid:`, result.errors);
  }
}
```
