步步为营桌游算法实现

来自我的知乎文章:https://zhuanlan.zhihu.com/p/127782718

CSDN插入视频不方便,就简单回忆下过程了

最近整理文档,发现了18年参加的智能车竞赛写的一个游戏算法,这是我第一次写的一个超过1000行代码程序,当时也是完全没有接触过算法上的东西,一边学一边写磕磕碰碰竟然也把这个事情做成了。现在上了研究生,遇到的都是控制理论这方面的东西,算法未来应该是不会再接触了,把当时的思路在这里整理一下 也算对这个方向画个句号了。

当年决赛的题目是 步步为营 桌游的对抗,挺益智的一款桌游(当时队友写代码写得头大的时候会来放松一下hh),简单描述一下规则:

刚开始己方和对方的棋子都在底部中间,每个回合可以选择放置挡板或者移动,谁先走到对面就获胜,但是放置挡板的时候不能把对方的路堵死。淘宝上有卖这个桌游的,长这样:

步步为营桌游算法实现_第1张图片

比赛需要制作小车搬运棋子和障碍完成对抗,我正好是团队里面负责算法这一块的,花了一个多月的时间勉勉强强写完了这个游戏,水平也大概是初级玩家的水平,如果要真动动脑子,还是可以击败电脑的。

18年正好是Alpha-Go大热的时候,最开始就打算用增强学习这一套逻辑来实现,自己和自己下棋,在训练的过程中逐步提高智力水平,因为评估函数是比较明显的,谁先到达对岸谁就赢了,那么只要把最后一步的评估值设为100,再根据之前的决策推导应该就可以了。

然而真正实现的时候发现没有那么简单。

我用的是Q-Learning算法,最终是要得到一个Q-table表的。卓晴大大可能也是考虑到算法复杂度的问题,我们当时的棋盘格是7X7大小的。即使是缩小版本的,这个Q-table表的状态和动作信息依然非常庞大。需要考虑的状态包括己方的位置、对手的位置、场上挡板的位置,7*7的棋盘里,水平/竖直放置挡板,有36个位置可以摆放,有放置或者不放置两种选择,那么光状态就49*49*2^{72}  种情况,这也太复杂了!

这种情况根本不可能做训练,所以做了简化。把棋子的位置(49种情况)改成到对岸的直线距离(7种情况),放置挡板只考虑在棋子位置的正前方/左边/右边范围内放置,那么此时的状态大小为: 7*7*2*2*2*2*2*2=3136 种情况,棋子可选择的动作有上下左右移动+放置挡板(在棋子正前方/左侧/右侧)一共有16种动作。

如此大规模的简化后至少在训练上看到了可行性,但是跑了一个晚上的训练之后,棋子的水平依旧很智障。

走到了这一步已经花掉了我差不多一个月的时间,离比赛大概还有两周时间,只好按照自己的思路莽。

思路其实很简单,首先在每一次决策之前先判断场上的局势,也就是计算己方和对手到对岸最少需要走多少步,这里要用到寻路算法。然后假设在每一个有效位置放置挡板,计算放置这块挡板以后己方和对手到对岸需要的新的步数,如果对手增加的步数大于己方的步数,那么说明这一块挡板放得有价值。可以执行。

但是这样的决策只考虑了未来一步的情况,一个典型的“贪心算法”,当前的决策只做下一步看起来最优的情况,这样的考虑不太够,于是再循环一次,考虑两步棋局,虽然还是很low,但是至少看起来的决策没有那么傻。

你可能感兴趣的:(控制理论,算法,步步为营,决策,棋类)