翔鹰帝国网|帝国时代论坛|帝国时代系列|神话时代
 找回密码
 注册翔鹰会员(昵称)
搜索
查看: 5376|回复: 17

[教程] 常数和GOAL配合——AI编写的利器

  [复制链接]

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
发表于 2009-8-31 08:41:44 | 显示全部楼层 |阅读模式
相信学过编程语言的都清楚,在编程时,往往要用到许多变量,要给他们赋值。而帝国时代的AI语言中,同样也有变量(受到AI官方教程的影响,我喜欢把它叫常数,虽然他是可变的。以下还是叫做常数吧!)。那么,常数到底有什么作用呢?简单地说,常数的用处有以下几点:

1.把常数作为条件的一部分,看成不成立。这一个用处的例子有很多,例如:
(defconst G_YES 1)                              
(defconst G_NO 0)      

(defconst gold-on-map 13)
(defconst stone-on-map 14)
(defconst stone-mine 102)        
(defconst gold-mine 66)  
………………
(定义的前两个常量只是为了表示“是”和“不是”。而13、14等式表示GOAL的编号
然后,就是设置初始值:
(defrule
  (true)
=>
   (set-goal gold-on-map G_YES)  
  (set-goal stone-on-map G_YES)
  (disable-self)
)

上面的语句等价于
(defrule
  (true)
=>
   (set-goal 13 1)  
  (set-goal 14 1)
  (disable-self)
)

然后下面是判断语句:

(defrule
  (cc-players-unit-type-count 0 gold-mine < 2)
=>
  (set-goal gold-on-map G_NO)
  (disable-self)
)

(defrule
  (cc-players-unit-type-count 0 stone-mine < 2)
=>
  (set-goal stone-on-map G_NO)
  (disable-self)
)


上面的语句等价于
(defrule
  (cc-players-unit-type-count 0 gold-mine < 2)
=>
  (set-goal 13 0)
  (disable-self)
)

(defrule
  (cc-players-unit-type-count 0 stone-mine < 2)
=>
  (set-goal 14 0)
  (disable-self)
)


(以上的意思是,当盖亚的金矿数小于等于2的时候,就把GOAL编号为gold-on-map(也就是13)的值设为G_NO(也就是0)。当盖亚的石矿数小于等于二的时候,就把GOAL编号为stone-on-map(也就是14)的值设为G_NO(也就是0)
(如果有不了解GOAL的 请稍等,在本文最后将会提到)

如何利用这个常数呢?请看:

(defrule
  (current-age == imperial-age)
  (goal gold-on-map G_YES)
  (goal stone-on-map G_YES)
=>
  (set-strategic-number sn-food-gatherer-percentage 40)
  (set-strategic-number sn-wood-gatherer-percentage 25)
  (set-strategic-number sn-gold-gatherer-percentage 30)
  (set-strategic-number sn-stone-gatherer-percentage 5)
  (set-strategic-number sn-maximum-food-drop-distance 25)
  (set-strategic-number sn-maximum-wood-drop-distance 25)
  (set-strategic-number sn-maximum-gold-drop-distance 15)
  (set-strategic-number sn-maximum-stone-drop-distance 15)
  (disable-self)
)


(defrule
  (current-age == imperial-age)
  (goal gold-on-map G_NO)
  (goal stone-on-map G_NO)
=>
  (set-strategic-number sn-food-gatherer-percentage 50)
  (set-strategic-number sn-wood-gatherer-percentage 50)
  (set-strategic-number sn-gold-gatherer-percentage 0)
  (set-strategic-number sn-stone-gatherer-percentage 0)
  (disable-self)
)


看!常数就可以用来当条件了!当那个GOAL的值为XX时,就执行XX语句!
如果还有金子,村民们就40%采集食物,25%砍树,30%采金,5%采集石头。
如果没有金子,村民们就一半采集食物,一半砍树。
为什么我们不把
(goal gold-on-map G_NO)

换成

(cc-players-unit-type-count 0 gold-mine < 2)

呢?
因为这样一来,假设后来测试AI的时候,你发现小于2好像不好,要改成3。如果你是用后者的写法,你要把每一个这样的语句中的2换成3。而用前者的写法,只要把
(defrule
  (cc-players-unit-type-count 0 gold-mine < 2)
=>
  (set-goal gold-on-map G_NO)
  (disable-self)
)


里面的2换成3就可以,只用改一个值!这就是常数的便利之处!







2.常数与随机数相结合(实际上也是用GOAL)。


这一点的意思可能很难讲清楚(我表达力不行),直接看代码!
     ; 定义常数
(defconst feudal-age-rush 1)
(defconst castle-age-rush 2)

; 首次演算:设置一个介于 1 100 之间的随机数。

(defrule

(true)


=>


(generate-random-number 100)


(disable-self)

)

; 由其结果决定战略
; 20% 机会进行封建时代快攻
; 80% 机会进行城堡时代快攻

(defrule

(random-number > 80)


=>


(set-goal 1 feudal-age-rush)


(disable-self)

)

(defrule

(random-number < 81)


=>


(set-goal 1 castle-age-rush)


(disable-self)

)


看了代码,你应该就明白了。这是用随机数来确定进行城堡RUSH还是封建RUSH,然后把GOAL 1 的值设为XX。

其实还有一点不知道大家想过没有,第一个例子中的:
(defconst stone-mine 102)        
(defconst gold-mine 66)

102,就是石矿的数字代码,66就是金矿的数字代码!

也许你已经想到了!没错!我们可以定义某个没法用英文表示的单位!(说的糊里糊涂的)
例如:
(defconst man-hunter 122)
(defconst woman-hunter 216)  
然后呢?我们可以这么写:

(defrule
    (building-type-count-total mill == 1)
    (or (unit-type-count man-hunter > 0)      
          (or (unit-type-count woman-hunter > 0) )
     (can-build mill)
=>
   (set-strategic-number sn-mill-max-distance 35)
   (build mill)
(disable-self)
)
看吧!只要一开始先定义某个常数(为了方便名称应该要有点意义)的值为那个单位的ID,然后就可以用那个常数的名字代替那个单位的ID,这样你下次再看的时候,就不会因为忘记了那个数字ID的含义而到处找了!(各种建筑和单位的数字ID看这里:https://www.hawkaoe.net/bbs/thread-23845-1-1.html

好吧,,下面我来详细讲解一下GOAL的用法。

大家有没有发现,我用常数很多都和GOAL结合了。的确,常数可以说是GOAL的亲密伙伴啊!!

那么,什么是GOAL呢?
通俗地说,GOAL就是一个个箱子,每个箱子都有一个编号。编号可以是1到40中的一个。每个箱子只能够放一个数。
GOAL语句有下面两个:
(set-goal GOAL的编号 要设的数)
(goal GOAL的编号 要检查的数)
上面两个语句第一个是一个动作,用处是把相应的GOAL的值设置为XX
第二个是一个条件 是检查一下那个GOAL的值是否为XX

打个比方 (set-goal a b)就相当于在编号是a的箱子里放一个b数。
(goal a b)就相当于去看一下编号是a的箱子里的数是不是b

其中a的要求是1到40     b的值大概没有要求(如果只是用于表示“是”或者“否”,一般为了方便都用0或1)

有的人可能要问了:那直接用数字不就行了么?为什么还要定义常数呢?那么麻烦!

举个例子吧,当你修改自己的AI,看到(set-goal 25 1)这一句话,你能记起来编号是25的GOAL用处是什么吗?记不得吧!
可是如果你看到(set-goal goal-resign yes) 这一句话,你就马上能够知道,这句话的意思是准备要投降啦!
可是你光这么写,AI可不认识他啊!怎么办呢?这就要用到常数啦!
(defconst goal-resign 25)
上面这句话用处可大了!有了它,AI就会把遇见的goal-resign都看做25来处理!同样地有了(defconst yes 1)这句话,AI就会把yes当做1处理了!
这么一来 你就可以用(set-goal goal-resign yes) 这句话了!

下面来讲一下实际的高级应用:


应用之一:看对方出什么兵,就把GOAL值改成一个数。例如:
(defconst enemy-soilder 1)
(defconst g-knight 1)
(defconst g-archer 2)
(defconst g-spear 3)



....
(defrule
(players-unit-type-count knight-line >= 8)
=>
(set-goal enemy-soilder g-knight)
)
(defrule
(players-unit-type-count archer-line >= 15)
=>
(set-goal enemy-soilder g-archer)
)
(defrule
(players-unit-type-count spearman-line >= 6)
=>
(set-goal enemy-soilder g-spear)
)

然后再根据GOAL的不同值来应对
(defrule
(goal enemy-soilder g-knight)
=>
(.......)
)
(defrule
(goal enemy-soilder g-archer)
=>
(.......)
)
(defrule
(goal enemy-soilder g-spear)
=>
(.......)
)


还可以把升级年代的时候把某个GOAL设为1,然后升完设置回去。然后写当常数为1就出兵或研究科技(怕不够食物或者黄金所以等到升级年代时候才出兵或研究科技。这里不再说了。

先写这么多 不懂就提问吧

[ 本帖最后由 老胡V1 于 2010-1-9 12:40 编辑 ]
心烦意乱。静下来吧。
回复

使用道具 举报

96

主题

0

精华

1610

积分

侯爵

耕战
194
鹰币
169
天龙币
0
回帖
870

翔鹰建站十周年纪念章

附庸关系0
发表于 2009-9-26 15:55:35 | 显示全部楼层
寫的的太深奧了,看的不大懂
回复

使用道具 举报

55

主题

2

精华

3257

积分

公爵

耕战
277
鹰币
207
天龙币
0
回帖
609

二级嘉禾勋章雏鹰勋章

附庸关系0
发表于 2009-10-30 21:53:45 | 显示全部楼层
真是太强大了!:10:
寒风声萧萧看江山景色渺
细雨纷纷送夕照
愿一生清风两袖   
偏偏心中多少扑朔恩怨未忘掉
我愿平静谁知晓
结伴明月尝哭笑
回复

使用道具 举报

33

主题

0

精华

2334

积分

侯爵

耕战
389
鹰币
355
天龙币
0
回帖
181
附庸关系0
发表于 2009-11-1 19:12:34 | 显示全部楼层
看不懂…:35: :35: :35: :35:
回复

使用道具 举报

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
 楼主| 发表于 2009-11-1 22:31:08 | 显示全部楼层
建议你先看看AI教程,在下载中心有。看完后应该会对AI有不小的了解。只要看基础格式和简单命令就可以了,一些复杂的条件或命令可以慢慢理解,也不一定要背,需要时候看就行了。当然一些兵种 建筑 的英文最好记几个,尤其是常用的。另外TRAIN BUILD 这些也最好记住(记不住就怪了)。其实最好是自己编一个,这样理解更快,不必写得很好,能让自己理解那些语句的意思就行。也可以参考别人的AI,利用教程来弄懂别人的语句的意思,理解他人思路,会对自己有不小帮助。
心烦意乱。静下来吧。
回复

使用道具 举报

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
 楼主| 发表于 2009-12-4 21:04:47 | 显示全部楼层
24……上次发现有错就重新写了,谁知道一恢复就没掉了55555
只好重新写 可是思路已经回不来了
暂且写了这些 不懂就提问吧……
心烦意乱。静下来吧。
回复

使用道具 举报

36

主题

1

精华

8394

积分

国王

耕战
1457
鹰币
650
天龙币
0
回帖
542

三级嘉禾勋章十字军勋章

附庸关系0
发表于 2010-1-11 19:25:48 | 显示全部楼层
上次用goal定义计时器,居然没有反应……
回复

使用道具 举报

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
 楼主| 发表于 2010-1-11 21:34:24 | 显示全部楼层
GOAL和定时器作用不太吧…只是条件。主要是用defconst,来用常数表示定时器,例如(enable-timer a 30)
心烦意乱。静下来吧。
回复

使用道具 举报

36

主题

1

精华

8394

积分

国王

耕战
1457
鹰币
650
天龙币
0
回帖
542

三级嘉禾勋章十字军勋章

附庸关系0
发表于 2010-1-13 11:54:59 | 显示全部楼层
嗯,知道是条件。但定义后拿那个名字来用发现游戏时没作用。所以我还是老老实实直接用数字了&
回复

使用道具 举报

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
 楼主| 发表于 2010-1-13 12:49:54 | 显示全部楼层
- -
能把你的代码给我看下吗……

用计时器应该是这样的吧……
(仅供参考)

(defconst TIMER-ATTACK 2)

(defrule
(XXXX)
=>
(enable-timer TIMER-ATTACK 30)
(disable-self)
)

(defrule
(timer-triggered TIMER-ATTACK)
(XXXX)
=>
(attack-now)
(enable-timer TIMER-ATTACK 30)
)
心烦意乱。静下来吧。
回复

使用道具 举报

36

主题

1

精华

8394

积分

国王

耕战
1457
鹰币
650
天龙币
0
回帖
542

三级嘉禾勋章十字军勋章

附庸关系0
发表于 2010-1-15 11:52:07 | 显示全部楼层
我的就是这样。原代码已经改了,也不用发。可能是我后面什么地方用冲突了
回复

使用道具 举报

78

主题

13

精华

2万

积分

圣徒

耕战
2683
鹰币
182
天龙币
0
回帖
1957

二级皇家勋章一级嘉禾勋章二级帝国勋章十字军勋章雄鹰勋章活跃者使者勋章

附庸关系0
 楼主| 发表于 2010-1-15 11:59:37 | 显示全部楼层
注意一下吧 看看是不是重复使用了计时器……代码太长很容易出现这种情况 最好把用了的列个表
心烦意乱。静下来吧。
回复

使用道具 举报

10

主题

0

精华

1074

积分

伯爵

耕战
89
鹰币
70
天龙币
0
回帖
325

活跃者

附庸关系0
发表于 2010-2-13 13:12:54 | 显示全部楼层
常量吧- -常数只限于数字............
回复

使用道具 举报

7

主题

0

精华

169

积分

男爵

耕战
7
鹰币
81
天龙币
0
回帖
78
附庸关系0
发表于 2011-6-23 20:55:49 | 显示全部楼层
本帖最后由 粹纳帝国 于 2011-8-25 22:42 编辑






                                    .
回复

使用道具 举报

0

主题

0

精华

0

积分

流徒

耕战
0
鹰币
63
天龙币
0
回帖
10
附庸关系0
发表于 2011-7-23 14:21:38 | 显示全部楼层
看看吧,大家都会支持你













论坛群发软件
回复

使用道具 举报

22

主题

0

精华

1782

积分

侯爵

耕战
219
鹰币
113
天龙币
0
回帖
520
附庸关系0
发表于 2011-8-16 13:27:15 | 显示全部楼层
还好有点编程基础,慢慢琢磨吧
QQ:316793523
回复

使用道具 举报

2

主题

0

精华

30

积分

骑士

耕战
0
鹰币
23
天龙币
0
回帖
54
附庸关系0
发表于 2011-8-24 21:10:19 | 显示全部楼层
看不懂啊高人啊
回复

使用道具 举报

6

主题

0

精华

808

积分

伯爵

耕战
130
鹰币
2012
天龙币
0
回帖
70

翔鹰建站十周年纪念章

附庸关系0
发表于 2014-11-7 19:12:42 | 显示全部楼层
还好,学过编程语言,看懂了。找时间练练
吾之所行,皆是开创之路。人生的乐趣就在于冒险,就在于一切都是未知数。
回复

使用道具 举报

本版积分规则

排行榜|小黑屋|翔鹰帝国

GMT+8, 2024-4-29 04:58 , Processed in 0.230920 second(s), 196 queries , File On.

Powered by Hawk Studio  QS Security Corp.® Licensed

Copyright © 2001-2023, Hawkaoe.net All Rights Reserved

快速回复 返回顶部 返回列表