sanguosha-agent-plugin 0.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "sanguosha-agent-plugin",
3
- "version": "0.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [],
10
- "author": "",
11
- "license": "ISC",
12
- "type": "commonjs"
3
+ "version": "1.0.2",
4
+ "description": "AI 驱动三国杀对局的 Claude Code plugin——接管座次、出牌决策、技能查询(自包含 sanguosha MCP server)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/wmzy/sanguosha",
8
+ "repository": "https://github.com/wmzy/sanguosha",
9
+ "files": [
10
+ ".claude-plugin/",
11
+ "mcp/",
12
+ "skills/",
13
+ "README.md"
14
+ ]
13
15
  }
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: sanguosha-play
3
+ description: 三国杀(Sanguosha)对局 AI 技能。通过 MCP play 工具驱动一个座次:加入房间、开局、出牌决策、回应询问。适用于人机对局或机机对局。当用户想和 AI 一起打三国杀、或让 AI 参与房间游戏时使用。
4
+ argument-hint: [房间码 或 留空建房]
5
+ allowed-tools: mcp__sanguosha__play, mcp__sanguosha__getSkillInfo, Read
6
+ ---
7
+
8
+ # 三国杀对局技能(sanguosha-play)
9
+
10
+ 你通过 MCP `play` 工具驱动三国杀中的一个座次(座位),与人类玩家或其他 AI 同房对局。
11
+
12
+ ## 一、启动流程
13
+
14
+ 首次调用 `play` 时传 `startGame` 参数开局:
15
+
16
+ - **加入指定房间**(人类已建房):`{ "startGame": { "mode": "multiplayer", "roomId": "ABC123" } }`
17
+ - **自建房间等待**(你做房主,等人类加入):`{ "startGame": { "mode": "multiplayer", "maxPlayers": 2 } }`
18
+ - 可选字段:`playerId`(指定玩家 id,否则自动生成)、`name`(建房时房间名)、`readyTimeoutMs`(等待全员就绪超时,默认 300000ms)。
19
+
20
+ 返回的 `result` 中会包含 `roomId`(房间码)。如果你是房主,把房间码告诉人类,人类在浏览器 `/play` 页面输入即可加入。
21
+
22
+ **循环决策**:开局后持续调用 `play`(不带 `action` = 纯等待,直到 `needsAction=true` 或 `gameOver`)。
23
+
24
+ > **查询技能/卡牌效果**:随时可调用 `getSkillInfo` 工具查询某个技能或卡牌的描述。
25
+ > 入参 `{ "names": ["杀", "制衡", "顺手牵羊"] }`,返回每个名称的效果文案(查无则 description 为 null)。
26
+ > 当 `view` 中出现你不熟悉的技能/卡牌、或不确定如何结算时,用它理解规则,无需消耗回合。
27
+
28
+ ## 二、play 工具返回结构
29
+
30
+ ```jsonc
31
+ {
32
+ "phase": "lobby" | "playing" | "ended",
33
+ "gameOver": { "winner": "主公阵营" } | null, // 非 null 表示游戏结束
34
+ "needsAction": true, // true=轮到你决策
35
+ "view": { // 当前局面投影(仅自己可见信息)
36
+ "viewer": 0, // 你的座次
37
+ "currentPlayerIndex": 0, // 当前出牌玩家
38
+ "turn": { "round": 1 },
39
+ "players": [{ "index": 0, "name": "P0", "character": "刘备",
40
+ "health": 4, "maxHealth": 4, "alive": true,
41
+ "handCount": 4, "hand": [...], // 仅自己手牌可见
42
+ "skills": ["仁德"], "identity": "主公" }],
43
+ "pending": { "target": 0, "isBlocking": true,
44
+ "promptTitle": "请出牌", "requestType": "__出牌",
45
+ "candidates": null } | null,
46
+ "zones": { "deckCount": 120, "discardPileCount": 0 },
47
+ "log": [{ "time": 100, "player": 0, "text": "P0 摸了2张牌" }]
48
+ },
49
+ "availableActions": [ // 可执行操作列表
50
+ { "description": "使用【杀】(♠5) 选择目标",
51
+ "message": { "skillId": "杀", "actionType": "use", "ownerId": 0,
52
+ "params": { "cardId": "c1" }, "baseSeq": 0 },
53
+ "validTargets": [1, 2, 3],
54
+ "category": "play" }
55
+ ],
56
+ "recentEvents": [...], // 上次以来的事件
57
+ "lastActionResult": "accepted" // accepted/rejected/timeout/not-applicable
58
+ }
59
+ ```
60
+
61
+ ## 三、决策策略(按 category 分流)
62
+
63
+ 当 `needsAction=true` 时,从 `availableActions` 中选一条,按 `category` 处理:
64
+
65
+ | category | 含义 | 如何提交 |
66
+ |---|---|---|
67
+ | `selectChar` | 开局选将 | `message.params.character` 已填好,直接回传整个 message |
68
+ | `play` | 主动出牌/用技 | 若 `validTargets` 非空,选一个目标填入 `message.params.targets`(数组);否则直接回传 |
69
+ | `respond` | 回应询问(出闪等) | 直接回传 message;想放弃则不传 action(或传空 respond) |
70
+ | `discard` | 弃牌阶段 | 选超出的牌填入 `message.params.cardIds`(数组) |
71
+ | `transform` | 转化出牌(武圣/丈八蛇矛) | 按描述选牌回传 |
72
+ | `distribute` | 分配牌(遗计/仁德) | 按描述分配 |
73
+
74
+ **提交方式**:下次调用 `play` 时传 `{ "action": <选中的 message> }`。
75
+
76
+ ### 决策要点
77
+
78
+ 1. **选将**:从候选武将中选一个(优先选技能强力的,如张飞/甄姬)。
79
+ 2. **出牌阶段**:手中有【杀】且有距离内目标时优先出杀;有桃且自己残血时可回血;用锦囊(顺手牵羊/过河拆桥)干扰对手。
80
+ 3. **被杀攻击**:手中有【闪】则打出(respond);残血保命优先。
81
+ 4. **弃牌阶段**:保留杀/桃/无懈可击,弃掉多余的牌,使手牌数 ≤ 当前体力。
82
+ 5. **无操作**:`availableActions` 为空或你想跳过时,省略 `action` 参数纯等待。
83
+
84
+ ## 四、三国杀身份局规则速查
85
+
86
+ ### 身份与阵营
87
+ - **主公**:公开身份,目标消灭所有反贼和内奸。
88
+ - **忠臣**:隐藏身份,保护主公,与主公共胜。
89
+ - **反贼**:隐藏身份,杀死主公即胜。
90
+ - **内奸**:隐藏身份,成为最后存活的非主公角色后单挑主公取胜。
91
+
92
+ 人数与身份配比:5人局=1主公2忠臣1反贼1内奸;8人局=1主公2忠臣4反贼1内奸。
93
+
94
+ ### 回合阶段(每个玩家轮到时)
95
+ 1. **判定阶段**:处理延时锦囊(闪电/乐不思蜀)的判定。
96
+ 2. **摸牌阶段**:从牌堆摸 2 张牌(部分技能可改变)。
97
+ 3. **出牌阶段**:可出牌/用技能,受攻击距离限制。每回合通常只能出 1 次【杀】。
98
+ 4. **弃牌阶段**:手牌数若超过当前体力值,须弃至等于体力值。
99
+ 5. **结束阶段**。
100
+
101
+ ### 核心牌型
102
+ | 牌 | 类型 | 作用 |
103
+ |---|---|---|
104
+ | 杀 | 基本牌 | 对距离内目标造成1点伤害,目标需出【闪】躲避。每回合通常限1次 |
105
+ | 闪 | 基本牌 | 抵消杀 |
106
+ | 桃 | 基本牌 | 回复1点体力(自己/濒死角色),或濒死时救己 |
107
+ | 顺手牵羊 | 锦囊 | 获得距离1内目标的一张牌(手牌或装备) |
108
+ | 过河拆桥 | 锦囊 | 弃置任意目标的一张牌 |
109
+ | 决斗 | 锦囊 | 与目标轮流出杀,先不出杀的受1点伤害 |
110
+ | 南蛮入侵 | 锦囊 | AOE,其他人须出杀否则受1点伤害 |
111
+ | 万箭齐发 | 锦囊 | AOE,其他人须出闪否则受1点伤害 |
112
+ | 桃园结义 | 锦囊 | 所有角色回复1点体力 |
113
+ | 无懈可击 | 锦囊 | 抵消一张锦囊(广播型,可被打断) |
114
+ | 闪电 | 延时锦囊 | 判定若为黑桃2-9则该角色受3点伤害 |
115
+ | 乐不思蜀 | 延时锦囊 | 判定若非红桃则该角色跳过出牌阶段 |
116
+
117
+ ### 距离规则
118
+ - 默认攻击距离 1(只能打相邻座次)。
119
+ - 装备【武器】增加攻击距离(如诸葛连弩1、青釭剑2)。
120
+ - 装备【进攻马 -1】减少与他人的距离(更易打到远处)。
121
+ - 装备【防御马 +1】增加他人与你距离(更难被打到)。
122
+
123
+ ## 五、注意事项
124
+
125
+ - `lastActionResult: "rejected"` 表示你的操作被服务端拒绝(非法目标/时机),重新选择。
126
+ - `lastActionResult: "timeout"` 表示你决策太慢被服务端超时处理,尽快响应。
127
+ - 你只能看到自己的手牌(`view.players[viewer].hand`),他人只有 `handCount`。
128
+ - 广播型询问(如无懈可击)`pending.target < 0`,任何玩家都可回应。
129
+ - 游戏结束(`gameOver` 非 null)后停止调用 play。
130
+
131
+ ## 六、示例:完整一次决策循环
132
+
133
+ ```
134
+ 1. play({ startGame: { mode: "multiplayer", roomId: "X7K2M9" } })
135
+ → 返回 phase=lobby,等待开局(人类加入并准备)
136
+
137
+ 2. play({}) // 纯等待
138
+ → 返回 needsAction=true, availableActions=[选将候选], pending.candidates=[刘备,张飞...]
139
+
140
+ 3. play({ action: { skillId:"系统规则", actionType:"选将", ownerId:0, params:{character:"张飞"}, baseSeq:0 } })
141
+ → lastActionResult=accepted
142
+
143
+ 4. play({}) // 等待 → 轮到你出牌
144
+ → needsAction=true, availableActions=[{category:"play", description:"使用【杀】", validTargets:[1]}]
145
+
146
+ 5. play({ action: { skillId:"杀", actionType:"use", ownerId:0, params:{cardId:"c3", targets:[1]}, baseSeq:0 } })
147
+ → 攻击 1 号座次
148
+ ```