俄罗斯方块人工智能 [ AI ]

SSDUT 小学期大作业,计划用 C++ 完成俄罗斯方块,用 QT 实现用户界面。实现基本功能后有多余时间,就加了 AI 的模块。目前的算法经测试,可以实现 25万 行左右的消除,在改进方块生成随机函数 (BAG7) 后,消除的行数会有大幅增加。

效果预览:

                   

以下是正文:

算法选取

实现 AI 的算法我考虑了两种,在其中权衡:

  • Pierre Dellacherie算法,求出一些参数,基于评估函数实现,每次只考虑当前情况的最优解
  • 搜索,基于DFS,用A*剪枝优化,结合多步的情况

DFS 需要优化的地方很多,假如计算的层数不够、没有高效的剪枝,一不小心容易写成人工智障,时间复杂度也不好。

Pierre Dellacherie算法更加清晰,复杂度更低。虽然不是很符合我的存储结构,但经过修改还是可以很好实现。

方块存储

我存储方块的模式比较简单暴力,直接放在数组矩阵里。共有 7 种方块,方块经过旋转形状不同,也分开存储。因此,共需要存 19 组数据来记录所有的方块。

以 “L” 形方块为例:

            "#3##",        //表示同一种方块的不同旋转
            "#3##",
            "#33#",
            "####"        
        
            "####",
            "333#",
            "3###",
            "####"
      
            "33##",
            "#3##",
            "#3##",
            "####"
           
            "##3#",
            "333#",
            "####",
            "####"

网上许多的方案是在确定一个中点(旋转点)之后,给出其他块的相对位置来表示形状,旋转时也是通过位置参数的变化实现。我这里虽然有些暴力但是可以减少很多计算。Pierre Dellacherie算法中的一个参数也需要用到中点这一概念,但很明显我的存储结构中没有维护中点这一概念。但其实也并不需要,我们可以简单修改此参数的获取规则,实现相同的作用。

Pierre Dellacherie算法

该算法只考虑当前,不对未来的情况进行计算。注重的是“不死性”,追求方块的“密集”,有时就算可以一次性消除 3 行,却会使全局方块更加“疏”,算法是不会在这种情况落子的。

每次生成一个方块,便穷举该方块所有旋转的所有落点。一种方块最多有 4 种旋转,并且由于游戏界面是 10 * 20 的,所以对于每个旋转形状,只需要考虑  10 种落点,故需要考虑的情况不多。加上剪枝后,穷举法也变得十分可观。

算法的核心是一个评估函数。对穷举出的每一种下落情况,计算 6 个参数值,用评估函数加权求和得到一个值,该值最大的情况便是目前方块的最优下落位置。

六个参数分别是:

  • Landing height 

表示方块下落后高度的参数 (相对于底部的高度)

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值