{
  "_comment": "PGS (PlayCraft Gameplay Schema) 参考骨架 - 点击连通区消除玩法。Agent 以此为起点编写或 fork 玩法规则。",
  "version": "1.0",
  "gameplayType": "tap_blast",
  "entities": {
    "board": {
      "type": "grid",
      "cols": 8,
      "rows": 8,
      "description": "游戏棋盘，默认 8×8 格子"
    },
    "tile": {
      "type": "cell-item",
      "colorCount": 5,
      "description": "棋盘格子上的彩色方块，共 5 种颜色"
    },
    "score": {
      "type": "counter",
      "initial": 0,
      "description": "当前得分"
    },
    "moves": {
      "type": "counter",
      "initial": 30,
      "description": "剩余步数（由 config 覆盖）"
    },
    "goalScore": {
      "type": "target",
      "description": "目标分数，达到后胜利（由 config.level 覆盖）"
    }
  },
  "rules": {
    "tap_connected_region": {
      "description": "玩家点击一个格子，通过 BFS/DFS 找到所有相邻同色连通格子。若连通区大小 ≥ minConnectedCount 则全部消除",
      "algorithm": "flood_fill",
      "connectivity": "orthogonal",
      "minConnectedCount": 2,
      "rejectIfTooSmall": true
    },
    "score_multiplier": {
      "description": "消除格子越多，分数倍率越高",
      "baseScorePerTile": 30,
      "multiplierThresholds": [
        { "count": 2,  "multiplier": 1,  "description": "2-3 格：×1 倍" },
        { "count": 4,  "multiplier": 2,  "description": "4-6 格：×2 倍" },
        { "count": 7,  "multiplier": 3,  "description": "7-9 格：×3 倍" },
        { "count": 10, "multiplier": 5,  "description": "10+ 格：×5 倍" }
      ]
    },
    "gravity": {
      "description": "消除后，上方格子逐列向下坠落填充空位",
      "direction": "down",
      "mode": "column_by_column"
    },
    "refill": {
      "description": "重力下落后，顶部空位补充随机颜色的新格子",
      "from": "top",
      "distribution": "uniform"
    }
  },
  "algorithm": {
    "description": "主循环：tap → flood-fill → remove → gravity → refill → win/lose 检测",
    "steps": [
      "1. 玩家点击某个格子 (col, row)",
      "2. BFS/DFS 找到该格子所在的同色连通区（findConnectedRegion）",
      "3. 若连通区大小 < minConnectedCount，拒绝并提示（不消耗步数）",
      "4. 消除连通区所有格子（removeTiles），steps - 1，计算得分（含倍率）",
      "5. 执行重力：每列中空格上方的格子向下补位（applyGravity）",
      "6. 顶部补充新的随机格子（refillBoard）",
      "7. 检测胜败条件：steps 归零？score 达标？"
    ]
  },
  "winCondition": {
    "type": "score_goal",
    "description": "在 moves 耗尽前达到目标分数（由 config.goalScore 定义）"
  },
  "loseCondition": {
    "type": "moves_exhausted_without_goal",
    "description": "moves 归零且 score < goalScore"
  },
  "testCases": [
    {
      "id": "tc_basic_tap_eliminate",
      "description": "基础消除：点击连通区 ≥2，消除成功，步数 -1",
      "initialState": {
        "board": [
          [1, 1, 1, 2, 2, 2, 3, 3],
          [1, 2, 3, 2, 1, 3, 2, 1],
          [3, 3, 2, 1, 2, 1, 3, 2],
          [2, 1, 1, 3, 3, 2, 1, 3],
          [1, 3, 2, 1, 2, 3, 2, 1],
          [3, 2, 1, 2, 1, 1, 3, 2],
          [2, 1, 3, 3, 2, 2, 1, 3],
          [1, 2, 2, 1, 3, 1, 2, 3]
        ],
        "score": 0,
        "moves": 20
      },
      "action": { "type": "tap", "col": 0, "row": 0 },
      "expectedState": {
        "eliminatedCount": { "min": 2 },
        "scoreGained": { "min": 60 },
        "movesLeft": 19,
        "gravityApplied": true,
        "boardRefilled": true
      }
    },
    {
      "id": "tc_invalid_tap_isolated",
      "description": "无效点击：孤立格子，连通区仅 1 格，不消除，不扣步数",
      "initialState": {
        "board": [
          [1, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3]
        ],
        "score": 100,
        "moves": 10
      },
      "action": { "type": "tap", "col": 0, "row": 0 },
      "expectedState": {
        "eliminatedCount": 0,
        "scoreGained": 0,
        "movesLeft": 10,
        "tapRejected": true
      }
    },
    {
      "id": "tc_score_multiplier",
      "description": "大连通区消除：≥10 格，触发 ×5 倍率",
      "initialState": {
        "board": [
          [1, 1, 1, 1, 1, 2, 3, 2],
          [1, 1, 1, 1, 1, 3, 2, 3],
          [1, 1, 2, 3, 2, 1, 3, 2],
          [2, 3, 2, 1, 3, 2, 1, 3],
          [3, 2, 3, 2, 1, 3, 2, 1],
          [2, 3, 2, 3, 2, 1, 3, 2],
          [3, 2, 3, 2, 3, 2, 1, 3],
          [2, 3, 2, 3, 2, 3, 2, 1]
        ],
        "score": 0,
        "moves": 15
      },
      "action": { "type": "tap", "col": 0, "row": 0 },
      "expectedState": {
        "eliminatedCount": { "min": 10 },
        "scoreGained": { "min": 1500 },
        "multiplierApplied": 5,
        "movesLeft": 14
      }
    },
    {
      "id": "tc_win_condition",
      "description": "胜利：本次消除后得分达到目标",
      "initialState": {
        "board": [
          [2, 2, 2, 2, 3, 1, 3, 1],
          [2, 2, 2, 3, 1, 3, 1, 3],
          [3, 1, 3, 1, 3, 1, 3, 1],
          [1, 3, 1, 3, 1, 3, 1, 3],
          [3, 1, 3, 1, 3, 1, 3, 1],
          [1, 3, 1, 3, 1, 3, 1, 3],
          [3, 1, 3, 1, 3, 1, 3, 1],
          [1, 3, 1, 3, 1, 3, 1, 3]
        ],
        "score": 900,
        "goalScore": 1000,
        "moves": 5
      },
      "action": { "type": "tap", "col": 0, "row": 0 },
      "expectedState": {
        "win": true,
        "score": { "min": 1000 }
      }
    },
    {
      "id": "tc_lose_condition",
      "description": "失败：最后一步消除后步数归零，分数未达标",
      "initialState": {
        "board": [
          [1, 1, 3, 2, 3, 2, 3, 2],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2],
          [2, 3, 2, 3, 2, 3, 2, 3],
          [3, 2, 3, 2, 3, 2, 3, 2]
        ],
        "score": 400,
        "goalScore": 1000,
        "moves": 1
      },
      "action": { "type": "tap", "col": 0, "row": 0 },
      "expectedState": {
        "movesLeft": 0,
        "win": false,
        "gameOver": true
      }
    }
  ]
}
