炉石传说 酒馆战棋 战斗模拟的实现

炉石传说 酒馆战棋 战斗模拟的实现

这几天工作闲余,琢磨着新的AI算法思路,于是想尝试一下和机器对战,遂想到炉石传说的酒馆战棋。想要机器对战,就得先把规则写成一个sandbox,然后再机器学习。那么这个第一步就比较繁琐,不想想太多设计,直接捋起袖子做吧。想代码好看,以后再说。

https://github.com/dna2ai/HSBG/blob/master/deck.js
git clone 后打开 index.html 等待一会就能看到demo结果

这个只是闲余极速之作,已经fix了很多bug了,比如从视频里找一些复杂的实例,然后run个100万遍,尤其是亡语招募各种复杂。原理其实很简单,就是两个循环的队列,1号元素不停进攻另一个队列里的元素,直到没有随从能进攻为止。然后,比如让这2个队列战斗个1000遍,就可以知道大概的胜负概率,和英雄伤害量,从而可以很轻松算出抬走概率。

比如我们来看看这个demo阵容:
在这里插入图片描述
结果就是 下方的SlotA win: 9.61%, 上方的SlotB win: 85.42%, 平局Tie: 4.96%

var slotA = [], slotB = [];
function last(slot) { return slot[slot.length-1]; }
slotA.push(api.newMinionById(612, false));
slotA.push(api.newMinionById(411, false));
last(slotA).hp = 7; last(slotA).atk = 2;
slotA.push(new Minion(-12, 2, 4, 0, {}));
slotA.push(new Minion(614, 12, 6, 99, { shield: true, windfury: true }));
slotA.push(api.newMinionById(611, false));
slotA.push(api.newMinionById(312, true));
last(slotA).hp = 7; last(slotA).atk = 7;
slotB.push(api.newMinionById(306, false));
last(slotB).hp = 6; last(slotB).atk = 5;
slotB.push(api.newMinionById(306, false));
last(slotB).hp = 8; last(slotB).atk = 5;
slotB.push(api.newMinionById(302, false));
last(slotB).hp = 2; last(slotB).atk = 3;
slotB.push(api.newMinionById(302, false));
slotB.push(api.newMinionById(406, false));
slotB.push(api.newMinionById(415, false));
last(slotB).hp = 14; last(slotB).atk = 4; last(slotB).flags.taunt = true; last(slotB).flags.shield = true;
slotB.push(new Minion(-15, 8, 20, 3, {}));

这里我们还可以顺便讨论讨论酒馆战棋的实现;其实插件只是按照我们大概的估算得到一个近似的概率。这些在暴雪的服务器上都可能是一个超参。比如说,狂战斧是打在最边上两个随从还是打中间击中3个随从,可能这个概率是个倒钟形从最中间到最旁边,以前的战棋版本,打旁边的概率特别高,之后调整了以后,攻击中间的概率作了稍微调高。包括暴雪可以看你平时用这个英雄的胜率,当你长时间赢以后,生成一套特定卡组,让你适当输一输。当然,酒馆战棋做不到让你输让你不爽然后充钱买卡牌包,在产品策略上,估计是往竞技平台去了。当然,你充钱了,暴雪可以多给你赢几把,这还是很正常的,控制输赢诸如60%:40%还是很容易的。抱歉,容我收回上面的话;暴雪还是要你充钱的,比如你充钱了以后,拿好牌的概率就大,你不充钱,就不给你牌;所以打着开心就好;想充榜,先交点钱。

所以平衡在战棋里很关键,比如一个6 10的鬼妈妈和白板随从交手,要怎样的身材能打平呢?3 55?5 21?10 14?交手胜负概率测一测就知道了。

我们可以再看一个例子:
在这里插入图片描述

# 把这个数据复制到 index.html里的输入框里,点 "Go fight!" 就可以看结果了
613/8/5/T
403/7/9
608/7/13
604/12/12
604/12/12
609
502
-
216/8/8/3T
306/7/4
306/5/2
411/7/12/ST
516/12/14/ST
415/13/17/3
406

阵容可谓势均力敌;上面的胜率是 48.3% (平均存活随从造成英雄伤害 10.51), 下面是 44.13% (7.18), 平局 7.57%
当我们将下面的5 2偏折机器人+2 +2,就基本五五开了。上面: 46.31% (10.61), 下面: 46.6% (7.22), 平局 7.09%。当然胜率一样了,但是我们看到,平均英雄伤害量是不一样的,所以如果是最后决赛,还是上面的迎面大。就是权重看 胜率 * 伤害。这里我们将两个偏折机器人改为9 6, 9 4,基本上就让这个权重相当了。

要是说到战棋的插件,网上比较流行的酒馆插件应该就是HDT了,它的实现和我这里的思路又不太一样。比如双方的随从互相战斗,循环10000次,得到的频率和概率还是有偏差的。而HDT可以做到没有偏差,也就是说它在穷举所有可能,然后把胜率用这个可行解的树计算出来,这样做可以没有偏差,但是我们经常看到它有的时候一直在转圈圈loading,就是可能性太多,还没有穷举完,尤其是套娃流,复杂度很高。

其实结合了计算机视觉,不用截取炉石的网络包也可以做到得到当前随从,只是没有网络包截取稳定就是。但是现在门槛也低,弄个resnet yolo什么的稍加训练就可以得到一个图片提取模型了。

战棋这种游戏,虽然有运气带概率,performance计算机肯定最终是要比人类好的。能记录大量信息,能逆向服务器各种超参的概率,基本就赢了这个游戏。当然,游戏嘛,开心就好~

下面就给出一下小测评吧(在召唤概率所有随从相等的情况有):
拿6费的随从 大蛇 鬼妈妈 和 海盗船来说,看看单挑数据
大蛇 和 鬼妈妈 {a: 4511, b: 4258, tie: 1231} a 为第一个赢,b为第二个赢,tie为平手
大蛇 和 海盗船 {a: 4031, b: 4227, tie: 1742}
鬼妈妈 和 海盗船 {a: 3754, b: 4966, tie: 1280}
白板 和 大蛇 在白板到 7 17 的时候基本五五开
白板 和 鬼妈妈 需要 5 22 白板单挑
白板 和 海盗船 需要 6 20

想要咨询讨论指导的朋友,欢迎添加微信好友。添加时注明您的话题。谢谢。
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值