魔塔小游戏中的AI(五)

在前面的几篇博客中,已经基本介绍了对于单层塔(低层塔),在不考虑商店的情况下,实现一个AI。

这一篇博客主要是对商店进行讨论。

商店的实现

商店的实现比较简单,我们需要给勇士和怪物们都加上“金币”属性;并在每次合并节点时也将金币合并进去。

[java]
1
2
3
4
5
6
7
public void visit(Node node) {
    if (!visited[node.id] && current.linked.remove(node)) {
        for (Monster monster: node.monsters)
            current.hero.money+=monster.money;
        visited[node.id] = true;
    }
}

然后给State增加一个标记shopTime,表示当前已经使用了多少次商店;尚未开启商店时其值为-1。

然后在地图上定义一个商店。商店可视为一个特殊的Item,当获得其时将shopTime标记为0。

有关商店的使用,我们主要是使用贪心算法,也就是一旦能使用商店立刻使用,不留金币;可以将其写入eatItem函数内后,在贪心地吃完所有宝物后,立刻使用商店。

商店加点算法

商店的算法其实是最难的。也就是,如何判断当前应该是加攻、加防还是加血呢?

我们不能使用搜索(对加攻、加防和加血都搜一遍),否则就进入了深度搜索的怪圈,这是我们不能接受的。

因此,最好有一种贪心算法,直接能根据地图当前状态来决定加什么。

这个问题很难,目前还没有一个很好的解决方式,暂时只有如下几种想法:

攻防和判断

和当前地图上所有怪物进行比较;若勇士的攻防和不大于怪物的加权平均攻防和,则加攻,否则加防。

===> 这个是有依据的:【数学】魔塔中增加攻击还是增加防御的数学证明,但是事实上也没有多大的意义。

这个算法比较简陋,而且“攻击不过临界值则无用”的条件摆在这里,一概而论不太合适。

减伤量判断

这个算法相对比上面要更靠谱一点。

和当前地图上所有怪物进行比较,比较加攻击和加防御后,所有怪物的减伤量的加权平均值。

如果加攻不过临界,减伤量可以视为 “下一个临界的减伤量/到下一个临界的攻击差*当前攻击增加量”

这样优点是直接考虑了加攻和加防的减伤量,但是缺点是仍不靠谱,因为“攻击不过临界值则无用”。

临界值判断

这个算法更暴力。

首先计算每个怪物的临界值,然后选取某个临界值作为加攻的终极目标。

每当商店选择加点时,如果攻击力小于目标临界值则加攻,大于则加防。

这个“临界值”可以由算法给出,也可以人工手动自行给定。

 

 

其实,对于商店上应该加攻还是加防,并不会有一个很好的数学公式存在,更多的还是要靠拆塔时的“感觉”。

AI只是一个辅助拆塔工具,不能完全依赖它,所以最好的方法还是,自己先尝试拆一拆塔,确定商店的加点方向,然后再使用AI去寻找最佳路线。

 

大家可以关注我的开源项目https://github.com/ckcz123/magic-tower-AI/,star或fork一下,感谢支持~

如果您有什么意见建议,或者比较好的想法的话,欢迎邮件至ckcz123@126.comckcz12345@gmail.com与我联系,也可以在魔塔吧官方交流QQ群里搜索“小艾”联系到我。期待对于AI,有与您的进一步交流~