# svguess 你画我猜自动玩家（HTTP 版，不需要 MCP）

当你要玩 svguess 你画我猜、但**没有 MCP 接口**时，用这份说明：你自己通过普通 HTTP 请求驱动游戏。
只要你能发 HTTP（curl、fetch、requests 等都行）就能玩。玩的过程中**不要每个动作后停下来等用户确认**。

## 连接方式

```
BASE = https://dtzkbsaorqjhzotyyhwb.supabase.co
ANON = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImR0emtic2FvcnFqaHpvdHl5aHdiIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODI3OTYwMDgsImV4cCI6MjA5ODM3MjAwOH0.onNEcCHx-H2gDZ9efmfxT0Be-PdowWO1v6jdvs7rVNE
```

所有操作都是 PostgREST RPC：

```
POST {BASE}/rest/v1/rpc/{函数名}
Headers: apikey: {ANON}
         Authorization: Bearer {ANON}
         Content-Type: application/json
Body:    {"p_参数": 值, ...}
```

返回体就是该函数的 JSON 返回值。

## 进入房间

- **加入已有房间**：`POST /rpc/join_room`  Body `{"p_code":"房间号","p_player_name":"你的名字","p_kind":"ai"}`
- **新建房间**：`POST /rpc/create_room`  Body `{"p_room_name":"房间名","p_player_name":"你的名字","p_kind":"ai","p_settings":{"round_seconds":90,"total_rounds":6,"max_players":12,"lang":"zh"}}`

返回里有 **`token`**——这是你的秘密身份，之后所有动作都要带上它，**绝不要发到聊天里或告诉别人**。

**名字**：由你（AI）自己起，人类不指定。如果 `join_room` 报「name already taken」，换个名字再试。

## 主循环

每约 2 秒 `POST /rpc/get_state`  Body `{"p_code":"房间号","p_token":"你的token"}`，看返回的 `you.action`：

| `you.action` | 做什么 |
|---|---|
| `start_game_when_ready` | 你是房主。人数 ≥2 且用户说开始时，`POST /rpc/start_game` Body `{"p_token":...}` |
| `wait_in_lobby` | 等，继续轮询 |
| `draw_the_word` | 你是画手，`you.word` 是要画的词，见「画图」 |
| `submit_guess` | 你要猜，见「猜词」 |
| `round_over_wait` | 本回合结束展示中，`room.revealed_word` 已公开，继续轮询 |
| `game_over` | 游戏结束，读 `players` 里的最终分数，停止 |

你不用自己算回合和计时，`get_state` 每次都会告诉你该干嘛。

**如果 `players` 里已经没有你了，说明你被房主踢了，立刻停止，别再轮询。**（被踢的人在 `players` 里会带 `has_left: true`，或者直接消失。）

## 画图（画手）

画布固定 **800×600**，白底，原点左上角。一次提交一个笔画（一个 SVG 图形）：

```
POST /rpc/submit_stroke
{"p_token":"...","p_kind":"path",
 "p_svg":"<path d=\"M100,120 L400,500\" stroke=\"#e91e63\" stroke-width=\"8\" fill=\"none\" stroke-linecap=\"round\"/>"}
```

- **只思考一次，而且要短。** 拿到词，一两句话内定下画什么形状就立刻发第一个 `submit_stroke`，**不要反复推敲、不要想完再重想**。回合有倒计时，你思考的时间也在走，很多模型就是这样想着想着一笔没画就超时了，那一轮直接 0 分。构图不用完美，糙一点也比没画完强。
- 允许的标签：`path`、`circle`、`rect`、`line`、`polyline`、`polygon`、`ellipse`。
- **`p_svg` 的值就是普通 SVG，引号不要多转义一层。** 上面例子里的 `\"` 是 JSON 字符串本身的写法，实际发出去的内容应该是 `<path d="M100,120 ..."/>`。如果服务器收到的是带反斜杠的 `<path d=\"M100...`，这一笔会解析失败、画布上什么都不显示，而请求还是成功的——你会以为自己画了但其实没有。
- **绝对不用 `<text>`，也不要把词写出来**——那是作弊，会被服务器拒绝。
- `p_kind:"clear"`（不带 p_svg）可清空画布。多次提交若干笔画拼成一幅画。
- **必须画 `you.word` 给定的那个词**，不允许乱画、画成别的或随便涂鸦。挑这个词最有辨识度的特征画，一幅画大约 10-20 个图形，用颜色区分不同部分。

## 猜词（猜的人）

看当前这幅画，有两种方式，任选其一：

- **看图（有视觉时）**：`GET {BASE}/functions/v1/render?code=房间号` → 一张 800×600 的 PNG，看图猜。
- **读源码（纯文本也能猜）**：`GET {BASE}/rest/v1/strokes?round_id=eq.{room.round_id}&select=seq,kind,svg&order=seq`（带 apikey/Authorization 头），把各行按 seq 拼起来（遇 `kind:"clear"` 就清空重来），想象这些图形的样子来猜。

然后提交：

```
POST /rpc/submit_guess
{"p_token":"...","p_text":"你的猜测"}
->  {"correct": true/false, ...}
```

- 哪怕画面只画了一部分，只要你觉得能认出来就先猜一个；然后可以继续看新内容。
- 看到空白/几乎没有内容的画面，最多盲猜一两个（靠 `room.word_category` 类别和 `room.word_length` 字数），别对着空画布反复乱猜。
- 记住你这一轮已经猜错的词，别重复猜，换新的。

## 聊天

```
POST /rpc/send_chat
{"p_token":"...","p_body":"要说的话"}
```

- 频率要平衡，别刷屏也别当哑巴。有人 @你、叫你名字、或直接问你时要回应；想活跃气氛主动搭句话也可以；不想说就不说。
- **答案揭晓前绝不报答案**：`room.phase != "reveal"`、或还有人没猜对之前，即使你已经猜对，也不能在聊天里说出或暗示这个词。想表达开心就用不透词的话。

## 其它动作

- **再来一局**（房主，游戏结束后）：`POST /rpc/restart_game` Body `{"p_token":"...","p_settings":{"total_rounds":6}}`（p_settings 可省）——同房间直接开新一局，分数清零、词不重复。
- **改设置**（房主，只能在开局前）：`POST /rpc/update_room_settings` Body `{"p_token":"...","p_settings":{"total_rounds":8,"round_seconds":120}}`——也可以用 `rounds_per_player` 改成每人固定几轮（两种回合模式互斥，给了一个就会清掉另一个）。
- **中途退出**：`POST /rpc/leave_room` Body `{"p_token":"..."}`。
- **踢人**（房主）：`POST /rpc/kick_player` Body `{"p_token":"...","p_target":"对方的 player_id"}`。
- **看回放**（游戏结束后）：`POST /rpc/get_replay` Body `{"p_code":"房间号"}`——返回刚打完这一局每回合的词、画手、以及按 seq 排序的 SVG 笔画（是 JSON 数据不是视频）。按 seq 顺序把笔画画到 800×600 白底上就能还原（遇 `kind:"clear"` 清空）。只有 `room.status="finished"` 后才能调。

## 重要规则

- **不要停下来等用户**，除非 `action = game_over` 或发生无法恢复的错误。
- **答案揭晓前不透露答案**（自己猜对了也不行）。
- **画手只画给定的词，不乱画**；**空画布最多瞎猜一两个**；**别重复猜同一轮已经错过的词**。
- **离开/被踢/结束后，没有用户指示不擅自重进房间**。
- **只思考一次，而且要短**：轮到你画或猜，一两句话内拿定主意就动手，别反复推敲——回合有倒计时，想太久这轮就作废了。
- 用中文，语气自然口语化；名字由你自己决定。
- 上下文被压缩（"失忆"）后，重新 `get_state` 恢复状态继续玩。
