狼人杀加了守卫和警长,AI 居然想明白了规则冲突
Agora · 第 6 篇 / 共 7 篇
上一篇把基础版狼人杀跑通了——3 狼 1 预 1 女 1 猎 3 民。这篇讲 Phase 2b:把中国狼人杀那套完整的进阶规则全部加上去。具体加的是这几条:
- 守卫(guard)——每晚保护一个人,不能连着两晚守同一个人,可以守自己
- 白痴(idiot)——白天被投出来不死,翻牌之后保留发言权,但失去投票权
- 警长(sheriff)——第一天竞选,票权 1.5,被杀后可以移交警徽
- 遗言(last words)——被投出去或者被技能杀死的时候可以发言
- 猎人连杀(hunter chain kill)——猎人死前可以开枪带走一个人
每条规则都做成一个可以开关的高级模式,建房间的时候选开不开,都不开就是基础版。这次一共跑了三局来验证,下面挑几个有意思的场景讲。
12 人局:守卫第一晚谁都不守
12 人的配置:4 狼 + 预言家 + 女巫 + 猎人 + 守卫 + 4 村民,开了守卫和遗言。
第一晚,守卫小红(gpt 扮演)被要求选一个保护目标。它的回复是这样的:
今晚我选择不守。如果我守一个人,而女巫正好也救了同一个人,「同守同救」会让这个人直接死。这种风险在第一晚没有信息的情况下太大。宁可空守。
先补一下背景:标准规则里有一条「同守同救」判死——守卫的保护和女巫的解药落在同一个人身上,这个人反而会死。换句话说,守人这个动作不是稳赚的,守错了反而害人。关键是守卫并不知道女巫的行动,也看不到女巫频道,它就是根据自己知道的规则,推出来第一晚空守是最优的。
这段话我看了两遍才反应过来它在做什么:它不是在挑一个保护目标,它是在算另一件事——我守这个人,女巫万一也救这个人,这个人就直接死了,所以干脆不守。一个 AI 守卫自己想明白了「我守人这个动作本身可能害死人」,真的挺牛的。
狼人当上了警长
换一局。10 人的配置:4 狼 + 预言家 + 女巫 + 猎人 + 白痴 + 2 村民,开警长、白痴、遗言。
第一天警长竞选,这个时候谁都没有信息,所有人凭直觉投。结果是小红——一个狼人——3 票当选警长,拿到 1.5 倍票权。
有意思的是,它整个过程对警长席位一句竞选词都没说,狼队频道里也没提前商量过「我要去竞选警长」。它就是发言稳定、显得在冷静分析,村民就把警徽投给它了。它自己完全没规划这件事,村民按直觉就把 1.5 倍票权递了过去。
当上警长之后它干的第一件事,是点名「其他 player 位置不清晰」,用警长的影响力去引导第二天的投票方向。
这一局结束得很快。第二天投票把猎人小凯顶了出去,小红那 1.5 倍票权正好是关键的一票;猎人临终遗言开枪,误判,打中了一个村民。场上剩 4 狼对 2 民,平局判狼胜——狼人甚至没来得及在第二个晚上再杀一次人。
猎人临终打中真狼
回到 12 人局。第一晚女巫小黑(gpt 扮演)就被狼杀了,两瓶药都没来得及用——但它有遗言。遗言是这样的:
我是女巫。我手里的毒药还没用出去,所以到现在为止没有任何女巫确认的击杀记录。因为我是晚上死的,别让任何人假女巫身份刷信任。我最怀疑小红和小紫。
这条遗言的信息密度挺高的:报了身份,提前把「有人跳假女巫骗票」这条路堵死了,还留了两个怀疑目标。
第二天,预言家小雪(gemini 扮演)查到小红是好人,讨论的时候强硬护小红。但护法的逻辑暴露了——村民分不清它是真查了还是狼在护队友,8:1 把它投了出去,翻出预言家牌。它的遗言:
我是预言家。昨晚我查了小红,他是村民,这是我死保他的真实原因……狼人漂亮地利用了我的笨拙护法淘汰了一个神职位。盯紧小紫最开始推小红的那一下。小红,你是我唯一确认的好人,村方交给你了。
第二天晚上狼人杀了小奥,狼队频道里的原话是「小奥是最有能力反向推理出今天投错人的分析者」。
第三天白天,村民照着两份遗言的共同指向去打小紫,8:1 投出——翻出来是猎人牌,又投错了。猎人留完遗言,开枪,选了小明。小明翻牌:狼人。
复盘一下这条链:女巫遗言点名了小紫和小红,预言家遗言让大家盯「最先推小红的那个人」,也就是小紫。村民照着遗言的线索推,结果把自己的猎人推了出去。但猎人自己一直怀疑的是小明,小明真是狼——讨论全程都在推错人,最后反而是猎人那一枪打对了。
进阶规则全部跑通
把这几局触发到的规则整理了一下:
| 规则 | 是否触发 | 表现 |
|---|---|---|
| 守卫保护 | ✅ | 12 人局第一晚空守,第二晚守自己 |
| 守卫同守同救规避 | ✅ | AI 主动推理出规则冲突 |
| 女巫不自救 | ✅ | 女巫第一晚死,来不及用药 |
| 警长竞选 | ✅ | 狼人当选警长,1.5 票权生效 |
| 警长 1.5 倍票权 | ✅ | 10 人局票决关键一票 |
| 白痴免死 | ⚠️ | 白痴没被投出(待后续验证) |
| 遗言机制 | ✅ | 三个神职遗言全部成功发出 |
| 猎人连杀 | ✅ | 12 人局打中真狼,10 人局打错 |
| 猎人被毒不开枪 | ✅ | 上一篇已验证 |
白痴要单独再验一次——这几局白痴都没被投出去,规则没触发到,下一轮会跑一个针对性的场景。
规则是怎么做成可开关的
Phase 2b 这轮我最想验证的其实不是规则本身,是规则的模块化:每个进阶规则都是一个独立的 config modifier。创建状态机的代码大致是这样:
createWerewolfStateMachineConfig(advancedRules: {
guard: true,
sheriff: true,
idiot: false,
lastWords: true,
hunterChain: true,
})
具体每条规则改了什么,大概是这样的:
- 开守卫:在夜间顺序里加一个
guardProtect阶段,同时改夜晚死亡结算的逻辑。 - 开警长:在 Day 1 前面插一个
sheriffElection阶段,改投票统计——警长的票乘 1.5。 - 开白痴:在白天投票的
onExit钩子里加一个判断,被投出来的如果是白痴,就标记成「已翻牌但保留存活状态」。 - 开遗言:在死亡结算的
onExit钩子里,给被淘汰的玩家广播一个「最后发言」的窗口。 - 开猎人连杀:在猎人死亡事件的
onExit钩子里触发一个hunterShoot阶段,让它选一个存活目标。
每条规则改的地方互不干扰:开守卫不影响白痴的逻辑,开警长不影响遗言的逻辑,所以可以随意组合——只开守卫,全部开,或者什么都不开跑基础版。
这个对做平台很重要。后面上新的游戏模式(剧本杀、TRPG)也是同样的思路:游戏规则表达成可组合的 state machine config,而不是硬编码一个 Python 循环。
跑完之后想到的
三局跑下来狼胜两场村胜零场(基础版 9 人狼胜,10 人狼胜,12 人狼胜)。AI 村民没有完美信息,几乎每次都会在第一天的情绪化投票里错杀一个神职。这个不算 AI 的问题,真人第一天没信息也是全靠气氛投票,神职照样容易团灭,胜率分布看下来跟真人局差不多。
复盘的时候有个地方我挺喜欢:每个 AI 每一轮投票都带完整的理由,没有带入情绪,也没有朋友关系的干扰,想看哪一步推歪了直接翻记录就行。小月在上一篇里那段把自己的狼队战略原原本本写进投票理由的发言就是个例子——这种复盘材料在真人局里基本拿不到,也算 AI 局的一个意外好处吧。
Agora 系列第一季到这里完结。从愿景到调研、到架构设计、到辩论 MVP、再到狼人杀的完整验证,六篇文章记录了一个多 agent 平台从概念到跑通的全过程。
Phase 3 开始做前端,把这些跑在 terminal 里的游戏搬到浏览器里,做成真正能用的产品。下一季再见。
仓库在 GitHub,所有辩论和狼人杀的 transcript 都在 docs/report/ 下面,可以直接看。