春田一九零三 发表于 2021-4-9 00:00:23

据点防御AI

本帖最后由 春田一九零三 于 2021-4-9 00:17 编辑

之前为了某战役(烂尾)定置的AI。可以供需要的人参考。注意并非所有变量都有用。主要是考虑到多个AI共存的情况才做了定义。
如果需要公用,可以在defconst中把变量对应的数字修改掉(当然如果缺乏ai基础可能不知道吾辈在说什么{:163:})

据点防御AI:
主要是代替传统TSA,每个AI玩家只能围绕一个TC展开防守的问题。
这个AI可以防御复数据点,并且为每个据点配置防御半径,并且他只会防御会移动的攻击单位,因此不会被建筑物吸引走。。。

;// 单位不动(简单版) //
(defrule
    (true)
=>
    (set-strategic-number sn-maximum-food-drop-distance -2)
    (set-strategic-number sn-maximum-wood-drop-distance -2)
    (set-strategic-number sn-maximum-gold-drop-distance -2)
    (set-strategic-number sn-maximum-stone-drop-distance -2)
    (set-strategic-number sn-maximum-hunt-drop-distance -2)
    (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-fish-boat-drop-distance -2)
    (set-strategic-number sn-task-ungrouped-soldiers 0)
    (set-strategic-number sn-total-number-explorers 0)
    (set-strategic-number sn-relic-return-distance 0)
    (disable-self)
)

;// 敌作战能力 //
(defrule
    (true)
=>
    (set-difficulty-parameter ability-to-maintain-distance 0)
    (set-difficulty-parameter ability-to-dodge-missiles 0)
    (set-strategic-number sn-percent-enemy-sighted-response 100)
    (set-strategic-number sn-enemy-sighted-response-distance 32)
    (disable-self)
)

;// 据点防御:召集半径X内的我方闲置单位,巡逻攻击同范围内发现的敌方单位 //

(defconst gl-point-x 100)       ;探测玩家信号座标x
(defconst gl-point-y 101)       ;探测玩家信号座标y
(defconst gl-point-x2 102)       ;转存玩家信号座标x,作为最终目标
(defconst gl-point-y2 103)       ;转存玩家信号座标y,作为最终目标
(defconst gl-point-x3 104)       ;设置的当前进攻座标x
(defconst gl-point-y3 105)       ;设置的当前进攻座标y
(defconst gl-point-x4 106)       ;设置ai的集结出发点x
(defconst gl-point-y4 107)       ;设置ai的集结出发点y
(defconst gl-point-A 108)       ;过渡用变量A
(defconst gl-point-B 109)       ;过渡用变量B
(defconst gl-faith 110)       ;队伍信心
(defconst gl-point-r 111)       ;探测半径
(defconst gl-player 112)       ;搜索的目标玩家
(defconst gl-enemy-unit-detect 113)      ;搜索到可攻击的敌人单位数
(defconst gl-local-total 120)
(defconst gl-local-last 121)
(defconst gl-remote-total 122)
(defconst gl-remote-last 123)
(defconst gl-random-number 124)       ;随机数

(defconst search-local 1)       ;搜索源常数:本地
(defconst search-remote 2)       ;搜索源常数:远方
(defconst stance-aggressive 0)       ;进攻状态常数:进攻
(defconst action-patrol 2)       ;行动编号常数:巡逻
(defconst position-object 12)       ;位置类型常数:物件
(defconst actionid-enter 617)       ;行动编号常数:进入(驻扎)
(defconst object-data-index -1)       ;up-remove-objects专用
(defconst object-data-action 5)       ;单位动作
(defconst object-data-target-id 23)      ;单位目标
(defconst object-data-tasks-count 32)      ;单位获得任务数
(defconst object-data-attacker-count 33)   ;单位的攻击数
(defconst object-data-next-attack 55)      ;单位正在交战
(defconst object-data-group-flag 73)      ;单位所属组0-9,无为-2
(defconst flare 274)      ;信号
(defconst king-class 959)       ;国王类
(defconst infantry-class 906)       ;步兵类
(defconst archery-class 900)       ;弓箭手类
(defconst archery-cannon-class 944)      ;火枪手类
(defconst cavalry-class 912)       ;骑兵类
(defconst cavalry-archer-class 936)      ;骑射手类
(defconst cavalry-cannon-class 923)      ;征服者类
(defconst siege-weapon-class 913)      ;攻城武器类


(defconst POINT 201)      ;据点编号
(defconst POINT-max 202)       ;最大据点数量

;// 据点防御初始化 //

(defrule
    (true)
=>
    (set-goal POINT 0)      ;据点未开启防御模式,编号0
    (set-goal POINT-max 2)       ;设定最大据点数量
    (disable-self)
)

;// 据点防御开启 //

(defrule
    (game-time greater-than 4)       ;游戏时间经过4秒(防开局加资源)
    (goal POINT 0)          ;据点防御模式未开启
    (stone-amount >= 100)       ;配合触发,AI玩家拥有100石开启据点防御
    (stone-amount < 200)
=>
    (cc-add-resource stone -100)      ;清除石头指令
    (enable-timer 1 0)      ;激活定时器1,时间为0秒(立刻启动)
    (set-goal POINT 1)      ;从据点1开始计算
    (chat-to-all "据点防御开启")
)

(defrule
    (up-compare-goal POINT g:== POINT-max)   ;开启过据点防御,并且遍历过至少一次
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (set-goal POINT 1)      ;重置当前据点编号为1
)

;// 据点防御开启-循环起点A //
;// 据点1:上方村庄(94,47),防御半径20 //
;// 据点2:下方港口(45,82),防御半径10 //
;// 复制下方段落实现扩展,并修改最后的jump差值 //

(defrule
    (up-compare-goal POINT c:== 1)
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-modify-goal gl-point-x c:= 94)      ;读取据点1座标x
    (up-modify-goal gl-point-y c:= 47)      ;读取据点1座标y
    (up-modify-goal gl-point-r c:= 20)      ;读取据点1防御半径r



(defrule
    (up-compare-goal POINT c:== 2)
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-modify-goal gl-point-x c:= 45)      ;读取据点2座标x
    (up-modify-goal gl-point-y c:= 82)      ;读取据点2座标y
    (up-modify-goal gl-point-r c:= 10)      ;读取据点2防御半径r
)

;// 查找敌人目标 //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (set-goal gl-player 1)       ;初始化搜索从玩家1开始
    (up-set-target-point gl-point-x)      ;将据点座标设置为搜索圆点
    (up-full-reset-search)       ;重置直接寻的系统的搜索索引和筛选状态、搜索状态
    (up-get-search-state gl-local-total)   ;重置搜索数量
;   (up-chat-data-to-all "目前据点的X座标是 %d 点" g: gl-point-x);汇报座标
;   (up-chat-data-to-all "目前据点的Y座标是 %d 点" g: gl-point-y)
)

;// 查找敌人目标-循环起点B //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-modify-sn sn-focus-player-number g:= gl-player)    ;设置当前玩家为焦点玩家
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (or (players-stance focus-player enemy)   ;只侦察敌对或中立玩家
(players-stance focus-player neutral))

=>
    (up-filter-distance c: -1 g: gl-point-r)   ;设置搜索半径
    (up-filter-include 4 -1 -1 -1)      ;只搜寻会移动的军事单位
    (up-find-remote c: -1 c: 40)      ;上限40
    (up-remove-objects search-remote object-data-action == actionid-enter)      ;忽略已经驻军的单位
;   (up-chat-data-to-all "我在探测 %d 号玩家" g: gl-player)   ;汇报玩家侦察情况
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-get-search-state gl-local-total)   ;记录搜索数量
    (up-reset-filters)      ;重置过滤器(每次filters后都应当重置才不会出错)
    (up-modify-goal gl-player c:+ 1)      ;搜索下一个玩家
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-compare-goal gl-player c:<= 8)
    (up-compare-goal gl-remote-total c:< 40)
=>
    (up-jump-rule -4)      ;跳回循环起点B
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-get-search-state gl-local-total)   ;记录搜索数量
    (up-modify-goal gl-enemy-unit-detect g:= gl-remote-total)
    (up-get-precise-time 0 gl-random-number)   ;利用系统时间生成伪随机数
    (up-modify-goal gl-random-number g:mod gl-remote-total)   ;伪随机数除以搜索个数得到其中1个
    (up-chat-data-to-all "我找到了 %d 个敌人" g: gl-remote-total);汇报玩家防御情况
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-compare-goal gl-random-number c:< 0)
=>
    (up-modify-goal gl-random-number c:* -1)
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-compare-goal gl-remote-total c:>= 1)
=>
    (up-remove-objects search-remote object-data-index g:!= gl-random-number) ;只瞄准一个单位
    (up-set-target-object search-remote c: 0)   ;将该单位设为目标单位
    (up-get-point position-object gl-point-x2)   ;将该单位座标存入x2
)

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-compare-goal gl-remote-total c:>= 1)   ;搜索到目标
    (up-path-distance gl-point-x2 1 == 65535)   ;目标无法到达
=>
    (up-modify-goal gl-enemy-unit-detect c:= 0)   ;潜在敌人数为0
)

;// 检测可安排的兵力 //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-modify-goal gl-enemy-unit-detect c:>= 1)    ;搜索到可攻击的敌人单位数至少为1
=>
    (up-full-reset-search)       ;重置直接寻的系统的搜索索引和筛选状态、搜索状态
    (up-get-search-state gl-local-total)   ;重置搜索数量
    (up-set-target-point gl-point-x)      ;将据点座标设置为搜索圆点
    (up-filter-distance c: -1 g: gl-point-r)   ;设置搜索半径
    (up-filter-include 4 -1 -1 -1)      ;只搜寻会移动的军事单位
    (up-find-local c: -1 c: 200)      ;搜索目标附近的自军单位,上限200
    (up-remove-objects search-local object-data-target-id c:!= -1)   ;忽略正在攻击的单位
    (up-remove-objects search-local object-data-next-attack c:> 0)   ;忽略正在交战的单位
;   (up-remove-objects search-local object-data-tasks-count c:>= 1);忽略已有任务的单位
;   (up-remove-objects search-local object-data-attacker-count c:>= 1)
;   (up-remove-objects search-local object-data-group-flag c:!= -2);忽略已有组队的单位
;   (up-remove-objects search-local object-data-index c:>= 1)
)

;// 让闲置兵力向发现敌人的位置巡逻 //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
    (up-compare-goal gl-enemy-unit-detect c:>= 1)    ;搜索到可攻击的敌人单位数至少为1
=>
;   (up-send-flare gl-point-x)       ;产生自己的闪光信号
    (up-target-point gl-point-x2 action-patrol -1 stance-aggressive);用巡逻方式、攻击姿态向目标进发
    (up-chat-data-to-all "我在防御 %d 号据点" g: POINT)    ;汇报玩家防御情况
)

;// 去下一个据点指挥 //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (up-compare-goal POINT g:< POINT-max)   ;未遍历完全部据点
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (up-modify-goal POINT c:+ 1)      ;进入下一个据点
    (up-jump-rule -14)      ;跳回循环起点A,为负(12+最大据点数)
)

;// 完成所有据点后延时,避免单位抽风 //

(defrule
    (up-compare-goal POINT c:> 0)      ;据点防御模式开启
    (timer-triggered 1)      ;定时器1,每60秒检测一次
=>
    (disable-timer 1)      ;关闭定时器1
    (enable-timer 1 60)      ;重新激活定时器1,时间为60秒(可按需要缩短)
)

;// 关闭据点防御只要把PONIT设为0 //




wangzhen 发表于 2021-4-9 12:54:07

据点坐标定死了吗

春田一九零三 发表于 2021-4-12 11:11:56

wangzhen 发表于 2021-4-9 12:54
据点坐标定死了吗

根据使用情况自己改

ziranjun 发表于 2023-1-12 20:41:11

本帖最后由 ziranjun 于 2023-1-12 20:47 编辑

大佬还在吗,想了解一下这个据点防御功能的一些问题,有空解答吗
页: [1]
查看完整版本: 据点防御AI