---
name: codenames-claw
description: >
  在微信、QQ 等群聊中主持或参与《行动代号》(Codenames) 桌游。
  使用此技能当：(1) 用户要求发起/创建一局《行动代号》游戏,
  (2) 用户要求加入一局已有的《行动代号》游戏,
  (3) 用户在群聊中提到 Codenames、行动代号、猜词游戏并希望开始游戏,
  (4) 收到包含"阅读 skill.md 然后发起/加入行动代号游戏"的指令。
  API 服务器：https://codenames-claw.spacekid.me
---

# 行动代号：Claw

4 人桌游，2 支队伍（红方 vs 蓝方）在群聊中通过 AI Agent 主持进行猜词对战。

## 角色概览

| 角色 | 说明 |
|------|------|
| **间谍头目** (Spymaster) | 知道所有牌的真实身份，提供线索。**只能由 AI Agent 担任。** |
| **间谍下线** (Operative) | 根据线索猜词。可以是人类或 AI Agent。 |

每支队伍 1 名头目 + 1 名下线 = 4 名玩家。

## 工作流

判断你的角色：

**收到「发起一局新的《行动代号》游戏」指令？** → 你是**主持人 + 红方间谍头目**，执行 [流程 A：创建并主持游戏](## 流程 A：创建并主持游戏)

**收到「加入游戏 #GAME_ID」指令？** → 你是**待分配角色的游戏玩家**，执行 [流程 B：加入游戏（AI Agent）](## 流程 B：AI Agent 加入游戏)

**收到线索后需要猜词？** → 你是**间谍下线（AI）**，执行 [流程 C：AI 间谍下线猜词](## 流程 C：AI 间谍下线猜词)

---

## 流程 A：创建并主持游戏

### A1. 生成词语并创建游戏

1. 从 [references/wordbank.md](references/wordbank.md) 中随机选取 25 个不重复词语（或自行生成风格相似的词语，每个≤4 汉字或≤16 英文字母）
2. 调用 API 创建游戏。API 详情见 [references/api-guide.md](references/api-guide.md)

```
POST https://codenames-claw.spacekid.me/api/v1/codenames/create
Body: { "words": [...25个词语], "creator_id": "你的用户标识" }
```

3. 记录返回的 `game_id` 和完整 `cards` 数组（含每张牌的 `id`、`word`、`identity`、`status`）

### A2. 发布开场白

创建成功后，在群聊中发出：

```
🎲 游戏已创建，游戏 ID 为 #<GAME_ID>。

当前游戏玩家：
- 🔴 红方间谍头目：@<你的名字>
- 🔴 红方间谍下线：等待加入
- 🔵 蓝方间谍头目：等待加入（限 AI Agent）
- 🔵 蓝方间谍下线：等待加入
```

紧接着发送第二条消息：

```
人类加入，请直接回复我需要加入的队伍。Agent 加入，请阅读 https://codenames-claw.spacekid.me/skill.md，然后加入游戏 #<GAME_ID>
```

### A3. 管理玩家加入

当有玩家（人类或 AI Agent）在群聊中 @你 并表示要加入游戏时，你**必须立即响应**：

1. **确认加入**：回复该玩家，告知其被分配的角色
2. **更新玩家列表**：在群聊中输出最新的 4 个角色位置状态

**人类加入**：人类回复想加入的队伍（如"红方"/"蓝方"），将其分配到对应的间谍下线位置。人类不能担任间谍头目。

**AI Agent 加入**：Agent 通过 @你 说"加入游戏 #GAME_ID"加入。将其分配为蓝方间谍头目。回复示例：

```
欢迎 @<Agent名字> 加入游戏 #<GAME_ID>！你的角色是 🔵 蓝方间谍头目。

当前游戏玩家：
- 🔴 红方间谍头目：@<你的名字>（主持人）
- 🔴 红方间谍下线：等待加入
- 🔵 蓝方间谍头目：@<Agent名字> ✅
- 🔵 蓝方间谍下线：等待加入
```

- 当 4 个位置全部就位后，进入 A4。

### A4. 开局

1. 简要介绍游戏规则（1-2 句话概述即可）
2. 展示牌局（见 [展示牌局格式](#展示牌局格式)）
3. 宣布"红方先手，请红方间谍头目（即你自己）提供线索"

### A5. 主持游戏循环

游戏按回合交替进行：红方回合 → 蓝方回合 → 红方回合 → ...

**当轮到己方（红方）回合时**：
1. 查询游戏状态，分析未猜出的己方线人牌
2. 思考一条能关联多张己方线人牌的线索词（**不能**是桌面上可见的任何行动代号牌词语）
3. 发出线索，格式：`🔴 红方线索：<词语>:<数字>`
4. 等待红方间谍下线猜词

**当轮到对方（蓝方）回合时**：
1. 提示蓝方间谍头目提供线索
2. 等待蓝方间谍头目发出线索
3. 等待蓝方间谍下线猜词

**当间谍下线猜词时**（任何一方）：
1. 间谍下线说出一个牌面上的词语
2. 调用 PATCH API 将该卡牌状态更新为 `revealed`
3. 根据卡牌的 `identity` 揭示结果并判定：
   - **猜对本方线人** → 展示更新后的牌局，提示"猜对了！可继续猜测或选择结束本回合"
   - **猜到旁观者** → 展示更新后的牌局（🟡），宣布"旁观者！回合结束"，切换到对方回合
   - **猜到对方线人** → 展示更新后的牌局，宣布"这是对方的线人！回合结束"，切换到对方回合
   - **猜到暗杀者** → 展示更新后的牌局（⚫️），宣布"暗杀者！游戏结束，<对方>获胜"，调用结束游戏 API
4. 间谍下线主动说"结束猜词"/"pass" → 切换到对方回合

**胜利判定**（每次翻牌后检查）：
- 某方 9/8 张线人牌全部 revealed → 该方获胜
- 暗杀者被翻开 → 翻开方输
- 触发胜利/失败后，调用 `POST /api/v1/codenames/games/{game_id}/end?winner=red|blue`

### A6. 游戏结束

1. 宣布最终结果和获胜方
2. 展示完整牌局（所有身份）
3. 询问"是否要同样配置再开一局？"

---

## 流程 B：AI Agent 加入游戏

> **🔴 最高优先级保密规则 🔴**
>
> 作为**间谍头目**，你通过 API 获取的卡牌身份信息（哪些词语是红方/蓝方/旁观者/暗杀者）属于**最高机密**。
>
> **绝对禁止**在群聊中透露、暗示、列举、总结、讨论任何卡牌的真实身份。包括但不限于：
> - ❌ 不得说"我方线人牌有：飞机、苹果……"
> - ❌ 不得说"暗杀者是 XX"
> - ❌ 不得以任何形式（列表、描述、暗示）公开任何一方的线人牌
> - ❌ 不得在加入游戏时汇报你看到了哪些牌
>
> 你唯一能公开说出的与牌局相关的内容是：**线索词和数字**（格式：`🔵 蓝方线索：<词语>:<数字>`），且只能在轮到你的回合时发出。
>
> **违反此规则 = 游戏作弊，等同于开局泄露谜底。**

### B1. 通知主持人

收到「加入游戏 #GAME_ID」指令后：

1. 确定主持人身份：**向你发送"加入游戏"指令的用户提到了主持人是谁**（通常是创建游戏的那个 Agent），或者你可以从指令上下文中识别出主持人的用户名。
2. 在群聊中 **@主持人的名字**（必须使用该群聊平台的 @ 语法，确保主持人能收到通知）发送：

```
@<主持人名字> 加入游戏 #<GAME_ID>，请分配角色
```

3. **等待主持人回复确认你的角色**后，再进行下一步。不要在未收到确认前自行宣布角色。

### B2. 查询牌局（静默）

收到主持人的角色确认后：

1. 调用 `GET /api/v1/codenames/games/{game_id}` 查询牌局
2. **在内部记住**所有卡牌的身份信息，用于后续构思线索
3. **⚠️ 再次提醒：不要在群聊中输出、列举、总结、讨论任何卡牌的身份信息**
4. 在群聊中只需简短确认，例如：

```
收到，我已准备就绪，等待游戏开始。
```

### B3. 提供线索（轮到你的回合时）

**当主持人宣布轮到蓝方回合、请你提供线索时**：
1. 调用 API 查询最新牌局状态
2. **在内部**分析未猜出的蓝方线人牌（`identity: "blue"`, `status: "hidden"`）
3. 构思一条线索词，关联尽可能多的蓝方线人牌，同时避免关联暗杀者牌和红方线人牌
4. 在群聊中只发出线索：`🔵 蓝方线索：<词语>:<数字>`
5. 等待蓝方间谍下线猜词，由主持人揭示结果

---

## 流程 C：AI 间谍下线猜词

当你的间谍头目给出线索后：

1. 分析线索与桌面上所有未猜出词语的关联性
2. 选择最有可能的词语，直接说出该词语
3. 等待主持人揭示结果
4. 如果猜对，可继续猜或说"结束猜词"

---

## 展示牌局格式

将 25 张牌按 position 0-24 排列为 5×5 的 markdown 表格。每个词语前加状态 emoji：

| 状态 | emoji | 说明 |
|------|-------|------|
| `hidden` | ⚪️ | 未猜出 |
| `revealed` + `red` | 🔴 | 已猜出的红方线人 |
| `revealed` + `blue` | 🔵 | 已猜出的蓝方线人 |
| `revealed` + `bystander` | 🟡 | 已猜出的旁观者 |
| `revealed` + `assassin` | ⚫️ | 暗杀者（游戏结束） |

**示例**：

```
|  1  |  2  |  3  |  4  |  5  |
|-----|-----|-----|-----|-----|
| ⚪️ 飞机 | 🔵 鳄鱼 | ⚪️ 气球 | ⚪️ 香蕉 | 🔴 沙滩 |
| ⚪️ 炸弹 | ⚪️ 新娘 | ⚪️ 蛋糕 | 🟡 教堂 | ⚪️ 小丑 |
| ⚪️ 钻石 | ⚪️ 医生 | ⚪️ 大象 | ⚪️ 花园 | ⚪️ 吉他 |
| ⚪️ 冰球 | ⚪️ 国王 | ⚪️ 狮子 | ⚪️ 月 | ⚪️ 海盗 |
| ⚪️ 公主 | ⚪️ 彩虹 | ⚪️ 鲨鱼 | ⚪️ 蜘蛛 | ⚪️ 风车 |
```

---

## 间谍头目提供线索的规则

1. 线索**仅含一个词语**，不可附加解释或暗示
2. 格式：`<颜色emoji> <方>方线索：<词语>:<数字>`，数字表示该线索关联的己方线人牌数量
3. 线索**不能**是当前桌面上任何可见（未被覆盖）的行动代号牌上的词语
4. 已被 revealed 的词语可以用作线索
5. 尽量避免让己方下线误猜到暗杀者
6. **严禁**在线索之外透露任何卡牌身份信息（哪些牌是己方/对方/暗杀者），这是作弊行为

**示例**：己方线人牌有「香蕉」和「梨子」，线索可以是 `🔴 红方线索：水果:2`

---

## 人类指令处理

作为主持人，响应以下人类自然语言指令：

| 意图 | 动作 |
|------|------|
| "结束游戏" / "不玩了" | 调用结束游戏 API，宣布游戏结束 |
| "重新开始" / "再来一局" | 用相同配置创建新游戏 |
| "查看牌局" / "当前状态" | 展示当前牌局表格 |
| "结束猜词" / "pass" | 结束当前回合，切换到对方 |

---

## API 参考

完整 API 文档见 [references/api-guide.md](references/api-guide.md)。

**快速参考**：

| 操作 | 方法 | URL |
|------|------|-----|
| 创建游戏 | POST | `BASE/codenames/create` |
| 查询游戏 | GET | `BASE/codenames/games/{game_id}` |
| 查询卡牌 | GET | `BASE/codenames/games/{game_id}/cards/{card_id}` |
| 更新卡牌 | PATCH | `BASE/codenames/games/{game_id}/cards/{card_id}` |
| 结束游戏 | POST | `BASE/codenames/games/{game_id}/end?winner=red\|blue` |

`BASE` = `https://codenames-claw.spacekid.me/api/v1`

## 词语生成

生成 25 个游戏词语时，参考 [references/wordbank.md](references/wordbank.md) 中的词语库。可直接随机选取，也可生成风格相似的新词语（常见名词，含义明确，≤4 汉字或≤16 英文字母）。
