想写一个判断血量的简单AI,遇到一些问题
本帖最后由 weidongzi 于 2016-6-27 14:49 编辑这是一个夺塔小实验,塔1-7为腐败之塔,塔8为诅咒之塔(id为4480-4486以及4597)。代码如下:
(defconst Object-data-hitpoints 10)
(defrule
(true)
=>
(set-strategic-number sn-maximum-food-drop-distance 0)
(set-strategic-number sn-maximum-wood-drop-distance 0)
(set-strategic-number sn-maximum-gold-drop-distance 0)
(set-strategic-number sn-maximum-stone-drop-distance 0)
(set-strategic-number sn-percent-civilian-gatherers 0)
(set-strategic-number sn-percent-civilian-builders 0)
(set-strategic-number sn-percent-civilian-explorers 0)
(set-strategic-number sn-maximum-hunt-drop-distance 0)
(set-strategic-number sn-maximum-fish-boat-drop-distance 0)
(set-strategic-number sn-task-ungrouped-soldiers 0)
(set-strategic-number sn-total-number-explorers 0)
(disable-self)
)
(defrule
(true)
=>
(up-set-target-by-id c: 4484)
(up-get-object-data object-data-hitpoints towerHP1)
(up-set-target-by-id c: 4480)
(up-get-object-data object-data-hitpoints towerHP2)
(up-set-target-by-id c: 4481)
(up-get-object-data object-data-hitpoints towerHP3)
(up-set-target-by-id c: 4482)
(up-get-object-data object-data-hitpoints towerHP4)
(up-set-target-by-id c: 4497)
(up-get-object-data object-data-hitpoints towerHP5)
(up-set-target-by-id c: 4483)
(up-get-object-data object-data-hitpoints towerHP6)
(up-set-target-by-id c: 4485)
(up-get-object-data object-data-hitpoints towerHP7)
(up-set-target-by-id c: 4486)
(up-get-object-data object-data-hitpoints towerHP8)
)
(defrule
(true)
=>
(set-goal 1 0)
(set-goal 2 0)
(set-goal 3 0)
(set-goal 4 0)
(set-goal 5 0)
(set-goal 6 0)
(set-goal 7 0)
(set-goal 8 0)
(disable-self)
)
(defrule
(goal 1 0)
(up-compare-goal towerHP1 < 380)
=>
(chat-to-all "tower1中立" )
(set-signal 1)
(set-goal 1 1)
)
(defrule
(goal 1 1)
(up-compare-goal towerHP1 >= 380)
=>
(chat-to-all "tower1占领" )
(set-signal 2)
(set-goal 1 0)
)
(defrule
(goal 2 0)
(up-compare-goal towerHP2 < 380)
=>
(chat-to-all "tower2中立" )
(set-signal 3)
(set-goal 2 1)
)
(defrule
(goal 2 1)
(up-compare-goal towerHP2 >= 380)
=>
(chat-to-all "tower2占领" )
(set-signal 4)
(set-goal 2 0)
)
(defrule
(goal 3 0)
(up-compare-goal towerHP3 < 380)
=>
(chat-to-all "tower3中立" )
(set-signal 5)
(set-goal 3 1)
)
(defrule
(goal 3 1)
(up-compare-goal towerHP3 >= 380)
=>
(chat-to-all "tower3占领" )
(set-signal 6)
(set-goal 3 0)
)
(defrule
(goal 4 0)
(up-compare-goal towerHP4 < 380)
=>
(chat-to-all "tower4中立" )
(set-signal 7)
(set-goal 4 1)
)
(defrule
(goal 4 1)
(up-compare-goal towerHP4 >= 380)
=>
(chat-to-all "tower4占领" )
(set-signal 8)
(set-goal 4 0)
)
(defrule
(goal 5 0)
(up-compare-goal towerHP5 < 380)
=>
(chat-to-all "tower5中立" )
(set-signal 9)
(set-goal 5 1)
)
(defrule
(goal 5 1)
(up-compare-goal towerHP5 >= 380)
=>
(chat-to-all "tower5占领" )
(set-signal 10)
(set-goal 5 0)
)
(defrule
(goal 6 0)
(up-compare-goal towerHP6 < 380)
=>
(chat-to-all "tower6中立" )
(set-signal 11)
(set-goal 6 1)
)
(defrule
(goal 6 1)
(up-compare-goal towerHP6 >= 380)
=>
(chat-to-all "tower6占领" )
(set-signal 12)
(set-goal 6 0)
)
(defrule
(goal 7 0)
(up-compare-goal towerHP7 < 380)
=>
(chat-to-all "tower7中立" )
(set-signal 13)
(set-goal 7 1)
)
(defrule
(goal 7 1)
(up-compare-goal towerHP7 >= 380)
=>
(chat-to-all "tower7占领" )
(set-signal 14)
(set-goal 7 0)
)
(defrule
(goal 8 0)
(up-compare-goal towerHP8 < 500)
=>
(chat-to-all "tower8中立" )
(set-signal 15)
(set-goal 8 1)
)
(defrule
(goal 8 1)
(up-compare-goal towerHP8 >= 500)
=>
(chat-to-all "tower8占领" )
(set-signal 16)
(set-goal 8 0)
)
测试时遇到了这样的问题:
有请高手看一下,是不是我的代码写漏了什么。感谢!
AI出错的提示说的很清楚,是25行的位置,TowerHp1这个词没有定义。
实际上在使用目标变量存储数据的时候需要事先定义,方法和定义常数一样,使用defconst,需要定义的是TowerHp1这个词所带表的目标变量编号。
1.4的AI最多支持512个变量,但是一般个位数的变量我们会直接调用,比如下面这段:
(defrule
(true)
=>
(set-goal 1 0)
(set-goal 2 0)
(set-goal 3 0)
(set-goal 4 0)
(set-goal 5 0)
(set-goal 6 0)
(set-goal 7 0)
(set-goal 8 0)
(disable-self)
)
这里就把编号为1-8的变量全部设置成了0。
如果把这句话中的TowerHP1换成数字9,实际上就不会出错了…意思是把塔的HP存在了编号为9的变量里。
(up-set-target-by-id c: 4484)
(up-get-object-data Object-data-hitpoints TowerHP1)
但是如果数字编号直接使用过多,AI的可读性就会下降,到了后来作者自己都会忘了哪个变量存的是什么数据…所以一般我们自定义一个英文名来代表一个编号。
只需要在AI最开始的地方加一些编号定义:
(defconst TowerHP1 9)
(defconst TowerHP2 10)
(defconst TowerHP3 11)
等等
那么后面的语句就不会出错了。 条顿武士 发表于 2016-6-26 09:48
AI出错的提示说的很清楚,是25行的位置,TowerHp1这个词没有定义。
实际上在使用目标变量存储数据的时候 ...
谢谢解答。AI现在能读了,但是测试时又出了问题。我的触发这么做:
触发1:循环,开启
条件:AI信号1
效果:改变所有权,将塔换至中立玩家名下
触发2:循环,开启
条件:AI信号2
效果:改变所有权,将塔给玩家1
测试中,我把塔1HP削至不足20%,塔1归中立玩家,中立玩家发送消息“tower1中立”;
腐败之塔自动回血,达到20%,塔1归我,中立玩家发送消息“tower1占领”。
以上两步均符合先前设计。
但当塔1再次遭受攻击,HP不足20%,中立玩家也发送了“tower1中立”的消息,但此时塔1所有权循环归我(没法持续选中)。敌方连续攻击,直至塔1被毁。此时,中立玩家发送消息“tower1占领”。
这让我有点摸不着头脑,到底是哪里出了错。难道goal 1变量此时恒为0了?
PS:在AI版讨论触发不算太离题吧{:146:}。。。 weidongzi 发表于 2016-6-26 19:22
谢谢解答。AI现在能读了,但是测试时又出了问题。我的触发这么做:
触发1:循环,开启
是因为AI信号这个东西原理上比较奇怪。
(set-signal 1)
这句其实不是我们理解的发送AI信号1,而是把1号AI信号设为“开”。
相当于AI信号从1到255是255个开关,只有开和关两个状态。将一个AI信号设置为“开”之后,如果不手动关闭它,它就一直是“开”状态。而触发里面的“检测AI信号”条件实际上就是检测对应的信号是“开”还是“关”,如果是“开”就满足条件。
所以一开始箭塔血少于20%,1号AI信号开启,变成中立;之后箭塔回血,2号AI信号也开启,箭塔变回玩家1,这里都可以运行。但是之后无论箭塔HP怎么变化,实际上都是两个AI信号全部开启的状态,两个触发就一直满足条件循环运行…导致bug。
解决方法是手动添加一个关闭注销AI信号的语句:
(acknowledge-taunt this-any-computer X)
其中X的位置填入对应的AI信号编号即可。
比如下面语句中加入红色的部分:
(defrule
(goal 1 0)
(up-compare-goal TowerHP1 < 380) ; 血量削至腐败之塔20%以下。
=>
(chat-to-all "tower1中立" )
(acknowledge-taunt this-any-computer 2)
(set-signal 1) ; 发送AI信号,触发改变所有权,将塔换至中立玩家名下。
(set-goal 1 1)
)
(defrule
(goal 1 1)
(up-compare-goal TowerHP1 >= 380) ; 血量恢复至腐败之塔20%以上。
=>
(chat-to-all "tower1占领" )
(acknowledge-taunt this-any-computer 1)
(set-signal 2) ; 发送AI信号,触发改变所有权,将塔换至占领玩家名下。
(set-goal 1 0)
) ; 以下塔2-8原理相同。
AI信号1开启之前先关闭2,同样2开启之前先关闭1,这样就不会出现1和2同时开启的情况了。
本帖最后由 一窍不开 于 2016-6-26 20:43 编辑
条顿武士 发表于 2016-6-26 20:11
是因为AI信号这个东西原理上比较奇怪。
(set-signal 1)
印象里这个set-signal是无法被取消的。
建议楼主使用资源法进行联动。 一窍不开 发表于 2016-6-26 20:40
印象里这个set-signal是无法被取消的。
建议楼主使用资源法进行联动。
啊,我想起来了…
那么就只能使用资源和触发连接了,用cc-add-resource动作使AI作弊增加资源,然后用触发检测资源实行命令,最后用触发清零资源保证可以多次触发。
把(set-signal 1)换成(cc-add-resource <资源种类> <数量>) ,资源种类只能是是以下其中一项:
food(食物)
gold(黄金)
stone(石头)
wood(木材)
触发检测到电脑玩家有某项资源之后,进贡这项资源给盖亚,然后执行效果即可。
由于资源栏数量有限,所以楼主可以考虑使用下面的方法来检测8个箭塔。
cc-add-resource 100石头 1木材 替代(set-signal 1)
cc-add-resource 99石头 2木材 替代(set-signal 2)
等等
以此类推…检测资源的时候使用两个条件来检测即可。 感谢楼上的高手们。可惜正常采集资源的玩家无法借助资源法判定。目前除了资源法还有没有方便AI与触发进行交互的方法呢?另外,进贡的资源真的只能是这四种基本资源吗?既然Aokts可以启用隐藏资源,那么理论上来说AI也可以吧? weidongzi 发表于 2016-6-27 14:38
感谢楼上的高手们。可惜正常采集资源的玩家无法借助资源法判定。目前除了资源法还有没有方便AI与触发进行交 ...
可以使用cc-add-resource作用于隐藏资源,后面依次填入资源编号和数量即可。
但是有些隐藏资源会在游戏中改变,尽量不要用,比如杀敌数之类的,而相对安全的隐藏资源,比如56号资源矿物,和15号资源肉量都是相对稳定的,可以利用。
(cc-add-resource 56 1)
(cc-add-resource 15 100)
然后用触发检测这些资源就好了~方法和普通资源是一样的,需要用到触发工作室AOKTS。
可以判断血量的AI?太支持了{:149:}{:149:}{:149:}
本来打算做一个,何奈对AI一窍不通{:156:}
楼楼做好了一定要发布出来注明使用方法,期待{:154:} 另外楼主可以考虑加入翔鹰活跃的战役制作者QQ群498122293,大家一起讨论会比较及时的解决一些制作上的问题~ 条顿武士 发表于 2016-6-27 19:26
另外楼主可以考虑加入翔鹰活跃的战役制作者QQ群498122293,大家一起讨论会比较及时的解决一些制作上的问题~
哈哈,荣幸之至~
页:
[1]