一个纯策略游戏——Goofspiel

上周接了一个小单,根据一个用户的需求用C++做了个小游戏------Goofspiel。游戏逻辑很简单,两个用户A,B和一个奖励方C,用户方每一轮出一张牌比点数,大的就赢得奖励牌。一共13轮,结束后,谁手中奖励牌之和大,谁就胜利。注意,用户牌和奖励牌的大小都是1到13。 有想体验的可以去试试别人写的网页版:coppercod.games/game/gops/

图1. Goofspiel game 网页版

一个不存在最优解的纯策略游戏

首先,这是一个不存在最优解的纯策略游戏。因为它是双方博弈性质的,不同对手有不同的出牌偏好,这也决定了你的出牌倾向。换言之,不同对手出牌的概率分布是变化的。

常见的游戏策略

这类游戏的策略非常多,我们列举几个如下:

  • 随机策略:随机从手中取出一张牌出
  • 确定性策略:假设奖励牌为prize_card,那么我们出一张确定的牌;即下次奖励牌为prize_card,我们扔出那张确定的牌
  • 加x策略:奖励牌为prize_card,那么我们出的牌就是(prize_card+x)%13
  • 拿中值牌策略:采用+3的方式,侧重于4,5,6,7,8,9,10这7张中值牌。对于非目标牌,可以随机性出牌

策略的评估

不同策略有不同的应对方法,下面列举一些策略的应对方法:

  • 对于随机策略,即出牌服从[1,13]的均匀分布。我们只需要出与奖励牌一样的牌,就可以获得最后的点数期望最大。
  • 对于确定性策略,如果你知道对手采用+x策略,我们只需要采用+(x+1)策略。

我们的策略

考虑到高价值奖励牌往往并不容易获取,我们对拿中值牌策略进行了改进。它可以自适应的预测对手出牌大小通过考虑轮次、奖励牌情况、对手历 史出牌和我们的手牌。这个策略针对下面三类牌会做出不同的反应:

  • 较低价值牌: 对于1到3的奖励牌x,如果是1,我们出手上最小的纸牌;否则我们倾向于选择一个[x, x+2]的随机卡牌。
  • 中等价值牌 (Prize cards 4-10): 对于4到10的奖励牌x,对局一开始,我们会选择+3的策略。然后,我们会动态学习对手拿牌的gap (gap= 出牌-奖励牌),从而针对性的拿牌。
  • 高价值牌 (Prize cards 11-13): 对于11到13的奖励牌x,我们根据对局状况来选择小牌、随机牌或者大牌。具体来讲,如果我们手上大牌比对手大牌大,则我们拿下该牌;如果我们手上大牌和对手大牌一样大,我们随机选择中等价值牌或者低价值牌;如果我们手上大牌没有对手大牌大,我们将随机选择小牌或者第三个四分位牌。 同时,为了限制对手学习能力,一旦我们得分超过45分,我们将随机选择手牌。

设计相关算法

  • 随机出牌检测算法:我们的算法会分析对手历史出牌,从而判断对手是否是随机出牌。具体来讲,如果对手是随机出牌,当轮数足够大时,对于任意奖励牌x,对手牌将遵循区间在1到13的均匀分布。由于大数定律可知,样本均值收敛于数学期望7。我们从而可以判断对手是否是随机算法。
  • 确定性出牌检测算法:对于一类确定性+x的算法,我们提出了针对性的检测算法。通过检测(对手出牌-奖励牌)%13是否为常数,我们可以确定对手是否是确定性出牌。
  • 自适应出牌算法:该算法会帮助我们的策略拿下更多的中等价值牌。具体来看,一开始我们会以+3的方式冷启动,如果对手与我们竞争中等价值牌,我们会记录对手出牌与奖励牌的gap(gap=对手出牌-奖励牌)。下次面对中等价值牌时,我们会通过 gap+1方式出更有竞争力的牌。
  • 动态丢牌算法:该算法会帮助我们的策略合理的丢弃高价值牌。具体来看,对于一张高价值牌(11,12 或 13),如果我们手中的大牌没有对手大,我们会随机选择丢弃小牌或者中等价值牌(防止对手不出大牌)。如果我们和对手手中的大牌一样大,对于比赛初,我们会随机丢弃中等价值牌或最小牌;对于比赛后期,我们会出最大牌(后期弃牌会非常被动)。

运行截图

下面,我们对上述算法的实现结果进行展示:

图2.游戏主界面

图3. 自适应出牌

图4. 确定性拿牌与动态丢牌

图5. 游戏结果展示

代码

具体代码可去我的github查看,github.com/guchengzhon...

相关推荐
Scc_hy30 分钟前
强化学习_Paper_2000_Eligibility Traces for Off-Policy Policy Evaluation
人工智能·深度学习·算法·强化学习·rl
leke20031 小时前
2025年10月17日
算法
CoovallyAIHub1 小时前
Mamba-3震撼登场!Transformer最强挑战者再进化,已进入ICLR 2026盲审
深度学习·算法·计算机视觉
Aqua Cheng.1 小时前
代码随想录第七天|哈希表part02--454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和
java·数据结构·算法·散列表
怀揣小梦想1 小时前
跟着Carl学算法--哈希表
数据结构·c++·笔记·算法·哈希算法·散列表
Nebula_g1 小时前
Java哈希表入门详解(Hash)
java·开发语言·学习·算法·哈希算法·初学者
Kent_J_Truman1 小时前
【模拟散列表】
数据结构·算法·蓝桥杯·散列表·常识类
Lchiyu1 小时前
哈希表 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和
算法
玩镜的码农小师兄1 小时前
[从零开始面试算法] (04/100) LeetCode 136. 只出现一次的数字:哈希表与位运算的巅峰对决
c++·算法·leetcode·面试·位运算·hot100
RTC老炮2 小时前
webrtc弱网-AcknowledgedBitrateEstimatorInterface类源码分析与算法原理
网络·算法·webrtc