铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 2174|回复: 7

[通用] 我也谈谈AI算法的设计(上)

[复制链接]
发表于 2009-7-14 08:09 | 显示全部楼层 |阅读模式

马上注册,结交更多侠友!

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
首先,我要声明一下,虽然代码还没有写,不过我绝不是纸上谈兵的,以下算法都是可实现的,代码有空再完成呵呵~

以下算法包括了吃药,武功选择,走位以及最新的特殊状态和特殊武功等等的处理,只有文字,不知道各位代码狂人能否融入代码中,呵呵~

首先说说整个算法的基本价值判定,也就是AutoBattle中各种判断的基本流程
在我的代码中,AI的价值观为:
自保>杀人>加持>伤人>休息

自保,顾名思义就是保持自己不死,吃药,医疗,或者使用特殊武学治疗等都算,这是放在所有事情的第一位,相信这是没有什么悬念的,对了,还有逃跑,因为休息可以恢复一部分生命内力等,所以逃跑也算是自保,有一些特殊状况,后面再说
如果吃药医疗等判断为false,那么AI将会判断是否存在可以杀掉的敌人,然后杀之,解决敌人(我方?)的有生力量是自保之后的第二件事情,而战斗判断复杂,同样后面再说
加持,也就是对友军施加正面状态,相信这是一个让AI设计者头痛的东西,往往不知道放在哪里好,对吧?在判断不能减少敌人数量之后,加强自我属性状态往往是一个比纯粹伤害敌军更佳的选择
伤人,就是使用武功,可能你会发现,伤人跟杀人同样使用武功,那是否意味着要重复进行武功判断呢?看下面就知道
休息就不说了,直白点说,什么都做不成就会休息


有了这么一个大的方向,剩下的就是把判断不断地细分的一个过程了~AI说起来神秘,其实也就是处理一堆变量的假设和循环罢了

然后,如何才能做出一个比较聪明的AI呢?如果只是跟以前的一样,那这AI就没有必要写了

我的变革有如下几点:
1,使用药品对象从自我变为友军
这个在代码中是很好实现的,我刚接触复刻源码时就做出来了这么个系统,只是加几行代码罢了。就是改了一下case mode后面的~
procedure BattleMenuItem(bnum: integer);
var
  i, rnum, inum, mode, step: integer;
  str: widestring;
begin
  if MenuItem then
  begin
    inum := CurItem;
    rnum := brole[bnum].rnum;
    mode := Ritem[inum].ItemType;
    case mode of
      3:              //战场吃药系统强化,突破只给自己吃药的限制,药物可以作用于队友
        begin
          CalCanSelect(bnum,1);
          step:=2;
          if ( SelectAim(bnum, step) ) then                  //选定某个坐标的角色
          begin
            for i:=0 to (BRoleAmount-1) do                 //在战场上搜索所有人物对照
            begin
            if (BRole[i].X = Ax ) and (BRole[i].Y =Ay) and (BRole[i].Team=0) then        //坐标上人物非空,为队友
              begin
                EatOneItem(BRole[i].rnum, inum);
                instruct_32(inum, -1);
                Brole[bnum].Acted := 1;
                waitanykey;
              end;
            end;
          end;
        end;
      4:
        begin
          UseHiddenWeapen(bnum, inum);
        end;
    end;
  end;

end;

然后在AI中,我的建议是用等级判断,每个角色行动前,先判断可使用药品范围内(如果药品范围是离自身两格内,那就是移动格数+2),是否存在需要使用药品的角色,如果存在,并且角色等级比自身要高,则优先给等级高的角色使用药品

例如,一个小兵跟欧阳锋同时被打成红血,然后小兵会给欧阳锋用药,欧阳锋攻击,这改革意义就大了,小兵的存在也只不是充当经验值了

2,记录最高伤害数值和角色
在源码中,单场战斗的数据是不被记录在什么R,D,S之类的文件中的,也就是战斗数据不会影响文件结构,所以为战斗人物加几个变量是很简单的事情

有见及此,我提议为角色加入最高受伤和带来该伤害的攻击者记录,提升AI的智能
不明白怎么回事?
我也举个例子:
例如郭靖一个降龙打欧阳锋(又是他)500,那在欧阳锋的最高受伤纪录就会变成500,攻击者为郭靖的人物编号
如果欧阳锋的生命值少于500的双倍1000,他就会采取吃药等自保行动,而郭靖也成了他攻击的第一顺位目标,这样就不会再被“快马”拉着跑了吧?

同样地,如果他的最高受伤纪录才50,那有1000血的他就没必要神经兮兮地吃药了。
这设计的价值在于更符合效益的吃药和攻击等行为判断,是否好用还是要经过调试,不太好说。

3,对逃跑坐标的记录
所谓的逃跑坐标,就是当角色放弃攻击而选择逃跑(如吃药,休息等)时,的移动坐标
我的设计中,把这坐标放到了所有判断的最前面!
而不同于一般的设计中,当角色逃跑时,才来计算
为什么要如此设计呢?
因为逃跑坐标被应用到了更广的方面来,更聪明的AI走位的实现其实不难

首先说说逃跑坐标是如何决定的吧

对每一个可以移动的格子,判断该格坐标与所有非我方角色的坐标差值的和,最大的那一格的坐标就是逃跑坐标了
如,敌人A的坐标为(1,1),敌人B为(2,3),如果可选择的行动坐标分别为C(1,4)和D(2,5)
那么可得,C与A,B的总距离为0+3+1+1=5,D与A,B总距离为1+4+0+2=7
得到D为逃跑坐标

当然,实际中不可能只有两格可走,不过从这个例子我们可以看出,逃跑坐标简而言之就是离所有敌人相对最远的一格了

记录这一格的好处是很大的,除了吃药跑路等,应用是多方面的,也是例子说明吧~
例子1,假设欧阳锋(呃)的蛤蟆功范围为线5,移动为7,跟敌人的距离为3格,
那欧阳锋坐标为(10,10)的话,敌人坐标为(10,13)
因此,我们可以得到逃跑坐标应该为离敌人最近的一格(10,3),
利用了逃跑坐标后,在攻击时,欧阳锋的AI就不再是一味地接近敌人然后攻击了,他完全可以后退两步,找到一个离逃跑坐标最近,而又让武功触及到敌人的移动坐标(10,8)才进行攻击
也就是说,我们的AI懂得后退攻击了!怎样,比想象中的要简单对吧?


或许有人说,不记录逃跑坐标,临时计算也可以实现啊,这没错,
但是!
如果有10个武功判断呢?这临时计算就要走10次,先把坐标记录了,计算时可以直接代入轻松地找到最佳的走位点,那在效率方面就高了

当然,也有可能是接下来的流程中都没有用到这个坐标,白算了 = =!,不过这样的可能性较小

4,正面状态的判断
正如我上面说的,这玩意往往不知道怎么让AI处理好,因为特殊武功的判断复杂,总不可能一个个去判断吧?难道必须让敌人舍弃特殊武功吗?
这明显是不妥的,因为AI不止用在敌人身上,也要用于我方!
谁也不想见到一按“自动”,AI就瘫痪了不是?

其实说出来一文不值,就是增加武功类型数量,也就是,武功不在局限于拳剑刀特,看到这里,或许有人要喝乌鸦的倒彩了,先别急,看下去先~
我说增加武功类型,不是说要在拳剑刀特后面再加一个什么辅助武功类型,不是!所有武功归类在四基之中在很多mod之中都是必要的,创造一个辅助类那不是变相的束缚吗?

我的建议是,增加不如细化,把四基根据目标分化为对敌武功和对我武功变成8基,甚至再加上全体武功,变成12基

——拳敌,拳我,拳全,剑敌,剑我……

说出来工作量似乎很大,不过就是复制一下代码,然后改一下switch case函数,阵型变量改一下罢了~~我是这么认为的

对于辅助状态的存在,这样的改动是必要的,武功使用时,判断一下人物是否有对我方的武功(总不会有武功杀友军吧?),如果存在,而且我方附近存在不含某某状态的友军,则使用该武功,为友军加持正面状态。
这样很方便是吧?至少比输入特殊武功的编号,然后一个一个的判断来得简单

5,负面状态的选择
两个字,加权~
相比起正面状态,带负面状态的武功判定相对是比较简单的,因为这种武功完全可以看做是普通的伤害性武功,而负面状态则可看作是一个附加的伤害,多调试几次,设置好就结了
如武功A的威力是1000,无效果,武功B是800,但带麻痹,假设设定麻痹的价值等同300伤害
那攻击某敌人时,AI自然会选择武功B,如果敌人已经带有麻痹,则武功A更佳,这没有什么意见吧?
哦,对了,对复数敌人也是一样的,如存在3个敌人,都是正常状态,而且武功一次性可以含盖3个敌人
第一轮攻击,武功A的价值为1000*3=3000,武功B的价值为800*3+300*3=3300,选武功B攻击,两人麻痹
第二轮,武功A价值依然为3000,武功B为800*3+300=2700,则选武功A


这是AI的设计(上)的全部内容,下篇将呈现整个流程(或者我会直接写成代码?)

欢迎各位研究讨论,谢谢

[[i] 本帖最后由 winson7891 于 2009-7-14 08:23 编辑 [/i]]
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2009-7-14 09:01 | 显示全部楼层
玉來了,hoho,今天開始培訓了,估計很難看見你的下了。
幾個小建議哈
一個是我覺得所有的判定的出口最好是一個。
什么意思呢?就是如果你就1點血,對方也就一點血,你應該殺了他還是自保,當然這個問題是南宮老師給我提的。。。
先思后動,但是這個思的時間會不會有點長?我的遍歷我已經覺得不能加東西了。是不是用加動畫或者其他的什么處理,我的處理方式是再次化簡算法,加入時間軸,讓slg變成aslg,這樣運算就有時間了,但是也不好。所以我有很多加權沒有放出來。
上面我想說的就是,流程上的內容是不是只有一個出口,內容會不會算法太多導致卡,還有一個問題,別人電腦厲害過了人,留個漏洞,不然大家都開自動也沒什么意思。
然后就是一些我做ai的心得。
傷害判定方面,先選武功-》攻擊模式-》只需要選擇方向或者點下去就能攻擊的,例如十字和線攻,我的思路是-》移動范圍-》每個可以攻擊的位置,計算傷害,記錄移動點和方向。。一點都不卡
-》面點攻-》移動范圍+攻擊范圍-》每個可以攻擊的位置,計算傷害,記錄移動點,攻擊點。。也不太卡,但是沒實現,沒找到原因,后來趕工就忘掉了,現在也來不及看了
現在的點面攻-》移動范圍-》攻擊范圍-》每個可以攻擊的位置,計算傷害,記錄移動點,攻擊點
有些許卡。原因很好找,兩個大遍歷,如果是移動范圍15,攻擊范圍15就是 15×15×15×15,當然我用一定的算法,讓后面的15化簡的一定的工作量,前面的15也化簡了,但是光空跑15×15×15×15,在比較夸張的mod一定有問題。
如果能把后面的范圍化簡,譬如我上次提的算法能實現的話,沒去嘗試。。。
然后是逃跑,我最近都在研究路徑,A*+Dijkstra的算法,把離敵人的距離都標記好,做一個疊加算法,直接就好移動了,或許會比較簡單,而這個標記或者可以放在對方移動后,這樣就不用放在ai里,應該可以簡單一點。
同時逃跑算法還帶有一個問題,傷害如果受距離加成,何時應該逃跑打(或者可以放風箏),何時應該全力輸出(反正逃不掉,傷害最大化直接比攻防),這個問題當然不考慮清楚能形成漏洞,ai一定要留漏洞!!!

[发帖际遇]: waxyzwa暑假期间在洛阳绿竹巷参加《任盈盈琴箫兴趣班》,学习初级课程,报名费银两12。
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2009-7-14 09:11 | 显示全部楼层
Dijkstra是低效率的,我没有用这种算法,直接代入各敌人坐标计算就好了

如果要得出最佳的目标坐标,用Dijkstra就意味着要进行复数次的Dijkstra运算吧~效率极低~

你是不是用了这个,所以卡?

另外,你觉得我这样的AI就没有漏洞吗?又不是人类永远无法战胜的黑白棋AI~AI中没有直接读取敌方数据进行精密计算~漏洞大着呢~要战胜当然没问题~

[发帖际遇]: winson7891被发现和仪琳一起偷西瓜,赔了银两15.
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2009-7-14 09:15 | 显示全部楼层
沒,本來也想加逃跑部分的,沒有想到很好的算法,再加上群攻有點卡,就放棄了
我以為你的加權時會參照人物數據加權呢,哈哈

[发帖际遇]: 胡斐要去和程灵素约会,出门前waxyzwa帮他打整了一下络腮胡,得到打赏银两8.
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2009-7-14 09:18 | 显示全部楼层
参照人物数据就等于是变相作弊了~

就好像玩大老二,电脑知道你的底牌,或者你知道电脑的底牌,那就没有意思了~

[发帖际遇]: winson7891帮张无忌翻译小昭写的情书,得到辛苦费银两10.
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2009-7-14 09:24 | 显示全部楼层
哈哈,反正玉是引出來了,我得走了,不走趕不上車了,對了
  TBattleRole = record
    case TCallType of
      Element:
      (rnum, Team, Y, X, Face, Dead, Step, Acted: Smallint;
        Pic, ShowNumber, ExpGot, SkillPoint, Auto: Smallint;
        BattleTime : integer;
        Threat: array[0..29] of Smallint);
      Address:
      (Data: array[0..43] of Smallint);
  end;

加傷害就加在這里,傷害計算的時候算一下,留下最高的就好了。。。好運哈
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2009-7-14 16:37 | 显示全部楼层
老兄,你只是引出另一块石头罢了~

玉啊玉,你快出来啊~~
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2009-7-14 20:05 | 显示全部楼层
我不懂什么delphi...绝对的拿来主义者。。。
LS过于谦虚。。。

[发帖际遇]: 黄顺坤去长白山捉火蟾,送给韦一笑,得感谢费银两20.
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-11-16 05:50

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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