从石头剪刀布到桌游:用博弈论破解《惨剧轮回》
从石头剪刀布谈起
Alice 和 Bob 在玩石头剪刀布。站在 Alice 的视角,将获胜记为 \(1\),平局记为 \(0\),失败记为 \(-1\),可以得到收益矩阵
矩阵的三行分别表示 Alice 出石头、剪刀、布,三列分别表示 Bob 出石头、剪刀、布。因此,这个矩阵本身就可以理解为一局游戏:Alice 选择一行,Bob 选择一列,行列交点处的数值就是这一局的结果。
例如 Alice 选择第一行,也就是出石头;如果 Bob 选择第二列,也就是出剪刀,那么交点为 \(1\),Alice 获胜;如果 Bob 选择第三列,也就是出布,那么交点为 \(-1\),Alice 失败。
显然,双方会按照某种概率随机行动。设 Alice 选择三行的概率为 \(\sigma=(\sigma_1,\sigma_2,\sigma_3)\),Bob 选择三列的概率为 \(\tau=(\tau_1,\tau_2,\tau_3)\)。这样每进行一局游戏,就相当于 Alice 按照 \(\sigma\) 随机选择一行,Bob 按照 \(\tau\) 随机选择一列,再看交点处的结果。长期重复游戏后,Alice 的平均收益为 \(\sigma^\top M\tau\)。
那么 Alice 应该选择怎样的概率分布呢?假设 Alice 永远出石头,即 \(\sigma=(1,0,0)\),那么 Bob 只要永远出布,就可以让 Alice 每局都得到 \(-1\)。即使 Alice 不是固定出某一种,只要她的策略存在明显偏向,Bob 也可以根据这种偏向调整自己的策略。
要知道 Bob 不是傻子,如果 Bob 已经观察到 Alice 使用的策略,肯定会专门选择对 Alice 最不利的策略。因此,评价一个 Alice 的策略 \(\sigma\) 时,我们要考虑的是,在被针对的情况下 Alice 最多还能保证多少收益?
对于固定的 \(\sigma\),Bob 所能造成的最坏结果为 \(\min_\tau \sigma^\top M\tau\)。这个值表示 Alice 使用策略 \(\sigma\) 时,无论 Bob 怎样针对自己,都至少能够保证的收益。不同的 \(\sigma\) 能保证的最低收益不同,因此 Alice 真正需要做的是从所有可能的策略中,选择一个“最坏情况下仍然最好”的策略:
这就是 minimax 的含义。其中内层的 \(\min_\tau\) 表示先考虑 Bob 对当前策略最不利的应对,外层的 \(\max_\sigma\) 表示 Alice 再选择一个策略,使这种最坏情况下的结果尽可能好。
注意,这里并不是说实际游戏中 Alice 先公布策略、Bob 再行动;双方仍然是同时行动。这个式子表达的是:一个策略如果要称为最优,就应当在对手知道并尽力针对它的情况下仍然成立。
石头剪刀布的这个矩阵博弈可以通过线性规划(Linear Programming, LP)精确求解,得到双方的最优策略均为 \((1/3,1/3,1/3)\),即分别以 \(1/3\) 的概率随机选择石头、剪刀和布。此时任何一方都无法通过改变自己的策略获得额外优势,博弈的期望收益为 \(0\)。
游戏规则
前几天,平时一起玩桌游《惨剧轮回》的朋友向我问了这样一个问题:在“谋杀计划”中,如果双方都采取最优策略,剧作家有多大概率获胜,以及应该如何出牌?
本文只考虑与这个问题相关的游戏规则,并等价变换为更简洁的形式。剧作家记为 Alice,主人公记为 Bob。Alice 的目标是通过移动角色和增加密谋满足胜利条件,Bob 则需要阻止 Alice,由于无法临时变牌,我们可以认为双方在每个回合都会同时对角色出牌。
游戏设定
版图由医院、神社、都市、学校 4 个区域组成,排列为一个 \(2\times2\) 方格。角色可以进行左右、上下或斜向移动。
“谋杀计划”追加关键人物、主谋和杀手各 1 名。本文假设这 3 名角色的初始区域随机,并且游戏开始时 Alice 与 Bob 都明确知道三名角色的身份。
双方手牌
Alice 的手牌包括:1 张“左右移动”、1 张“上下移动”、1 张“斜向移动”(每张限使用一次)、1 张“密谋+1”、1 张“密谋+2”(每张限使用一次)和 3 张空白牌。
Bob 的手牌包括:3 张“左右移动”、3 张“上下移动”、3 张“禁止移动”(每张限使用一次)、1 张“禁止密谋”和 3 张空白牌。
双方每回合都必须分别对关键人物、主谋和杀手各出 1 张牌。游戏共有 \(D\) 个回合。
回合流程
每个回合依次进行以下结算:
- Alice 与 Bob 同时对三名角色各出 1 张牌。出牌时,双方都不知道对方本回合打出的具体牌名。
- 结算密谋牌。如果角色被打出“密谋+1”或“密谋+2”,且没有被打出“禁止密谋”,则该角色增加对应数量的密谋。
- 结算移动牌。如果角色被打出移动牌,且没有被打出“禁止移动”,则按照对应方向移动。若同一角色被打出两张牌名不同的移动牌,则先合成移动方向:左右+上下=斜向,左右+斜向=上下,上下+斜向=左右。
- 公开并弃置本回合打出的“限使用一次”的牌。此时双方都可以得知这些牌。
- 主谋选择同一区域的 1 名角色,使其密谋+1。
胜负判定
每个回合结算后,如果满足以下任意一个条件,Alice 立即获胜:杀手的密谋达到 4;或杀手与关键人物处于同一区域,且关键人物的密谋达到 2。
如果 \(D\) 个回合全部结束后 Alice 仍未获胜,则 Bob 获胜。
问题建模
进行到任意一个回合时,我们只关心那些影响之后胜负的信息,因此我们先考虑如何表示状态。
状态表示
设 Key Person、Brain、Killer 分别记为 \(P,B,K\)。四个区域记为 \(\mathbb F_2^2=\{0,1\}^2\),左右、上下、斜向三种移动分别记为 \(e_x=(1,0)\)、\(e_y=(0,1)\)、\(e_d=(1,1)\)。
我们只关心角色的相对位置,因此以 Key Person 为原点,令 \(x,y\in\mathbb F_2^2\) 分别表示 Brain、Killer 相对于 Key Person 的位置。这样 \(x=0\) 表示 Brain 与 Key Person 同区,\(y=0\) 表示 Killer 与 Key Person 同区,而 \(x=y\) 表示 Brain 与 Killer 同区。

图 1:角色的相对位置状态图
令 \(c\in\{0,1,2,3,4\}\)、\(h\in\{0,1,2\}\) 分别表示 Killer 与 Key Person 的截断密谋值,因为一旦达到对应阈值,更大的数值不会改变之后的胜负判断。再令 \(r\) 表示双方剩余的一次性牌。
于是,一个局面可以表示为
剩余回合数 \(d\) 会在后面的价值函数 \(V_d(S)\) 里单独记录。
回合行动
在状态 \(S\) 下,Alice 与 Bob 的合法完整行动集合分别记为 \(\mathcal A(S)\)、\(\mathcal B(S)\)。一个完整行动指这一回合对三名角色的三张牌一起组成的出牌方案:
双方同时选择 \(\mathbf a\) 与 \(\mathbf b\),随后按照游戏规则依次结算。
对 \(i\in\{P,B,K\}\),令 \(u_i\in\{0,e_x,e_y,e_d\}\)、\(v_i\in\{0,e_x,e_y\}\) 分别表示 Alice、Bob 对角色 \(i\) 产生的移动类型,其中 0 表示没有移动牌。
两张移动牌同时作用在同一角色上时,移动合成为
其中加法在 \(\mathbb F_2^2\) 上进行。
再令 \(n_i\in\{0,1\}\) 表示 Bob 是否对角色 \(i\) 使用禁止移动,并记实际位移为 \(m_i=(1-n_i)(u_i\circ v_i)\)。考虑到 Key Person 一旦移动,Brain 和 Killer 相对于 Key Person 的位置都会一起改变。结算移动后,两个相对位置变为
令 \(q_i\in\{0,1,2\}\) 表示 Alice 对角色 \(i\) 打出的密谋增量,\(f_i\in\{0,1\}\) 表示 Bob 是否对角色 \(i\) 使用禁止密谋。
移动和密谋牌结算后,Alice 还需要决定 Brain 的能力目标。令 \(\alpha,\beta\in\{0,1\}\) 分别表示 Brain 是否给 Killer、Key Person 增加 1 点密谋。由于 Brain 只能选择同一区域的角色,并且一次只能选择一个目标,合法选择集合为
于是本回合结算后的密谋值为
本回合使用的一次性牌也会从剩余手牌中移除。若用 \(\rho(r,\mathbf a,\mathbf b)\) 表示这一更新,那么完整的状态转移可以写成
即通过当前状态、双方这一回合的完整出牌,以及 Brain 最后的选择,就可以下一状态。
胜利条件
Alice 有两种获胜方式:Killer 的密谋达到 4;或 Killer 与 Key Person 同区域,并且 Key Person 的密谋达到 2。因此把所有已经满足胜利条件的状态记为
到这里,原来的游戏规则已经被整理成了三部分:当前状态 \(S\)、本回合状态转移 \(\Phi\),以及胜利状态集合 \(W\)。后续的动态规划在三者上进行。
价值函数与最优策略
石头剪刀布每一局是独立的,所以行列交点可以直接写成 \(1,0,-1\)。而在这里,双方当前回合的出牌通常不会立刻决定整局游戏,而是把游戏带到一个新的状态。因此,一个行动组合的收益为,进入这个新状态以后,Alice 最终还能以多大概率获胜。
因此,总体思路是,先解决只剩较少回合的情况,再用这些结果去计算还剩更多回合的情况。
状态价值
令 \(d\in\{0,1,\ldots,D\}\) 表示当前剩余回合数。定义 \(V_d(S)\) 为:当前处于状态 \(S\),还剩 \(d\) 个回合,并且之后双方都采取最优策略时,Alice 最终获胜的概率。
可以把 \(V_d(S)\) 直接理解成这个局面对 Alice 的价值。例如 \(V_d(S)=0.8\),表示从这个局面继续最优对抗,Alice 最终有 80% 的获胜概率。
当 \(d=0\) 时已经没有任何回合可以继续。如果此时已经满足 Alice 的胜利条件,则结果为 1,否则为 0,因此
现在考虑 \(d\ge1\)。假设当前双方完整行动 \(\mathbf a,\mathbf b\) 已经确定并公开,本回合只剩 Brain 的能力目标需要由 Alice 选择。
不同的 Brain 选择会产生不同的下一状态。Alice 自然会选择其中后续胜率最高的一个,因此定义
这表示,如果本回合双方已经确定采用这对出牌方案,那么 Alice 在最优选择 Brain 目标之后,最终能够获得的胜率是多少。
双方目标
真正出牌时,Alice 并不知道 Bob 会选择哪个完整行动,Bob 也不知道 Alice 的选择,所以双方都需要采取某种概率分布的混合策略。
对任意有限集合 \(X\),记 \(\Delta(X)\) 为 \(X\) 上所有概率分布的集合。令 Alice、Bob 的混合策略分别为 \(\sigma\in\Delta(\mathcal A(S))\)、\(\tau\in\Delta(\mathcal B(S))\)。若 \(S\in W\),显然 \(V_d(S)=1\);否则
这个式子和前面石头剪刀布的 minimax 完全是同一件事:对 Alice 的一个随机出牌方案,先考虑 Bob 最不利的应对,再从所有随机方案中选择最能保证胜率的那个。
对应的最优局部出牌策略为
这里的 \(\sigma_d^*(S)\) 和 \(\tau_d^*(S)\) 是对所有合法完整出牌方案给出的概率分布。
初始胜率
游戏开始时,三名角色的绝对位置独立均匀随机。换成相对位置后,有
若初始剩余手牌状态记为 \(r_0\),则开始时剩余 \(D\) 个回合。对 16 种可能的初始相对位置取平均,就得到 Alice 的总体最优胜率
到此为止,我们的目标已经变为,求出所有需要的 \(V_d(S)\),以及对应的 \(\sigma_d^*(S)\)、\(\tau_d^*(S)\)。
求解方法
上一节给出了递推公式,但真正计算时我们并不需要一次处理整个游戏树。如果已经知道所有还剩 \(d-1\) 个回合的状态价值,那么对于一个还剩 \(d\) 个回合的状态,只需要解决当前这一回合的出牌问题。
所以每一层的计算都分成两步:先把当前状态变成一个收益矩阵,再求这个矩阵博弈的最优混合策略。
构造收益矩阵
固定 \(d\ge1\) 与一个尚未胜利的状态 \(S\)。把 Alice 与 Bob 所有合法的完整行动分别编号为
现在和石头剪刀布一样,把 Alice 的行动放在行上,把 Bob 的行动放在列上。对于第 \(p\) 行和第 \(q\) 列,双方本回合的出牌已经完全确定。结算这些牌以后,再由 Alice 选择最有利的 Brain 目标,因此定义
于是 \(M_d(S)\) 就是当前状态对应的收益矩阵。第 \(p\) 行、第 \(q\) 列的交点不再像石头剪刀布那样是 \(1,0,-1\),而是这对出牌结算以后,Alice 从下一状态继续最优游戏的最终胜率。
如果双方采用混合策略 \(\sigma=(\sigma_1,\ldots,\sigma_m)\)、\(\tau=(\tau_1,\ldots,\tau_\ell)\),那么 Alice 的期望胜率为
因此当前状态的价值就是这个矩阵博弈的 minimax value:
线性规划
矩阵 \(M_d(S)\) 一旦构造完成,剩下的问题就和普通的有限零和矩阵博弈完全一样。Alice 需要找到一个概率分布 \(\sigma\),使 Bob 无论选择哪一列,Alice 都能保证尽可能高的期望胜率。
设 Alice 想保证的最低胜率为 \(v\)。那么对于 Bob 的任何针对性策略,这个期望胜率都必须至少为 \(v\),于是得到线性规划
求解以后,最优目标值就是 \(V_d(S)\),最优概率向量就是 Alice 在这个状态下的最优混合策略 \(\sigma_d^*(S)\)。
Bob 的问题完全对称。他希望找到 \(\tau\),使 Alice 无论选择哪一行,期望胜率都不会超过尽可能小的 \(v\):
它给出 Bob 的最优混合策略 \(\tau_d^*(S)\)。由有限零和博弈的极小极大定理,两边得到的最优值相同,所以只要解完当前矩阵,就同时知道了这个状态的胜率和双方应该怎样随机出牌。
实际计算时可以直接交给标准 LP solver,用线性规划从已经构造好的收益矩阵中找出最优随机概率。
动态规划
动态规划的边界条件是 \(V_0(S)=\mathbf 1_{\{S\in W\}}\).
当 \(d=1\) 时,本回合就是最后回合。每一对行动结算以后,要么满足胜利条件,要么没有满足,因此 \(M_1(S)\) 的元素只会是 0 或 1。解这些矩阵博弈,就得到所有 \(V_1(S)\)。
有了 \(V_1\),就可以构造 \(M_2(S)\) 并求出 \(V_2(S)\);有了 \(V_2\),再求 \(V_3(S)\),以此类推一直到 \(V_D\)。
真实游戏的剩余回合数是从 \(D\) 一路减到 0,求解时反过来,从最简单的 0 回合开始逐层向上计算:
对于其中任意一层,都可以把一步计算概括为
其中 \(Q_d\) 负责处理双方行动已经确定后的 Brain 最优选择,\(M_d\) 把所有行动组合整理成矩阵,最后通过矩阵博弈得到 \(V_d\)。
使用策略
最终,我们得到一张随剩余回合数和当前状态变化的策略表。
实际进行游戏时,可以这样理解求解结果:
- 先根据当前角色相对位置、密谋值和剩余一次性牌确定状态 \(S\) 和剩余回合数 \(d\)。
- Alice 按照 \(\sigma_d^*(S)\) 给出的概率,在所有完整出牌方案中随机选择一个;Bob 同样按照 \(\tau_d^*(S)\) 随机选择自己的完整出牌方案。
- 双方出牌公开并完成移动、密谋等结算后,Alice 再决定 Brain 的能力目标。此时对每一个合法选择比较下一状态的 \(V_{d-1}\),选择价值最大的一个。
- 进入新的状态,将剩余回合数改为 \(d-1\),然后重复同样的过程。
Brain 的这一部分策略可以写成
因此,Alice 的完整最优策略包括两部分:出牌前根据 \(\sigma_d^*(S)\) 随机选择完整行动,以及出牌公开后根据 \(\gamma_d^*\) 选择 Brain 的目标;Bob 的完整最优策略则由 \(\tau_d^*(S)\) 给出。
注意,最优混合策略并不是挑概率最高的那个行动。比如求得 \(\sigma_d^*(S)=(0.2,0.5,0.3)\),那么真正的最优策略就是分别以 20%, 50%, 30% 的概率采用这三个完整行动,而不是永远选择概率为 50% 的行动。
如果某个状态下存在多个同样最优的混合策略,或者 Brain 有多个后继状态价值完全相同的选择,那么任选其中一个最优解即可。
最终,\(V_D(x,y,0,0,r_0)\) 给出每一种初始相对位置下 Alice 的最优胜率,按照初始位置分布取平均即可得到总体胜率 \(V^*\)。而 \(\sigma_d^*(S)\)、\(\tau_d^*(S)\) 与 \(\gamma_d^*\) 则告诉我们,在游戏真正进行到某个具体局面时,双方应该怎样行动。
代码实现
建模完毕后,我们就可以愉快地开始 Python 了,代码详见 murder-plan-solver 。
核心代码分成三个部分:model.py 定义状态、行动和求解结果;rules.py 负责单回合规则结算;solver.py 负责状态搜索、动态规划和矩阵博弈求解。而 cli.py 只负责把命令行输入转换成 State 并调用求解器。
求解流程
整个求解由 Solver.solve() 驱动。一次状态求值大致包括三个阶段:生成合法行动并结算单回合效果、读取后继状态的价值并构造收益矩阵、调用线性规划求解矩阵博弈。
首先讲一下单回合的转移规则是如何建立的。 rules.py 先通过 _alice_actions() 和 _bob_actions() 生成当前剩余手牌下的所有合法完整行动,再由 _effect() 结算每一对行动。当然,很多不同的行动组合可能产生相同的结果,因此 _turn_data_for_inventory() 会把它们合并成同一个 _Effect,并建立这些 Effect 与收益矩阵之间的索引关系。_next_states() 会考虑行动牌的 _Effect 和 Brain 不同合法选择,从而改变当前状态。
具体求解时, _reachable_layers() 从输入状态开始逐回合展开,调用 _next_states 收集下一层状态(已经满足胜利条件的状态就不需要再继续展开了),这样就向前建立了所有可以达到的状态层。然后根据前文所述的 DP 顺序,从最后一层反向求值。对每个状态,_payoff_matrix() 读取下一层已经算好的 value。它先为每种 _Effect 比较 Brain 各个候选状态的价值,再利用之前保存的关系恢复完整的 Alice × Bob 收益矩阵。随后 _matrix_game() 调用 scipy.optimize.linprog,使用 HiGHS 求出这个矩阵博弈的 value 和 Alice 的最优混合策略。当前层算出的 value 会继续供前一层使用,以此类推回到最初输入的状态。
这里说一下,一个比较关键的实现是 _Effect 这一层压缩。行动组合的数量远多于真正不同的回合结果,我们只需要为每种 Effect 计算一次后续价值,再填回收益矩阵,从而省掉大量重复计算。同一剩余手牌状态下的行动和 Effect 数据也可以通过 lru_cache 复用。
求解结果
Solver.solve() 最终返回输入状态的最优胜率和 Alice 当前的混合策略,Result.pick() 可以按照这组概率抽取一次实际出牌。
average_win_rates() 使用相同的求解流程,只是把 16 种初始相对位置同时作为起点,因此它们可以共享后续的可达状态和反向计算。
缓存与性能优化
算法层面上 DP 已经节省了不少计算量,不过仍然会随回合数迅速增长,需要想想办法优化一下。
瓶颈分析
对一个状态求值我们要做三件事:根据剩余手牌取得合法行动和回合 Effect,读取后继状态 value 并构造收益矩阵,调用 linprog 求出矩阵博弈的 value 与混合策略。
分析一下,行动生成和单回合效果只由剩余的一次性牌决定,组合数量相对较少。状态转移会被大量调用,不过其中许多输入可能只出现一两次。线性规划单次规模其实不大,但调用次数实在太多了,需要频繁启动 HiGHS。
对于第一类,rules.py 使用 lru_cache 按剩余手牌保存 _turn_data_for_inventory() 的结果。第一次遇到某种手牌状态时生成完整数据,之后所有具有相同手牌的局面直接共享。注意与前文介绍的 _Effect 压缩区分,其减少的是单个矩阵内部的重复计算,lru_cache 减少的是不同状态之间的重复生成。
第二类,状态转移有两个优化角度。
两条游戏历史只要到达相同的 State 和剩余回合数 day ,之后面对的行动策略和胜负条件就完全一致。因此,状态求值后 Solver 把 value 保存在 _values 中,_results 保存完整请求过的输入。对于完全相同的一次查询,大约可以从 9 ms 缩短到 3 µs。值得一提的是,这种按访问过程建立的缓存不需要我们事先预测哪些状态常见。
另一个角度是合并对称状态。将位置坐标交换,同时交换左右与上下行动,本质应当不变。_values 使用固定选取的 canonical state 作为索引,原状态与对称状态共用一个 value。注意,混合策略带有具体方向不能直接照搬。
第三类,我们知道,状态不同不代表收益矩阵不同。矩阵元素记录每对行动结算后的最优后续胜率,只要行动数量和这些 value 的排列完全一致,linprog 收到的就是同一个问题。我们根据矩阵形状和全部元素的字节数据计算 BLAKE2b-256 摘要,以此保存 _matrix_game() 求出的 value 与 Alice 混合策略。再次出现完全相同矩阵时直接读取结果,省去一次线性规划。矩阵形状要参与索引,用来区分元素总数相同但行列结构不同的情况。
我们对 D=3 随机初始位置的求解进行了两组插桩。共请求求解 3571 个矩阵,其中只有 2862 个矩阵内容不同,另外 709 次可以复用已有结果,重复率为 19.85%。
随后同时启用状态对称合并和矩阵缓存,共有 2231 个 canonical (State, day) value,只产生了 1832 次实际 LP 调用(因为多个不同状态构造出了相同的收益矩阵),缓存数据量约为 1.12 MiB,完全可以接受。
未采取的策略
_next_states() 没有缓存,测试发现它大约被调用 139 万次,其中 783402 个输入互不相同,虽然能够节省 44% 的重复调用,但由于每项结果还可能包含多个 State,保存 78 万余组后继状态空间成本太高,得不偿失。
线性规划调用彼此独立,因此还测试了线程并行求解,仍然以 D=3 为例:
| 线程数 | 运行时间 | 相对单线程减少 |
|---|---|---|
| 1 | 4.59 s | 0% |
| 2 | 4.30 s | 6.3% |
| 4 | 4.18 s | 8.9% |
| 8 | 4.00 s | 12.9% |
收益没有预期的大,因此最终还是只保留了单线程版本。
减少线性规划的固定开销
完成缓存后,剩余时间主要花在许多规模较小、结构相近的线性规划上。SciPy 的 HiGHS 默认执行 presolve,先删除冗余约束并缩小问题。这个步骤通常有利于大型 LP;当前任务中的单个矩阵较小,presolve 的准备时间反而有点浪费。
将求解器设置为 options={'presolve': False},直接处理原始约束。这个不影响正确性,测试发现 presolve 开关的最大 value 差异为 \(1.665\times10^{-15}\).
假设三名角色初始区域独立均匀随机,测试发现确实能省不少时间:
| 总回合数 \(D\) | 开启 presolve | 关闭 presolve | 耗时减少 |
|---|---|---|---|
| 3 | 6.58 s | 5.09 s | 22.6% |
| 4 | 15.98 s | 11.03 s | 31.0% |
| 5 | 27.18 s | 17.39 s | 36.0% |
| 6 | 40.17 s | 25.23 s | 37.2% |
| 7 | 52.80 s | 32.18 s | 39.1% |
| 8 | 64.16 s | 39.07 s | 39.1% |

图 2:开启和关闭 presolve 的运行时间。上图为绝对运行时间,下图为耗时减少比例
胜率分析
下面比较三种初始位置下 Alice 的最优胜率:
- Brain 与 Killer 分别位于 \(x=(0,1),y=(1,0)\);
- 三名角色均位于同一区域即 \(x=y=(0,0)\);
- 16 种初始相对位置平均情况。
| 总回合数 \(D\) | \(x=(0,1),y=(1,0)\) | \(x=y=(0,0)\) | 随机初始平均 |
|---|---|---|---|
| 3 | 14.51% | 13.43% | 13.39% |
| 4 | 26.74% | 25.91% | 26.01% |
| 5 | 41.34% | 39.36% | 40.60% |
| 6 | 55.42% | 53.53% | 55.13% |
| 7 | 67.67% | 66.08% | 67.43% |
| 8 | 77.37% | 76.08% | 77.16% |

图 3:不同初始位置下 Alice 的最优胜率。上图为绝对胜率,下图为两个固定局面相对随机初始平均值的百分点差
显然,剩余回合数是影响胜率的主要因素。三条曲线的变化趋势基本一致,说明对于初始位置的依赖较小。
这里有个稍微反直觉的结论,初始区域全部相同反而胜率略低,我认为原因是,在真实的对局中,由于 Bob 不仅要防范主线“谋杀计划”,还需要提防其他失败条件,不得不将牌打在其他地方,而在仅考虑“谋杀计划”的情况下,Bob 有充足的牌拉走角色,而 Alice 没有“禁止移动”牌,难以让他们待在一起。
以上混合策略将在 惨剧轮回自助模拟器 实装,欢迎有权限的玩家前来体验!

浙公网安备 33010602011771号