{
  "_comment": "PGS (PlayCraft Gameplay Schema) 参考骨架 - 单词连线玩法。Agent 以此为起点编写或 fork 玩法规则。",
  "version": "1.0",
  "gameplayType": "word_connect",
  "entities": {
    "grid": {
      "type": "2d-grid",
      "description": "字母网格",
      "fields": {
        "rows": { "type": "number", "default": 5 },
        "cols": { "type": "number", "default": 5 },
        "cells": {
          "type": "cell[][]",
          "description": "二维数组，每个 cell = { letter: string, found: boolean }，found 表示已作为某单词的一部分"
        }
      }
    },
    "wordList": {
      "type": "string[]",
      "description": "目标单词列表（全大写），玩家需要找出其中所有单词"
    },
    "foundWords": {
      "type": "string[]",
      "description": "已找到的单词列表"
    },
    "currentPath": {
      "type": "cell-path",
      "description": "当前正在滑动的路径",
      "fields": {
        "cells": { "type": "array", "item": "{ row: number, col: number }", "description": "路径经过的格子（按顺序）" },
        "letters": { "type": "string", "description": "路径格子组成的字母串（实时更新）" }
      }
    },
    "score": {
      "type": "counter",
      "initial": 0,
      "description": "当前得分，每找到一个单词得 word.length * 10 分"
    },
    "timer": {
      "type": "counter",
      "description": "剩余时间（ms，仅 timedMode=true 时有效）"
    }
  },
  "rules": {
    "start_trace": {
      "description": "玩家按下格子，开始连线路径",
      "effect": "currentPath = { cells: [{ row, col }], letters: grid[row][col].letter }"
    },
    "extend_trace": {
      "description": "玩家滑动到相邻格子，延伸路径",
      "conditions": [
        "目标格子与路径末尾格子相邻（|dr| ≤ 1 && |dc| ≤ 1，不含自身）",
        "目标格子不在 currentPath.cells 中（同一路径不重复使用）"
      ],
      "effect": "currentPath.cells.push({ row, col }); currentPath.letters += grid[row][col].letter"
    },
    "complete_word": {
      "description": "玩家抬起手指，验证当前路径组成的单词",
      "steps": [
        "1. word = currentPath.letters（大写）",
        "2. 若 word.length < minWordLength：视为无效，清除路径",
        "3. 若 word 不在 wordList 中 且不在字典（若配置字典模式）：无效，清除路径",
        "4. 若 word 已在 foundWords 中：无效，清除路径",
        "5. 否则：有效，markWordFound(word, path)"
      ]
    },
    "valid_word_reward": {
      "description": "找到有效单词后奖励",
      "effect": "foundWords.push(word); score += word.length * 10; 对应格子标记 found=true（eliminateFoundLetters 模式下移除并补充）"
    },
    "win_check": {
      "description": "检查是否找到所有目标单词",
      "condition": "foundWords.length >= wordList.length"
    }
  },
  "algorithm": {
    "description": "主流程：trace → validate → reward → win",
    "steps": [
      "1. 玩家触摸格子：startTrace(row, col)",
      "2. 玩家滑动：extendTrace(row, col)，实时检查相邻性和路径唯一性",
      "3. 玩家抬手：completeTrace()",
      "   3a. validateWord(currentPath.letters, wordList)",
      "   3b. 有效：markWordFound(word, path)，更新 score，检查 checkWin()",
      "   3c. 无效：清除 currentPath",
      "4. （计时模式）每帧：timer -= deltaMs，timer ≤ 0 且未胜利则 gameOver"
    ]
  },
  "winCondition": {
    "type": "all_target_words_found",
    "description": "找到 wordList 中的所有单词"
  },
  "loseCondition": {
    "type": "timer_expired",
    "description": "（计时模式）时间耗尽前未找到所有目标单词"
  },
  "testCases": [
    {
      "id": "tc_valid_word_found",
      "description": "找到有效单词：路径拼出 wordList 中的单词，得分增加",
      "initialState": {
        "grid": {
          "rows": 3, "cols": 3,
          "cells": [
            [{ "letter": "C", "found": false }, { "letter": "A", "found": false }, { "letter": "T", "found": false }],
            [{ "letter": "D", "found": false }, { "letter": "O", "found": false }, { "letter": "G", "found": false }],
            [{ "letter": "X", "found": false }, { "letter": "Y", "found": false }, { "letter": "Z", "found": false }]
          ]
        },
        "wordList": ["CAT", "DOG"],
        "foundWords": [],
        "currentPath": { "cells": [], "letters": "" },
        "score": 0
      },
      "actions": [
        { "type": "startTrace", "row": 0, "col": 0 },
        { "type": "extendTrace", "row": 0, "col": 1 },
        { "type": "extendTrace", "row": 0, "col": 2 },
        { "type": "completeTrace" }
      ],
      "expectedState": {
        "foundWords": ["CAT"],
        "score": 30,
        "currentPath.cells.length": 0,
        "win": false
      }
    },
    {
      "id": "tc_invalid_word_rejected",
      "description": "无效单词：路径拼出的字母不在 wordList 中，路径被清除，分数不变",
      "initialState": {
        "grid": {
          "rows": 3, "cols": 3,
          "cells": [
            [{ "letter": "X", "found": false }, { "letter": "Y", "found": false }, { "letter": "Z", "found": false }],
            [{ "letter": "D", "found": false }, { "letter": "O", "found": false }, { "letter": "G", "found": false }],
            [{ "letter": "C", "found": false }, { "letter": "A", "found": false }, { "letter": "T", "found": false }]
          ]
        },
        "wordList": ["CAT", "DOG"],
        "foundWords": [],
        "currentPath": { "cells": [], "letters": "" },
        "score": 10
      },
      "actions": [
        { "type": "startTrace", "row": 0, "col": 0 },
        { "type": "extendTrace", "row": 0, "col": 1 },
        { "type": "extendTrace", "row": 0, "col": 2 },
        { "type": "completeTrace" }
      ],
      "expectedState": {
        "foundWords": [],
        "score": 10,
        "currentPath.cells.length": 0
      }
    },
    {
      "id": "tc_all_words_found_win",
      "description": "全部找到：找到所有目标单词后游戏胜利",
      "initialState": {
        "grid": {
          "rows": 3, "cols": 3,
          "cells": [
            [{ "letter": "C", "found": false }, { "letter": "A", "found": false }, { "letter": "T", "found": false }],
            [{ "letter": "D", "found": false }, { "letter": "O", "found": false }, { "letter": "G", "found": false }],
            [{ "letter": "X", "found": false }, { "letter": "Y", "found": false }, { "letter": "Z", "found": false }]
          ]
        },
        "wordList": ["CAT", "DOG"],
        "foundWords": ["CAT"],
        "currentPath": { "cells": [], "letters": "" },
        "score": 30
      },
      "actions": [
        { "type": "startTrace", "row": 1, "col": 0 },
        { "type": "extendTrace", "row": 1, "col": 1 },
        { "type": "extendTrace", "row": 1, "col": 2 },
        { "type": "completeTrace" }
      ],
      "expectedState": {
        "foundWords": ["CAT", "DOG"],
        "score": 60,
        "win": true,
        "gameOver": false
      }
    },
    {
      "id": "tc_non_adjacent_rejected",
      "description": "非相邻格子：尝试滑向不相邻的格子，路径不延伸",
      "initialState": {
        "grid": {
          "rows": 3, "cols": 3,
          "cells": [
            [{ "letter": "C", "found": false }, { "letter": "A", "found": false }, { "letter": "T", "found": false }],
            [{ "letter": "D", "found": false }, { "letter": "O", "found": false }, { "letter": "G", "found": false }],
            [{ "letter": "X", "found": false }, { "letter": "Y", "found": false }, { "letter": "Z", "found": false }]
          ]
        },
        "wordList": ["CAT"],
        "foundWords": [],
        "currentPath": { "cells": [{ "row": 0, "col": 0 }], "letters": "C" },
        "score": 0
      },
      "actions": [
        { "type": "extendTrace", "row": 2, "col": 2 }
      ],
      "expectedState": {
        "currentPath.cells.length": 1,
        "currentPath.letters": "C"
      }
    }
  ]
}
