太阳神三国杀单机版怎么添加第二个技能

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
【精品】教程贴:教你自己编写DIY武将的AI(太阳神三国杀lua)
下载积分:860
内容提示:【精品】教程贴:教你自己编写DIY武将的AI(太阳神三国杀lua)
文档格式:PDF|
浏览次数:498|
上传日期: 05:18:24|
文档星级:
全文阅读已结束,如果下载本文需要使用
 860 积分
下载此文档
该用户还上传了这些文档
【精品】教程贴:教你自己编写DIY武将的AI(太阳神三国杀
关注微信公众号后使用我的收藏没有帐号?
所属分类: &
查看: 7|回复: 0
太阳神三国杀怎么添加第二个技能
发表于 1&分钟前
太阳神三国杀怎么添加第二个技能
情与义再聚首
全平台首发福利来袭!
百万现金公会赛热血开战!后使用我的收藏没有帐号?
所属分类: &
查看: 9|回复: 0
太阳神三国杀怎么添加第二个技能
发表于 1&分钟前
太阳神三国杀怎么添加第二个技能
情与义再聚首
全平台首发福利来袭!
百万现金公会赛热血开战!新版太阳神三国杀武将技能AI设计概要_图文攻略_全通关攻略_高分攻略_百度攻略
新版太阳神三国杀武将技能AI设计概要目录第一章:AI概述精彩内容,尽在百度攻略:第二章:触发技与响应询问一、响应技能发动询问二、响应卡牌使用询问精彩内容,尽在百度攻略:三、响应卡牌打出询问四、响应选择询问五、响应角色选择询问精彩内容,尽在百度攻略:六、响应卡牌选择询问七、响应五谷丰登选牌询问八、响应卡牌展示询问精彩内容,尽在百度攻略:九、响应花色询问十、响应遗计询问十一、响应拼点询问精彩内容,尽在百度攻略:十二、响应弃牌询问第三章:视为技与技能发动一、一般视为技与卡牌使用精彩内容,尽在百度攻略:二、一般视为技与卡牌响应三、判定锁定视为技四、使用技能卡精彩内容,尽在百度攻略:第四章:AI特征信息一、使用价值与使用优先级二、相合花色与相合卡牌精彩内容,尽在百度攻略:三、武将嘲讽值四、仇恨值与角色关系第五节:常用AI函数精彩内容,尽在百度攻略: 第一章 AI概述 精彩内容,尽在百度攻略:正如《新版太阳神三国杀武将扩展学习手册》所描述的那样,太阳神三国杀的AI系统还是有一定章法可循的。武将技能AI作为AI系统的重要组成部分,自然也不例外。手册第八章里简单介绍了AI的概念和作用,给我们留下了一个初步的印象;这里将更进一步,感受一下更具体的武将技能AI设计工作。 说起来,武将技能AI还是与具体的武将技能有着密不可分的联系。技能的种类、传递数据的方式,许多因素都影响着武将技能AI的设计。触发技有触发技的AI策略,视为技也有自己的一套AI实现方法。具体到技能上,更是花样百出,各有不同。不过,掌握了武将技能AI的工作方法,再进行具体的设计,就容易很多了。一般而言,距离修改技、手牌上限技之类的技能,在游戏里以锁定技的样貌出现,不需要玩家干预。不论操作者是人类玩家还是电脑玩家,都是同样的效果,所以这些技能理论上是不需要AI支持的。对于触发技来说,电脑玩家只需要知道在需要作出选择的时候,如何找出正确的答案即可。为此,AI系统提供了一系列的决策表和决策函数。每当遇到触发技询问时,首先查阅决策表中是否有对应的决策函数。若找到这样的函数,就根据函数的结果作出选择;若没有找到,就交给AI系统统一处理,得出一个一般情形下的选择结果。精彩内容,尽在百度攻略:所以,触发技AI的设计,其实就是针对技能中出现的各个询问场景,编写对应决策函数的过程。每个询问场景都会有自己特定的决策函数格式,按照这些格式写决策函数,就会很容易设计出触发技的AI了。而对于视为技来说,情况又有所不同。视为技没有特定的触发时机,需要玩家主动选择发动。这需要考虑两个方面:什么时候发动,以及要以怎样的方式发动。在这个过程中,AI系统会依次检查玩家拥有的卡牌,判断哪些卡牌可用,并参照可用卡牌的优先级、使用价值等特征信息,选出当前最应使用的卡牌(包括技能卡和实际的卡牌),按照对应的卡牌使用方式使用它。每当使用完一张卡牌,再重复这个过程,直到不再有卡牌可用。这样,视为技的AI设计,一方面要提供判断卡牌是否可用的检测函数,一方面要提供包含了卡牌使用方式的执行函数。此外,还要提供一些相关的特征信息,以决定在所有卡牌使用过程中的出场顺序。精彩内容,尽在百度攻略:除了武将技能AI以外,AI系统还包括了身份识别等更为丰富的内容,这里就不再关注了。关于AI系统的更为详尽的介绍,可以参考太阳神三国杀extension-doc文件夹中的11-Fundamentals.lua~18-Beta.lua等文档。第二章 触发技与响应询问一、响应技能发动询问精彩内容,尽在百度攻略:技能代码中出现askForSkillInvoke()函数的地方就是询问是否发动技能的场景了。它的函数原型是:Room:askForSkillInvoke(player, skill_name, data)其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问发动技能的当前角色。skill_name:string类型,表示技能的名字。data:QVariant类型,表示传递给AI系统的参考数据。精彩内容,尽在百度攻略:另一个函数原型是:ServerPlayer:askForSkillInvoke(skill_name, data)参数skill_name和data的涵义与第一个原型中的同名参数是相同的。精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForSkillInvoke(skill_name, data)这个函数首先将通过表sgs.ai_skill_invoke查找对应的决策函数,而这个决策函数正是我们要具体设计的内容。精彩内容,尽在百度攻略: 响应技能发动询问的决策函数原型是:function(self, data)精彩内容,尽在百度攻略:其中:self:表示表SmartAI,由AI系统提供。data:表示参考数据,其实就是技能代码中传递过来的data参数了。精彩内容,尽在百度攻略:它的执行结果是bool类型的。如果为true,表示发动技能;为false的话,则不发动这个技能。 这个表self(或者说表SmartAI)提供了许多有用的信息,比如:精彩内容,尽在百度攻略:self.player就是Room:askForSkillInvoke(player, skill_name, data)中的第一个参数player,ServerPlayer类型,表示当前响应询问的角色。self.room表示当前所在的游戏房间,Room类型。self.friends表示当前角色的所有友方角色,也包括自己在内,table类型。这里的友方不一定意味着身份的相同,主公与忠臣、忠臣与内奸、主公与内奸、内奸与反贼之间在一定时段內都可能会是友方关系。精彩内容,尽在百度攻略:self.friends_noself表示当前角色的除自身以外的所有友方角色,table类型。 self.enemies表示当前角色的所有敌方角色,table类型。同self.friends的情形一样,身份的差异也不一定意味着阵营的对立。 将我们的决策函数写入表sgs.ai_skill_invoke的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_invoke[skill_name] = function(self, data)这就将技能名skill_name与特定的决策函数对应起来了。 精彩内容,尽在百度攻略:如果技能是否发动与决策无关,那么决策函数可以简化成一个对应的bool值,比如:sgs.ai_skill_invoke[skill_name] = true就表示技能skill_name始终发动。精彩内容,尽在百度攻略: 如果SmartAI:askForSkillInvoke(skill_name, data)函数没有找到所需要的决策函数,那么它将按照默认的方式处理这个场景。即,如果技能skill_name的触发频率是sgs.Skill_NotFrequent,那么产生一个false结果,不发动这个技能;如果触发频率是sgs.Skill_Frequent,那么产生一个true结果,发动技能。 精彩内容,尽在百度攻略:对于其它场景,AI系统也是大体依照这样的流程进行处理的,后文不再赘述。二、响应卡牌使用询问技能代码中出现askForUseCard()函数的地方就是询问使用卡牌的场景了。函数原型是:精彩内容,尽在百度攻略:Room:askForUseCard(player, pattern, prompt, notice_index=-1, method = sgs.Card_MethodUse )其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问使用卡牌的当前角色。pattern:string类型,表示卡牌应符合的条件。prompt:string类型,表示询问时出现的提示信息。精彩内容,尽在百度攻略:notice_index:number类型,表示提示信息的编号,默认为-1。method:sgs.Card_HandlingMethod类型,表示卡牌的处理方式,默认是sgs.Card_MethodUse。 精彩内容,尽在百度攻略:对于这个场景,AI的处理函数是:SmartAI:askForUseCard(pattern, prompt, method)三个参数pattern、prompt、method和技能代码中的同名参数是相同的。 这个函数通过表sgs.ai_skill_use来查找决策函数。精彩内容,尽在百度攻略: 响应卡牌使用询问的决策函数原型是:function(self, prompt, method)精彩内容,尽在百度攻略:它的执行结果是一个string,表示卡牌的使用方式。具体的格式是: #N:C:-&U#N[S:P]:C:-&U@N=C-&U精彩内容,尽在百度攻略:@N[S:P]=C-&U其中:N表示卡牌的对象名(objectName())。精彩内容,尽在百度攻略:S表示卡牌的花色字符串(getSuitString())。P表示卡牌的点数(getNumber())。C表示卡牌的子卡构成,是由一系列通过“+”连接的卡牌编号(getId())组成的字符串。”.”表示没有子卡。精彩内容,尽在百度攻略:U表示卡牌的使用对象构成,是由一系列通过“+”连接的角色的对象名(objectName())组成的字符串。”.”表示不指定使用对象。以“#”开始的string结果表示Lua卡牌的使用方式,而以“@”开始的string结果表示C++卡牌的使用方式。因此我们在设计武将技能AI时,写出的卡牌的使用方式,都是以“#”开始的。 精彩内容,尽在百度攻略:将决策函数写入表sgs.ai_skill_use的方法是:sgs.ai_skill_use[pattern] = function(self, prompt, method) 精彩内容,尽在百度攻略:如果SmartAI:askForUseCard(pattern, prompt, method)函数没用找到这个决策函数的话,默认产生的结果是”.”,表示不使用任何卡牌。三、响应卡牌打出询问技能代码中出现askForCard()函数的地方就是询问打出卡牌的场景了。这个函数的原型是:精彩内容,尽在百度攻略:Room:askForCard(player, pattern, prompt, data, skill_name)以及Room:askForCard(精彩内容,尽在百度攻略:player, pattern, prompt, data, method = sgs.Card_MethodDiscard,to=NULL, isRetrial = false, skill_name)精彩内容,尽在百度攻略:其中:player:ServerPlayer类型,表示被询问打出卡牌的当前角色。pattern:string类型,表示卡牌应符合的条件。精彩内容,尽在百度攻略:prompt:string类型,表示询问时出现的提示信息。data:QVariant类型,表示参考数据,还是从技能代码里传递过来的。 skill_name:string类型,表示技能的名字。method:sgs.Card_andlingMethod类型,表示对卡牌的处理方式,默认是sgs.Card_MethodDiscard。精彩内容,尽在百度攻略:to:ServerPlayer类型,默认为nil。isRetrial:bool类型,表示是否用于改判,默认为false。 精彩内容,尽在百度攻略:对于这个场景,AI的处理函数是:SmartAI:askForCard(pattern, prompt, data)这个函数通过表sgs.ai_skill_cardask来查找决策函数。精彩内容,尽在百度攻略: 响应卡牌打出询问的决策函数原型是:function(self, data, pattern, target, target2)精彩内容,尽在百度攻略:和响应卡牌使用询问的决策函数一样,它的结果也是string类型的,表示卡牌的使用方式。 将决策函数写入表sgs.ai_skill_cardask的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_cardask[prompt] = function(self, data, pattern, target, target2)如果SmartAI:askForCard(pattern, prompt, data)函数没有找到这个决策函数,AI系统会尝试着按照pattern和prompt决定打出哪些卡牌。如果仍然找不到符合条件的卡牌,那么将产生”.”的结果,表示不打出任何卡牌。四、响应选择询问精彩内容,尽在百度攻略:技能代码中出现askForChoice()函数的地方就是询问选择的场景了。这个函数的原型是:Room:askForChoice(player, skill_name, choices, data)其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问选择的当前角色。skill_name:string类型,表示技能的名字。choices:string类型,表示各个选项,是由一系列通过”+”连接的选项字符串组成的。精彩内容,尽在百度攻略:data:QVariant类型,表示要向AI传递的参考数据。 对于这个场景,AI系统的处理函数是:精彩内容,尽在百度攻略:SmartAI:askForChoice(skill_name, choices, data)这个函数通过表sgs.ai_skill_choice来查找决策函数。 精彩内容,尽在百度攻略:响应选择询问的决策函数原型是:function(self, choices, data)它将产生一个string类型的结果,表示选出的那个选项。精彩内容,尽在百度攻略: 将决策函数写入表sgs.ai_skill_choice的方法是:sgs.ai_skill_choice[skill_name] = function(self, choices, data)精彩内容,尽在百度攻略: 如果选择的结果与决策无关,那么决策函数可以直接简化成这个结果,比如: sgs.ai_skill_choice[skill_name] = “choiceA”就表示技能skill_name询问选择时,始终选择choiceA。精彩内容,尽在百度攻略: 如果SmartAI:askForChoice(skill_name, choices, data)函数仍然没有找到这个决策函数,那么AI系统首先将检查这个技能是否有默认的选择,如果有,就直接用默认的选择作为结果。否则,AI系统将从choices里随机选出一个选项,作为最终的结果。五、响应角色选择询问精彩内容,尽在百度攻略:技能代码中出现askForPlayerChosen()函数的地方就是询问选择一名角色的场景了。这个函数的原型是:Room:askForPlayerChosen(player, targets, reason)其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问选择角色的当前角色。targets:QList&serverplayer *&类型,是一个列表,表示各个备选的角色。 reason:string类型,表示询问角色选择的原因。 精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForPlayerChosen(targets, reason)这个函数通过表sgs.ai_skill_playerchosen来查找决策函数。精彩内容,尽在百度攻略: 响应角色选择询问的决策函数原型是:function(self, targets)精彩内容,尽在百度攻略:它将产生一个ServerPlayer类型的结果,表示被选出的角色。 将决策函数写入表sgs.ai_skill_playerchosen的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_playerchosen[reason] = function(self, targets) 如果SmartAI:askForPlayerChosen(targets, reason)找不到这样的决策函数,那么AI系统将从这些备选角色中随机选择一名,作为最后的结果。精彩内容,尽在百度攻略:六、响应卡牌选择询问技能代码中出现askForCardChosen()函数的地方就是询问选择一张卡牌的场景了。这个函数的原型是:Room:askForCardChosen(player, who, flags, reason)精彩内容,尽在百度攻略:其中:player:ServerPlayer类型,表示被询问选择卡牌的当前角色。who:ServerPlayer类型,表示待选卡牌所属的目标角色。精彩内容,尽在百度攻略:flags:string类型,表示待选卡牌的位置标志。由”h”(表示手牌区)、”e”(表示装备区)、”j”(表示判定区)组合而成。reason:string类型,表示询问卡牌选择的原因。 精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForCardChosen(who, flags, reason)这个函数通过表sgs.ai_skill_cardchosen来查找决策函数。精彩内容,尽在百度攻略: 响应卡牌选择询问的决策函数原型是:function(self, who, flags)精彩内容,尽在百度攻略:它将产生一个number类型的结果,表示选出的卡牌的编号。 将决策函数写入表sgs.ai_skill_cardchosen的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_cardchosen[reason] = function(self, who, flags) 如果选择的结果与决策过程无关,那么可以决策函数可以简化为具体的卡牌编号。比如:精彩内容,尽在百度攻略:sgs.ai_skill_cardchosen[reason] = 23就表示在响应原因为reason的卡牌选择询问时,始终选择编号为23的卡牌(杀[?10])。 精彩内容,尽在百度攻略:如果SmartAI:askForCardChosen(who, flags, reason)找不到这个决策函数,那么AI系统将根据who是否为友方、flags包含的区域以及具体的reason作出一般情形下的选择。这个选择的过程较为复杂,具体可参考smart-ai.lua中该函数的具体代码。七、响应五谷丰登选牌询问技能代码中出现askForAG()函数的地方就是询问从五谷丰登界面选择一张卡牌的场景了。这个函数的原型是:精彩内容,尽在百度攻略:Room:askForAG(player, card_ids, refusable, reason)其中:player:ServerPlayer类型,表示被询问五谷丰登选牌的当前角色。精彩内容,尽在百度攻略:card_ids:QList&int&类型,表示五谷丰登界面中所有备选卡牌的编号列表。 refusable:bool类型,表示是否可以拒绝响应此询问。reason:string类型,表示询问选择的原因。 精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForAG(card_ids, refusable, reason)这个函数通过表sgs.ai_skill_askforag来查找决策函数。精彩内容,尽在百度攻略: 响应五谷丰登选牌询问的决策函数原型是:function(self, card_ids)精彩内容,尽在百度攻略:它将产生一个number类型的结果,表示选出的卡牌的编号。 将决策函数写入表sgs.ai_skill_askforag的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_askforag[reason] = function(self, card_ids) 如果SmartAI:askForAG(card_ids, refusable, reason)找不到这样的决策函数,那么AI系统将根据refusable、reason以及self.player自身的技能和对卡牌的需求程度作出一般情形下的选择。这个选择的过程同样较为复杂,具体可以参考smart-ai.lua中该函数的具体代码。精彩内容,尽在百度攻略:八、响应卡牌展示询问技能代码中出现askForCardShow()函数的地方就是询问展示一张卡牌的场景了。这个函数的原型是:Room:askForCardShow(player, requestor, reason)精彩内容,尽在百度攻略:其中:player:ServerPlayer类型,表示被询问展示卡牌的当前角色。requestor:ServerPlayer类型,表示发起询问的源角色。精彩内容,尽在百度攻略:reason:string类型,表示询问卡牌展示的原因。 对于这个场景,AI系统的处理函数是:精彩内容,尽在百度攻略:SmartAI:askForCardShow(requestor, reason)这个函数通过表sgs.ai_cardshow来查找决策函数。 精彩内容,尽在百度攻略:响应卡牌展示询问的决策函数原型是:function(self, requestor)这个函数将产生一个Card类型的结果,表示将展示的卡牌。精彩内容,尽在百度攻略: 将决策函数写入表sgs.ai_cardshow的方法是:sgs.ai_cardshow[reason] = function(self, requestor)精彩内容,尽在百度攻略: 如果SmartAI:askForCardShow(requestor, reason)没用找到这样的决策函数,那么AI系统将从当前角色的手牌中随机选择一张作为结果以进行展示。九、响应花色询问精彩内容,尽在百度攻略:技能代码中出现askForSuit()函数的地方就是询问选择一种花色的场景了。这个函数的原型是:Room:askForSuit(player, reason)其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问选择花色的当前角色。reason:string类型,表示询问花色的原因。如果reason缺失的话,AI系统会将其补全为”fanjian”,并依照反间选择花色的情形处理。 精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForSuit(reason)这个函数通过表sgs.ai_skill_suit来查找决策函数。精彩内容,尽在百度攻略: 响应卡牌展示询问的决策函数原型是:function(self)精彩内容,尽在百度攻略:这个函数将产生一个number类型的结果,表示选出的花色编号。其中,0、1、2、3分别表示黑桃、红心、草花、方块花色。 将决策函数写入表sgs.ai_skill_suit的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_suit[reason] = function(self) 如果SmartAI:askForSuit(reason)没用找到这样的决策函数,那么AI系统将从0~3中随机选出一个数字作为最后选择的结果。精彩内容,尽在百度攻略:十、响应遗计询问技能代码中出现askForYiji()函数的地方就是询问遗计分牌的场景了。这个函数的原型是:Room:askForYiji(guojia, cards, is_preview=true, visible=false)精彩内容,尽在百度攻略:其中:guojia:ServerPlayer类型,表示被询问遗计分牌的当前角色。cards:QList&int&类型,表示待分配的卡牌的编号列表。精彩内容,尽在百度攻略:is_preview:bool类型,默认为true。visible:bool类型,表示卡牌在分配过程中是否对所有角色可见,默认为false。 原本这个函数只是技能“遗计”专用的,后来随着“礼让”等技能的出现,才开放出来,有了进行额外的AI设计的可能。 精彩内容,尽在百度攻略:对于这个场景,AI系统的处理函数是:SmartAI:askForYiji(card_ids, reason)这个函数是通过表sgs.ai_skill_askforyiji来查找决策函数的。精彩内容,尽在百度攻略: 响应遗计询问的决策函数原型是:function(self, card_ids)精彩内容,尽在百度攻略:这个函数将产生两个结果,依次是ServerPlayer类型(表示分牌的目标角色)和number类型(表示分给目标角色的卡牌的编号)的。 将决策函数写入表sgs.ai_skill_askforyiji的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_askforyiji[reason] = function(self, card_ids) 如果SmartAI:askForYiji(card_ids, reason)没有找到这个决策函数,那么AI系统将根据self.player自身存在的标志,采用“礼让”或“遗计”的策略产生分牌的结果。这部分内容较为复杂,具体可以参考smart-ai.lua中此函数的相关代码。 十一、响应拼点询问精彩内容,尽在百度攻略:技能代码中出现askForPindian()函数的地方就是询问打出一张卡牌拼点的场景了。这个函数的原型是:Room:askForPindian(player, from, to, reason)其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示被询问打出卡牌拼点的当前角色。from:ServerPlayer类型,表示发起拼点的角色。to:ServerPlayer类型,表示被拼点的角色。精彩内容,尽在百度攻略:reason:string类型,表示拼点的原因。 对于这个场景,AI系统的处理函数是:精彩内容,尽在百度攻略:SmartAI:askForPindian(requestor, reason)这个函数通过表sgs.ai_skill_pindian查找决策函数。 精彩内容,尽在百度攻略:响应拼点询问的决策函数原型是:function(minusecard, self, requestor, maxcard, mincard)其中:精彩内容,尽在百度攻略:minusecard:Card类型,由AI系统产生的当前角色手牌中点数最小的卡牌。 self:表示由AI系统提供的表SmartAI。requestor:ServerPlayer类型,表示发起拼点的角色。maxcard:Card类型,由AI系统产生的当前角色手牌中使用价值不高的卡牌中点数最大的卡牌;或者就是minusecard。精彩内容,尽在百度攻略:mincard:Card类型,由AI系统产生的当前角色手牌中使用价值不高的卡牌中点数最小的卡牌;或者就是minusecard。这个函数将产生一个Card类型的结果,表示将打出的用于拼点的卡牌。将决策函数写入表sgs.ai_skill_pindian的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_pindian[reason] = function(minusecard, self, requestor, maxcard, mincard) 如果SmartAI:askForPindian(requestor, reason)没有找到这样的决策函数,那么AI系统将根据requestor是否为友方角色,来决定使用mincard或maxcard作为产生的结果。精彩内容,尽在百度攻略:十二、响应弃牌询问技能代码中出现askForDiscard()的地方就是询问弃置卡牌的场景了。这个函数的原型是:Room:askForDiscard(精彩内容,尽在百度攻略:target, reason, discard_num, min_num,optional=false, include_equip=false, prompt)精彩内容,尽在百度攻略:其中:target:ServerPlayer类型,表示被询问弃牌的当前角色。reason:string类型,表示弃牌的原因。精彩内容,尽在百度攻略:discard_num:int类型,表示应当弃牌的数目。min_num:int类型,表示最少应弃牌的数目。optional:bool类型,表示是否可以选择不弃牌,默认为false。精彩内容,尽在百度攻略:include_equip:bool类型,表示弃牌范围是否包括装备区,默认为false。 prompt:string类型,表示询问时出现的提示信息。 对于这个场景,AI系统的处理函数是:精彩内容,尽在百度攻略:SmartAI:askForDiscard(reason, discard_num, min_num, optional, include_equip) 它是通过表sgs.ai_skill_discard来查找决策函数的。 响应弃牌询问的决策函数原型是:精彩内容,尽在百度攻略:function(self, discard_num, min_num, optional, include_equip)这个函数将产生一个table类型的结果,表示将弃掉的卡牌的编号名单。将决策函数写入表sgs.ai_skill_discard的方法是:精彩内容,尽在百度攻略:sgs.ai_skill_discard[reason] = function(self, discard_num, min_num, optional, include_equip) 如果AI系统的处理函数没有找到这样的决策函数,那么将按照一般情形的弃牌策略产生结果。这个决策的过程较为复杂,具体可参考smart-ai.lua中此函数的相关代码。精彩内容,尽在百度攻略: 第三章 视为技与技能发动一、一般视为技与卡牌使用精彩内容,尽在百度攻略:一般视为技,也就是将一些卡牌视为一张已存在的卡牌的技能,大多是没用特定的触发时机的。从第一章我们知道,AI系统通过不断检查卡牌是否可用来决定具体的使用方式;而在这个过程中,除了需要检查各个真实的卡牌,还需要检查那些可能通过视为技视为的虚拟卡牌。这首先要求AI系统了解当前角色拥有哪些视为技,或者说,我们需要先将我们的一般视为技信息加入AI系统。 AI系统通过表sgs.ai_skills记录已经存在的视为技,而视为技的各种信息也是通过一个表来体现的。所以最初的代码应该是:精彩内容,尽在百度攻略:local 视为技信息表对象 = {}视为技信息表对象[“name”] = “视为技名字”table.insert(sgs.ai_skills, 视为技信息表对象)精彩内容,尽在百度攻略:第一句话创建了一个视为技信息表,用于记录一个视为技AI的各类信息。 第二句话指明了这个信息表的名字,表明其对应的视为技。从此这个信息表就可以用来表示当前的这个视为技了。第三句话是将信息表插入到表sgs.ai_skills,使得AI系统可以意识到这个视为技的存在,进而也有了发动它的可能。 精彩内容,尽在百度攻略:在AI系统通过这三句话得知了视为技的存在后,接下来就是要检查包括视为的虚拟卡牌在内的各个卡牌是否可用了。对于视为技AI来说,这一步是通过getTurnUseCard函数具体实现的。这个函数的原型是:function(self, inclusive)其中:精彩内容,尽在百度攻略:self:其实就是表SmartAI自身。inclusive:bool类型,仅在当前角色没有手牌时其值为true,否则为nil。 它将产生一个Card类型的结果,表示通过这个视为技视为的虚拟卡牌。如果产生的结果为nil,那么AI系统将不会在出牌时考虑发动这个视为技。 精彩内容,尽在百度攻略:经常我们会用sgs.Card_Parse()函数产生这个虚拟卡牌,函数的原型是: Parse(str)这里,唯一的参数str表示卡牌的构成方式,string类型。对于一般视为技来说,它的具体格式是:“N:K[S:P]=C”精彩内容,尽在百度攻略:其中:N表示视为卡牌的对象名(objectName())K表示视为技的名字精彩内容,尽在百度攻略:S表示视作卡牌的花色字符串(getSuitString())P表示视作卡牌的点数字符串(getNumberString())C表示卡牌的具体构成,是由一系列通过“+”连接的所用卡牌的编号组成的字符串。精彩内容,尽在百度攻略: 因此,检查视为的卡牌是否可用,让AI系统考虑发动视为技的方法就是: 视为技信息表对象.getTurnUseCard = function(self, inclusive) 精彩内容,尽在百度攻略:由于一般视为技视作的是一种已经存在的卡牌,所以具体的使用方式,我们就不用额外给出了。二、一般视为技与卡牌响应有很多一般视为技都可以用于卡牌的响应,而不仅仅是在出牌阶段主动发动。在响应卡牌需求时,AI系统要做的事情,就是判断一下哪些卡牌可以用于发动这个视为技,并且给出视作卡牌的具体构成方式。当然,这个具体的判断过程,实际上也是一个函数,它的原型是:精彩内容,尽在百度攻略:function(card, player, card_place)其中:card:Card类型,表示当前判断的一张实际卡牌。精彩内容,尽在百度攻略:player:ServerPlayer类型,表示需要作出卡牌响应的当前角色。card_place:sgs.Player_Place类型,表示当前这张实际卡牌所在的位置。 class_name:string类型。如果处于card_place位置的卡牌card符合此视为技的要求,那么它将产生一个string类型的结果,表示所视作的卡牌的构成方式。精彩内容,尽在百度攻略: AI系统通过表sgs.ai_view_as来查找这个函数,方法是:sgs.ai_view_as[skill_name] = function(card, player, card_place, class_name) 这里,用于指明此函数的skill_name,string类型,表示这个一般视为技的名字。精彩内容,尽在百度攻略:三、判定锁定视为技锁定视为技作为视为技的一种特殊情形,在AI设计时,除了要像主动发动一般视为技那样,创建自己的信息表并记录到表sgs.ai_skills中之外,还要给出一个判定卡牌是否受到影响而改变的处理函数。每次AI系统在检查所拥有的卡牌之前,都会先通过这个处理函数,将受影响的卡牌变更为其锁定视作的卡牌,再继续后续的工作。这个处理函数的原型是:function(card, card_place, player)精彩内容,尽在百度攻略:其中:card:Card类型,表示当前判定的一张实际卡牌。card_place:sgs.Player_Place类型,表示此判定的卡牌当前所在的位置。 player:Player类型,表示拥有此锁定视为技的角色,同时也是卡牌持有者。 如果卡牌的确受到此锁定视为技的影响,那么这个函数将产生一个string类型的结果,表示具体的影响方式。和卡牌构成方式一样,格式是“N:K[S:P]=C”,只是这里的C必然只由一个卡牌编号组成而已。精彩内容,尽在百度攻略:四、使用技能卡在武将扩展行为中,比起一般视为技,在视为技中使用技能卡的情形更为普遍。不过同样地,这也需要先将相应的视为技加入AI系统,方法和一般视为技是一样的,通过sgs.ai_skills实现。 精彩内容,尽在百度攻略:接下来也是通过getTurnUseCard函数让AI系统认识到这张技能卡的可用性。而且我们通常也是用sgs.Card_Parse()函数产生一个虚拟的技能卡的。不同的是,虽然这个Parse函数的原型没变,还是Parse(str),不过参数str的格式不再是一般视为技中的“N:K[S:P]=C”了,而是在“响应卡牌使用询问”时介绍的,技能卡自己的构成方式”#N:C:-&U”(Lua技能卡)或者”@N=C-&U”(C++技能卡)。 由于getTurnUseCard函数只是用来告诉AI系统考虑使用这张技能卡的,具体的使用方式,包括具体要用什么牌、对谁使用等等,通常不需要在这里写好,所以很多时候,参数str的内容只是被刻意简单地写成了:精彩内容,尽在百度攻略:“#N:.:”(对于Lua技能卡)或者是"@N=.-&."(对于C++技能卡)精彩内容,尽在百度攻略:仅仅给出了技能卡的名字N,而子卡构成C和使用对象U都被忽略了。 在AI系统决定使用这张技能卡后,就要考虑具体的使用方法了。显然这是需要我们提供的,而AI系统则提供了一个表sgs.ai_skill_use_func来记录这些具体的使用方法。届时,AI系统通过查这个表,找到我们提供的使用方法,就可以真正发动技能使用技能卡了。精彩内容,尽在百度攻略:说到这个具体的使用方法,其实也表现为一个函数,这个函数的原型是: function(card, use, self)其中:card:Card类型,表示一张虚拟的技能卡,其实就是刚才那个getTurnUseCard函数产生的结果。比如sgs.Card_Parse(“#N:.:”),如果之前str参数被简单地写成”#N:.:”的话。精彩内容,尽在百度攻略:use:sgs.CardUseStruct类型,是一个卡牌使用结构体,表示技能卡的使用方法。我们就是通过填充这个结构体来告诉AI系统如果按照我们的意愿正确使用技能卡的。self:依然是SmartAI的代名词,不解释了。这个函数并不显式地产生任何结果,因为结果已经通过填充参数use传达出去了。比如,use.card表示要使用的技能卡,而use.to表示技能卡的使用目标。在这里,只有当use.card被填充(不为nil)时,AI系统才会去真正使用这张技能卡。精彩内容,尽在百度攻略: 将这个函数写入表sgs.ai_skill_use_func的方法是:sgs.ai_skill_use_func[name] = function(card, use, self)精彩内容,尽在百度攻略:里面的那个name表示技能卡的名字,用于在表中区分各个使用方法函数。关于这些触发技与视为技的AI设计,大体上就分为这些类型了,具体实例可参阅与本文拟配套的《新版太阳神三国杀武将技能AI实例分析》。第四章 AI特征信息精彩内容,尽在百度攻略:一、使用价值与使用优先级对于使用技能卡的视为技来说,提供具体的使用方法只能令AI系统在游戏时按要求使用技能卡,但是很多时候我们同样关心包括技能卡在内的各类卡牌的使用次序。比如,孙权先使用一张【无中生有】再发动制衡(使用制衡技能卡)可能就会比直接发动制衡(使用制衡技能卡)的效果更好。这其实就涉及了卡牌的两个设计要素:使用价值和使用优先级。 精彩内容,尽在百度攻略:卡牌是有自己的使用价值的,而AI系统通常倾向于先使用价值更高的卡牌。在上面的例子中,无中生有的使用价值是10,而制衡卡的使用价值是9,所以一般情况下电脑玩家会先使用无中生有而不是直接制衡掉它。这样一个容易想到的结果就是,如果不向AI系统给出我们的技能卡的使用价值,那么这些技能卡应该总是被最后使用的。 精彩内容,尽在百度攻略:表sgs.ai_use_value被用来记录各个卡牌的使用价值,比如我们可以用形如sgs.ai_use_value[name] = value的式子来规定名称为name的技能卡所具有的使用价值是value。精彩内容,尽在百度攻略: 另外,有些技能卡可能本身使用价值并不高,但是我们仍然希望电脑玩家优先使用它,那么可以通过设定卡牌的使用优先级来达到这个目的。 精彩内容,尽在百度攻略:表sgs.ai_use_priority用于记录各个卡牌的使用优先级,优先级数值越高的卡牌将被优先考虑使用。我们可以用形如sgs.ai_use_priority[name] = priority的式子将名称为name的技能卡的使用优先级设定为priority。精彩内容,尽在百度攻略: 二、相合花色与相合卡牌许多技能卡都是由一些实际的卡牌构成的。而很多情况下会对这些实际的卡牌有各种各样的约束,不是所有的卡牌都能被用来产生技能卡的。在这些约束中,花色限制和卡牌种类限制应该是最为常见的方式了。精彩内容,尽在百度攻略:因而对于一个武将来说,如果TA拥有这样的技能,那么TA可能会对特定的花色或种类的卡牌的需求更多一些。如果我们能将这些信息提供给AI系统,那么这名武将就会提高对特定卡牌的关注程度(比如在五谷丰登选牌时优先选择特定类型的卡牌),达到更好地发动技能的目的。 表sgs.NAME_suit_value用于记录一个名为NAME的视为技的相合花色,通常这个表中可以包括四个项目,spade、heart、club和diamond,用来表示此视为技与四种花色的相合程度。比如:精彩内容,尽在百度攻略:sgs.qixi_suit_value = {spade = 3.9,club = 3.9精彩内容,尽在百度攻略:}表示技能“奇袭”(qixi)的相合花色是黑桃(spade)和(club),分别达到了3.9的相合程度。 精彩内容,尽在百度攻略:表sgs.NAME_keep_value用于记录一个名为NAME的视为技的相合卡牌类型,表中的项目就是具体的卡牌种类了,用来表示此视为技与各类卡牌的相合程度。比如:sgs.qiangxi_keep_value = {Peach = 6,精彩内容,尽在百度攻略:Jink = 5.1,Weapon = 5}精彩内容,尽在百度攻略:表示技能“强袭”(qiangxi)的相合卡牌是桃(Peach)、闪(Jink)以及武器牌(Weapon),分别达到了6、5.1、5的相合程度。 三、武将嘲讽值精彩内容,尽在百度攻略:技能的不同带来的影响还有武将地位和作用的差异。拥有更高技能强度的武将理应遭到对立阵营的更多的攻击,这体现的就是武将嘲讽的概念。在AI系统中,武将嘲讽是通过数值来体现的,而一名武将的默认嘲讽值是0。这个数值越高,嘲讽越大,也就有更多可能遭到对立方的攻击;反之,被对立方视而不见的几率就会增强。比如,张辽的嘲讽值是4,夏侯惇的嘲讽值是-3,因此在同等条件下,张辽遭到攻击的可能性比夏侯惇要高出很多。 精彩内容,尽在百度攻略:AI系统使用表sgs.ai_chaofeng来记录武将的嘲讽值,格式是:sgs.ai_chaofeng.NAME = value其中,NAME表示武将的名字,value就是对应的嘲讽值了。精彩内容,尽在百度攻略:比如,sgs.ai_chaofeng.liubei = -2,就表示刘备(liubei)的嘲讽值是-2。有如此低的嘲讽值,也难怪很少有优先集火刘备的情形出现了。 四、仇恨值与角色关系精彩内容,尽在百度攻略:在游戏中,从一名角色的行为出发,我们很可能感觉到TA的立场,或者TA对其他角色的态度。这为我们判断角色的身份,提供了重要的依据。其中很重要的一点就是,在这些行为中包含的友好或敌视的程度。在AI系统中,通常用仇恨值的概念,来表达和体现这样的行为特征。在AI系统中,我们关注的可能包含角色关系的行为,主要有3种,包括: 使用卡牌、选择目标,以及选择卡牌。对于这些仇恨值来说,数值越大,表明源角色对目标角色的敌意越重,双方立场对立的可能性也就越大。精彩内容,尽在百度攻略: 第一,使用某些卡牌(包括技能卡)可能会表现出一定的立场倾向。比如,对一名角色使用仁德技能卡(发动仁德),通常应当被认为是一种友好行为;而使用突袭技能卡(发动突袭),更多情况下表达出的则是一种敌对的立场。 精彩内容,尽在百度攻略:AI系统使用表sgs.ai_card_intention来记录使用各种卡牌时的仇恨值。而很多时候计算仇恨值是通过一个函数完成的。这个函数的原型是:function(card, from, tos)其中:精彩内容,尽在百度攻略:card:Card类型,表示这张被使用的卡牌;from:ServerPlayer类型,表示使用这张卡牌的源角色;tos:QList&ServerPlayer*&类型,表示使用这张卡牌的目标角色列表。精彩内容,尽在百度攻略:通常这个函数并不产生显式的结果,而是在函数中引用一个叫作sgs.updateIntention的函数,通过这个函数来更新双方的仇恨关系。 sgs.updateIntention函数的原型是:精彩内容,尽在百度攻略:sgs.updateIntention(from, to, intention, card)其中:from和card与计算仇恨值的函数中的同名参数的含义是相同的,分别表示卡牌的使用者和卡牌自身;精彩内容,尽在百度攻略:to表示其中一个目标角色,ServerPlayer类型。intention表示具体要更新的仇恨值。这个函数的功能便是在使用卡牌card后,以intention为涨幅更新from对to的仇恨值了。 精彩内容,尽在百度攻略:将计算仇恨值的函数写入表sgs.ai_card_intention的方法是:sgs.ai_card_intention[name] = function(card, from, tos)在这里,name表示所使用卡牌的名称,用来区分各个具体的计算函数。 如果计算函数中,更新的仇恨值始终是固定的,那么函数可以简化为这个固定的数值。即:精彩内容,尽在百度攻略:sgs.ai_card_intention[name] = intention就表示使用一次卡牌name,仇恨值始终增加intention。 精彩内容,尽在百度攻略:第二,在响应角色选择询问等场合,目标选择的结果也会体现出角色间的关系如何。比如,驱虎拼点成功时要选择一名伤害目标,那么显然这种选择就是带有敌意的,因为我们通常不会把友方角色当成被选择的目标。 AI系统使用表sgs.ai_playerchosen_intention来记录选择目标所引起的仇恨值变更情况。当然,这种变更也是由一个函数具体完成的,它的函数原型是:精彩内容,尽在百度攻略:function(from, to)其中:from:ServerPlayer类型,表示作出选择的源角色。精彩内容,尽在百度攻略:to:ServerPlayer类型,表示被选择的目标角色。同使用卡牌时的仇恨值计算函数一样,这个函数也没有显式的结果产生,而是通过函数内部的sgs.updateIntention来更新仇恨值的。 精彩内容,尽在百度攻略:将这个变更函数写入表sgs.ai_playerchosen_intention的方法是:sgs.ai_playerchosen_intention[reason] = function(from, to)这里,reason表示选择的原因,通常就是askForChoice函数中的第二个参数skillname。精彩内容,尽在百度攻略:当仇恨值固定时,这个函数就可以简化为一个具体的数值,表示这个固定的仇恨值:sgs.ai_playerchosen_intention[reason] = intention就表示在reason询问角色选择时,对目标角色的仇恨值始终增加intention。精彩内容,尽在百度攻略:第三,在选择目标角色的卡牌时也可能传达出某种感情色彩。比如,用过河拆桥拆掉目标的装备应当被认为比拆掉目标判定区的延时性锦囊更有敌视的意味。 AI系统使用表sgs.ai_cardChosen_intention来记录选择卡牌时所引起的仇恨值变化情况。此时我们可以通过一个函数来提供这类仇恨值,它的原型是:精彩内容,尽在百度攻略:function(from, to, card_id)其中:from:ServerPlayer类型,表示作出选择的角色。精彩内容,尽在百度攻略:to:ServerPlayer类型,表示被选择卡牌的目标角色。card_id:number类型,表示被选出的卡牌的编号。同样地,这个函数依然不产生显式的结果,而是通过内部的sgs.updateIntention更新仇恨值。精彩内容,尽在百度攻略: 将这个供给函数写入表sgs._ai_cardChosen_intention的方法是:sgs.ai_cardChosen_intention[reason] = function(from, to, card_id)精彩内容,尽在百度攻略:里面的reason,表示卡牌选择的原因,被用来区分各个提供仇恨值的函数。 当然,如果这里提供的仇恨值也是固定的一个数值,那么函数将被简化为这个值,也就是:sgs.ai_cardChosen_intention[reason] = intention这说明,在reason条件下不论选择哪张卡牌,都将累积intention的仇恨值。精彩内容,尽在百度攻略:第五章 常用AI函数一、排序如果想对一系列卡牌或角色进行排序,那么可以参考AI系统提供的一些排序函数。主要有以下一些:精彩内容,尽在百度攻略: 1、function SmartAI:sort(players, key)这个函数被用来对一些角色(players)以某种标准(key)进行排序。其中: players:table类型,表示待排序的角色名单。精彩内容,尽在百度攻略:key:string类型,表示排序的标准。可以省略。通常在排序时有这样一些已经设定好的标准:“hp”,表示按体力值从小到大排序;精彩内容,尽在百度攻略:“handcard”,表示按手牌数目从少到多排序;“value”,表示按角色的质量从小到大排序;“chaofeng”,表示按角色的嘲讽值从高到低排序;精彩内容,尽在百度攻略:“defense”,表示按角色的防御杀的能力从低到高排序;“threat”,表示按角色的威胁程度从高到低排序。而默认的标准是”defense”,也就是当参数key被省略时,按照角色对杀的防御能力排序。精彩内容,尽在百度攻略:这个函数并不产生显式的结果,但是players所代表的角色名单将被实际排序。 2、function SmartAI:sortByKeepValue(cards,inverse,kept)精彩内容,尽在百度攻略:这个函数被用来将一些卡牌(cards)按照各自的卡牌保留值进行排序。其中: cards:table类型,表示待排序的卡牌名单。inverse:bool类型,表示排序的结果是否反转。可以省略。这里如果填true,那么将按照卡牌保留值从大到小排序,而填false或者省略的话,表示按照卡牌保留值从小到大的顺序排列。kept:bool类型,表示是否参考实际技能对卡牌的影响。可以省略。这个参数的存在其实是因为卡牌有两种保留值,一个是本身固有的保留值,或者说通常意义上的保留值(由表self.keepValue记录);还有一个是因为与某些武将技能相合而产生的技能保留值(由表sgs.NAME_keep_value记录)。如果填true,那么将参考技能保留值进行排序;如果填false或者省略,那么只根据卡牌自身的保精彩内容,尽在百度攻略:留值进行排序。同sort函数一样,这个函数也不产生显式的结果,只是对cards所代表的卡牌名单进行排序操作而已。 精彩内容,尽在百度攻略:3、function SmartAI:sortByUseValue(cards, inverse)这个函数可以用来按卡牌使用价值对一些卡牌(cards)进行排序。其中: cards:table类型,表示待排序的卡牌名单。inverse:bool类型,表示排序的结果是否反转。可以省略。如果填true,表示按照使用价值从小到大进行排序;填false或者省略,则会按照使用价值从大到小的顺序排序。精彩内容,尽在百度攻略:这个函数没有显式的结果,只负责对cards所代表的卡牌名单进行排序处理。二、敌友关系1、function SmartAI:isFriend(other, another)精彩内容,尽在百度攻略:这个函数被用来判断两名角色(other和another)是否属于同一阵营。其中: other:ServerPlayer类型,表示待判断的一方。another:ServerPlayer类型,表示待判断的另一方。可以省略。如果参数another被省略,那么将判断other代表的角色与自身self.player是否是属于同一阵营的。或者可以等价地认为(虽然实际上不是这样),another被自动填充为self.player。精彩内容,尽在百度攻略:这个函数的结果是bool类型的。如果结果为true,表明从another方看来,other是友方角色;如果结果为false,则认为other不属于友方(可能是中立,更可能是敌方角色)。 2、function SmartAI:isEnemy(other, another)精彩内容,尽在百度攻略:跟isFriend很相似的一个函数,用于判断两名角色(other和another)是否属于两个对立的阵营。参数的含义和isFriend中同名参数的是一样的。结果也是bool类型的。不同的是,如果结果为true,表明从another方看来,other是一个敌方角色;而结果为false时,认为other不算是敌方(可能是中立角色,更可能是友方)。 精彩内容,尽在百度攻略:三、角色状态1、function SmartAI:getOverflow(player, getMaxCards)这个函数被用来检查一名角色(player)手牌溢出的情况。其中:精彩内容,尽在百度攻略:player:ServerPlayer类型,表示待判断的目标角色。getMaxCards:bool类型,表示检查的方式。可以省略。这和最后产生的结果有关,如果填true,函数将产生弃牌阶段弃牌后将剩余的手牌数目;如果填false,产生的则是当前手牌溢出(超出手牌上限)部分的数目。这个函数的结果是number类型的,表示检查的结果。精彩内容,尽在百度攻略:这个函数在处理时,考虑了庸肆等技能的影响,在AI设计时不需要重复考虑了。 2、function SmartAI:isWeak(player)精彩内容,尽在百度攻略:这个函数经常被用来检查一名角色(player)是否处于虚弱状态。其中:player:ServerPlayer类型,表示待检查的目标角色。可以省略。如果不写的话,默认是指自身self.player。这个函数的结果是bool类型的。如果结果为true,表示此角色虚弱,而false则认为其尚有足够强的生存能力。精彩内容,尽在百度攻略:这个函数在处理时,考虑了不屈、龙魂、魂姿等技能的影响,在AI设计时是不需要重复考虑它们的。 3、function SmartAI:hasSkills(skill_names, player)精彩内容,尽在百度攻略:这个函数被用来检测一名角色(player)是否至少拥有某些技能(skill_names)中的一个。其中:skill_names:table类型或string类型,表示待检查的所有目标技能的名字名单。如果传递过来的参数是string类型的,那么各技能名字间应用符号“|”分隔,以便在函数内部将其转化成对应的table类型。player:ServerPlayer类型,表示待检查的目标角色。可以省略。在这个参数被省略时,它将被自动补全为自身self.player,表示检测自己是否拥有skill_names中包含的某个技能。精彩内容,尽在百度攻略:这个函数的结果是bool类型的。只要目标角色拥有这些技能中的任意一个,函数就会产生true的结果。而只有在目标角色不具备所有这些技能时,才会得到false的结果。 四、伤害效果精彩内容,尽在百度攻略:1、function SmartAI:damageIsEffective(to, nature, from)这个函数的作用是判断对一名角色(to)造成的伤害是否有效。其中: to:ServerPlayer类型,表示伤害的目标。可以省略。被省略时,将被自动补全为自身self.player。nature:sgs.DamageStruct_Nature类型,表示伤害的属性。可以省略。被省略时,将被自动选择为无属性伤害sgs.DamageStruct_Normal。精彩内容,尽在百度攻略:from:ServerPlayer类型,表示伤害的来源。可以省略。被省略时,将被自动填充为进行当前回合的角色(由self.room:getCurrent()确定)。这个函数的结果是bool类型的,表示from对to造成的nature属性伤害是否有效。如果结果为true,表示可以造成伤害;当结果为false时,伤害无效。在这个函数中,考虑了绝情、神君、愤勇、大雾、水泳、名士等技能的影响,设计AI时就不需要重复考虑了。精彩内容,尽在百度攻略: 2、function SmartAI:aoeIsEffective(card, to, source)和damageIsEffective类似,这个函数是用来判断多目标伤害性锦囊牌(card)能否对一名角色(to)造成伤害的。其中:精彩内容,尽在百度攻略:card:Card类型,表示可能造成伤害的多目标伤害性锦囊牌。to:ServerPlayer类型,表示待判断的目标角色。source:ServerPlayer类型,表示卡牌的使用者。可以省略。省略时,将被自动设定为当前进行回合的角色(由self.room:getCurrent()确定)。精彩内容,尽在百度攻略:这个函数的结果是bool类型的,表示角色source使用的多目标锦囊牌card能否对目标角色to造成伤害。如果结果为true,表示伤害有效;如果结果为false,说明不能造成伤害。在这个函数中,考虑了藤甲、各类禁止技、无言、绝情、祸首、巨象、智迟、啖酪、皇恩等因素的影响,同时结合了damageIsEffective的结果,因而在设计AI时,可以就不考虑上述因素了。 精彩内容,尽在百度攻略:3、function SmartAI:getJiemingChaofeng(player)这是一个针对技能“节命”设计的评估函数,主要用来评价一名拥有节命技能的角色在受到伤害时可能得到的收益。其中,参数player为ServerPlayer类型,表示被评价的目标角色。在这个函数中,将对目标角色player的所有友方角色进行统计,查看他们当前手牌数与其体力上限(超出5时取5体力上限)的差距,得出节命时可能摸牌的数目,并根据这个数目评出相应的得分。精彩内容,尽在百度攻略:函数的结果是一个number类型的数值,表示最终的评分。如果得分为正数,表明目标角色的友方角色都有很多的手牌,节命空间较小;得分越多,嘲讽越高。如果得分为负数,表明有些友方角色手牌较少,节命空间较大;得分越少,嘲讽越低。
相关攻略推荐}

我要回帖

更多关于 太阳神三国杀技能代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信