1、AI系统设计分析,前 太阳神三国杀AI项目组成员 独孤安河2016年6月5日,版本信息,神杀版本:太阳神三国杀 V2 终结版(版本号:20150926)神杀AI 版本:QSanguosha AI 20141006 (V1.32 Alpha)Lua 版本:Lua 5.2,什么是AI?,人工智能(Artificial Intelligence),简称AI。它是计算机科学的一个分支学科。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。就其本质而言,它是对人的意识、思维的信息过程的
2、模拟。,那么,什么又是太阳神三国杀的AI?,游戏中出现的“电脑玩家”?No!它是帮助玩家(含“电脑玩家”)进行游戏的后台逻辑。主要包括“选将AI”、“托管AI”和“高级AI”三类。有了它,“电脑玩家”才能够表现得像个人类核心任务:模拟人类玩家的思维过程,并最终做出决策!,目录,选将AI情况1:KOF模式选将情况2:3v3对战模式选将情况3:身份局选将情况4:双将模式选择副将托管AI高级AI场景1:出牌阶段主动使用牌场景2:响应请求场景3:弃牌阶段弃牌场景4:身份判断场景5:分析局势场景6:聊天及其它,选将AI,哪里有需要,AI就到哪里去!于是游戏的第一个问题出现了选择武将。面对若干备选武将,要
3、选择使用哪位武将参与游戏呢?思路:给武将评分,谁分高谁上!,情况1:KOF模式(02_1v1)选将,加载武将1v1评分表(游戏目录/etc/1v1-priority.txt)读取各备选武将的评分,并排序选取评分最高的武将,选将举例,选将框中有下列武将:新标准版黄月英新标准版周瑜新标准版司马懿新标准版马超新标准版大乔标准版甄姬以及四个暗将AI会选择哪个武将呢?,选将举例(解),查表可知新标准版黄月英:65分新标准版周瑜:82分新标准版司马懿:69分新标准版马超:70分新标准版大乔:14分标准版甄姬:93分而暗将的评分被固定为50分所以AI向电脑玩家推荐的选将是甄姬,其次周瑜。,情况2:3v3对战
4、模式(06_3v3)选将,加载武将3v3评分表(游戏目录/etc/3v3-priority.txt)读取各备选武将的评分,并排序选取评分最高的武将其实和KOF模式的思路是相似的,情况3:身份局选将,根据角色身份采用不同的策略进行选将。主公随机选将。忠臣、内奸、反贼依然是先分别评分,然后最高分入选。与前两种情况不同的是,身份局选将需要考虑主公因素。所以评分包括两个部分:基础分,匹配分。评分公式:最终评分基础分匹配分,基础分,初始值:5分。忠臣:势力为“神”,或者与主公势力相同,基础分1.04反贼:势力为“群”,且主公有技能“血裔”(火袁绍),基础分0.8势力为“吴”,且主公有技能“归命”(SP孙
5、皓),基础分0.5内奸或反贼:势力为“蜀”,且主公有技能“誓仇”(SP刘备),基础分0.1所以经常见到主公选曹操时,全场一片魏蓝色;而选刘备时,一堆蜀将。,匹配分,加载忠臣评分表(游戏目录/etc/loyalist.txt)、 反贼评分表(游戏目录/etc/rebel.txt ) 和内奸评分表(游戏目录/etc/renegade.txt)根据角色身份,从对应的评分表中读取备选武将的: 通用适应度(不关心主公是谁时的适应度,默认为0) 主公适应度(在特定武将做主公时的适应度,默认为0)于是,匹配分1.1通用适应度1.1主公适应度评分公式:最终评分基础分1.1通用适应度1.1主公适应度,选将举例,
6、火典韦风夏侯渊标准版孙权风张角神赵云,主公:林董卓角色身份:忠臣备选武将:如图所示,忠臣评分表(节选),通用适应度SP曹昂:0.3SP袁术:0.3新标准版郭嘉:0.2标准版郭嘉:0.2SP华雄:-1,林董卓 主公适应度神吕布:1.1火袁绍:1新风张角:1风张角:1新标准版吕布:1标准版吕布:1风小乔:0.8火颜良文丑:0.7新风周泰:-2风周泰:-3,选将举例(火典韦),基础分:5分查表知,典韦没有忠臣身份的通用适用度和董卓主公时的适应度所以典韦的评分为:51.101.105分,选将举例(风夏侯渊),基础分:5分查表知,夏侯渊没有忠臣身份的通用适用度和董卓主公时的适应度所以夏侯渊的评分为:51
7、.101.105分,选将举例(标准版孙权),基础分:5分查表知,孙权没有忠臣身份的通用适用度和董卓主公时的适应度所以孙权的评分为:51.101.105分,选将举例(风张角),基础分:51.045.2分查表知,张角没有忠臣身份的通用适用度,但董卓主公时的适应度为1所以张角的评分为:5.21.101.115.72分,选将举例(神赵云),基础分:51.045.2分查表知,赵云没有忠臣身份的通用适用度和董卓主公时的适应度所以赵云的评分为:5.21.101.105.2分,选将举例(解),火典韦:5分风夏侯渊:5分标准版孙权:5分风张角:5.72分神赵云:5.2分,经过计算,各武将的评分为:所以AI最终会
8、选择张角做董卓的忠臣。,情况4:双将模式选择副将,加载双将评分表(游戏目录/etc/double-generals.txt)对于每个备选武将,读取已选主将与其进行配对时的评分(默认为0分)若没有评分,再读取其与已选主将进行配对时的评分(默认为50分)将所有备选武将的最终评分进行排序选择评分最高的备选武将做为副将,选将举例,主将:林鲁肃备选副将:标准版张辽标准版甘宁标准版孙尚香新标准版华佗标准版刘备应该选谁作为鲁肃的副将呢?,双将评分表(节选),新标准版刘备林鲁肃:75分标准版孙尚香林鲁肃:54分林鲁肃新一将成名凌统:52分林鲁肃SP袁术:54分林鲁肃标准版张辽:20分林鲁肃标准版刘备:75分林
9、鲁肃一将成名凌统:53分,选将举例(标准版张辽),查表可知:林鲁肃标准版张辽:评分为20分。这个20分就是张辽的最终评分了。,选将举例(标准版甘宁),查表可知:林鲁肃标准版甘宁:没有评分(取默认值0分)再查:标准版甘宁林鲁肃:还是没有评分(取默认值50分)所以甘宁的最终评分是50分。,选将举例(标准版孙尚香),查表可知:林鲁肃标准版孙尚香:没有评分(取默认值0分)。再查:标准版孙尚香林鲁肃:评分为54分。于是孙尚香的最终评分被修改为54分。,选将举例(新标准版华佗),查表可知:林鲁肃新标准版华佗:没有评分(取默认值0分)。再查:新标准版华佗林鲁肃:还是没有评分(取默认值50分)。于是华佗的最终
10、评分为50分。,选将举例(标准版刘备),查表可知:林鲁肃标准版刘备:评分为75分。这样刘备的最终评分即为75分。,选将举例(解),所有备选武将的评分为:标准版张辽:20分标准版甘宁:50分标准版孙尚香:54分新标准版华佗:50分标准版刘备:75分获得最高分的是刘备,评分为75分所以AI最后将选择 标准版刘备 作为林鲁肃的副将,托管AI,如果你点击了“托管”,那么接下来帮你游戏的,就是托管AI托管AI为游戏中那些需要作决定的场合制定了最简单的策略以使游戏能够继续正常进行比如开五谷丰登时让玩家从中随机选牌等然而这并不是重点讲托管AI主要是为了引出后文的高级AI没错,托管AI其实只是一个代码中的概念
11、其工作现在已经完全被高级AI替代在实现上,高级AI继承自托管AI,是托管AI的子类,高级AI,于是重点来了对于电脑玩家,要想跟上人的节奏,它们就必须依靠高级AI。怎样出牌?怎样响应?怎样留牌?怎样判断其他角色身份?怎样分析局势?怎样卖萌,场景1:出牌阶段主动使用牌,确定所有可能将使用的卡牌(包括:真卡牌、视为卡牌)尝试使用卡牌,以此选出所有可以使用的卡牌分别计算各选出卡牌的使用优先级排序,确定优先级最高的卡牌,此即将要使用的卡牌确定卡牌使用方式(包括:用哪些牌?对谁使用?)其实和人类玩家思考的过程是类似的下面给出一个例子具体解释一下。,出牌举例,庞统忠臣,第一轮出牌阶段准备出牌,目前场上局势如
12、下:1号位:火袁绍(主公,2体力0牌)2号位:林董卓(6体力4牌)3号位:林祝融(反贼,2体力1牌,八卦阵,大宛)4号位:风夏侯渊(反贼,2体力1牌,贯石斧)5号位:火庞统(1体力5牌,未涅槃)【主视角角色,忠臣】6号位:风黄忠(3体力2牌)7号位:新标准版郭嘉(1体力9牌)8号位:标准版曹操(3体力4牌)手牌为:【绝影】(5)、【朱雀羽扇】(A)、【雷杀】(8)、【决斗】(A)、【闪】(Q)现在庞统该如何出牌呢?,出牌举例,局势如图,现在庞统该如何行动?,确定所有可能将使用的卡牌,【绝影】(5)【朱雀羽扇】(A)【雷杀】(8)【决斗】(A)【闪】(3)铁索连环(A) 来自技能“连环”,由构成
13、,在AI看来庞统共有6张卡牌!,尝试使用,选出所有可用卡牌,【绝影】(5)【朱雀羽扇】(A)【雷杀】(8)【决斗】(A)铁索连环(A) 来自技能“连环”,不能主动使用闪!所以现在庞统共有5张卡牌可用!,计算卡牌的使用优先级,卡牌的使用优先级包括:预设的“使用优先级”,以及游戏中实时确定的“动态使用优先级”两类。“使用优先级”只与卡牌种类有关(记录在sgs.ai_use_priority表中)。“动态使用优先级”与花色、点数、角色技能等信息有关。一般来说,“使用优先级”是基准,“动态使用优先级”根据实际情况,在其基础上上下浮动。最终优先级以“动态使用优先级”为准。,获取预设的“使用优先级”,绝影
14、(防御马):2.75朱雀羽扇(武器):2.655雷杀:2.5决斗:2.9铁索连环:9.1(数据来自:游戏目录/lua/ai/standard_cards-ai.lua 和游戏目录/lua/ai/maneuvering-ai.lua),计算“动态使用优先级”,【绝影】(5):2.750.00322.7468【朱雀羽扇】(A):2.6550.79923.4542【雷杀】(8):2.50.49952.9995【决斗】(A):2.90.00022.9002铁索连环(A):9.10.00029.1002(参考:游戏目录/lua/ai/smart-ai.lua中的SmartAI:getDynamicUse
15、Priority 函数),按优先级排序,铁索连环(A):9.1002【朱雀羽扇】(A):3.4542【雷杀】(8):2.9995【决斗】(A):2.9002【绝影】(5):2.7468最终选择使用铁索连环(A),确定使用方式,首先排除“无言”、“忍戒”、“敌人数过少”、“无谋”等特殊情形然后排除“啖酪”(SP杨修)或“皇恩”(贴纸刘协)的干扰接着对所有角色进行分组:组F1:被横置的、可生效的、害怕受伤的、带闪电的友方角色(空)组F2:被横置的、可生效的、害怕受伤的、不带闪电的友方角色(空)组OF:不属于F1和F2的其他友方角色(袁绍、庞统)组E:未被横置的、可生效的、不希望扣减体力的、明确的敌
16、方角色(夏侯渊、祝融)并判断是否需要连环自己(不需要),确定使用方式(续),分组后,优先考虑为组F1中的友方角色解锁(不需要)然后考虑组E中的敌方角色,发现其数目不少于2个因此依次将前2个敌方角色添加为使用目标即决定使用目标为:夏侯渊、祝融最终结果:庞统发动了技能“连环”将【决斗】(A)当作一张铁索连环(A)对夏侯渊和祝融使用。,神杀技能分类,触发技:在特定时机发动的技能。描述通常会具有类似“XX时机,你可以做XX”的结构。视为技:将一些牌视为另一些牌的技能。描述通常会具有类似“你可以将XX牌当做XX牌使用”的结构。特殊技包括:禁止技、距离修正技、手牌上限技、目标增强技、攻击范围技、技能失效技
17、等。,游戏规则本质上也属于触发技哦!,关键概念:技能卡,为了便于AI思考,引入“技能卡”的概念。“技能卡”是一种虚构的卡牌,用来表现特定技能的效果。制衡:阶段技,你可以弃置至少一张牌。若如此做,你摸等量的牌。制衡:(同义描述)阶段技,你可以将X张牌当做“制衡技能卡”使用(X至少为1)。制衡技能卡:你摸X张牌。,关键概念:技能卡,意义:出牌阶段的“主动发动技能”和“使用卡牌”自此在形式上得到了统一,简化了AI的思考过程。在出牌阶段空闲时间点主动发动的技能都是视为技!只不过有些是视为了卡牌,有些是视为了技能卡而已。“视为技技能卡”是实现许多技能效果的经典搭配。衍生概念:子卡构成技能卡的那些真正的卡
18、牌,称作该技能卡的子卡。,出牌举例(二),残局阶段,目前场上形势如下:主公:标准版曹操(3体力3牌,1号位)忠臣:标准版貂蝉(1体力4牌,古锭刀、骅骝,2号位)【当前回合角色】新标准版郭嘉(1体力2牌,3号位)新标准版夏侯惇(1体力0牌,5号位)反贼:新标准版刘备(1体力1牌,横置,4号位)标准版司马懿(1体力2牌,青釭剑,横置,6号位)标准版华佗(1体力0牌,白银狮子,横置,7号位)内奸不明已知貂蝉的手牌为:【闪】(4)、【顺手牵羊】(4)、【顺手牵羊】(3)、【兵粮寸断】(10)现在是貂蝉的出牌阶段,貂蝉应当怎样出牌呢?,出牌举例,现在貂蝉该如何行动?,思路是一样的,仍然要先确定有哪些可使
19、用的卡牌然后对其按使用优先级进行排序最后选出最高优先级的卡牌,确定其具体的使用方式只是在确定可使用卡牌的时候这次还要把技能卡考虑进去:貂蝉拥有技能“离间”也就意味着还有一张卡牌“离间技能卡”,确定所有将可能使用的卡牌,【闪】(4)【顺手牵羊】(4)【顺手牵羊】(3)【兵粮寸断】(10)“离间技能卡”(无花色,点数为0)来自技能“离间”,尝试使用,确定所有可用卡牌,“离间技能卡”(无花色,点数0),例行公事,获取预设的使用优先级“离间技能卡”:4计算“动态使用优先级”“离间技能卡”(无花色,点数0):4(不变)按优先级进行排序排序结果:“离间技能卡”(无花色,点数0)最后决定使用的卡牌就是:“离
20、间技能卡”(无花色,点数0),确定技能卡构成,采用手牌数大于体力时的策略首先将所有手牌按卡牌的保留价值从小到大进行排序然后找出第一个不为【桃】的:基本牌或装备牌或【五谷丰登】结果为:【闪】(4)此即为“离间技能卡”的子卡所以貂蝉将用这张【闪】发动技能“离间”具体过程可参考:游戏目录/lua/ai/nostalgia-ai.lua中的noslijian_skill.getTurnUseCard函数该函数最终调用了:游戏目录/lua/ai/standard-ai.lua中的SmartAI:getLijianCard函数,确定技能卡的使用目标,首先排除特殊情况,如:离间主公杀忠臣、收友方反贼、帮孙策
21、主公觉醒、利用神关羽等然后将所有敌方男性角色按防御力从小到大排序排序结果:华佗、刘备、司马懿发现第一目标华佗的体力为1并且没有【杀】考虑离间主公收反贼华佗检查主公可以使用【决斗】并且【决斗】对华佗有效因此决定使用目标为:华佗、曹操具体过程可参考: nostalgia-ai.lua中的sgs.ai_skill_use_func.NosLijianCard函数该函数最终调用了: standard-ai.lua中的SmartAI:findLijianTarget函数,最终结果,因此,貂蝉会将【闪】(4)当做“离间技能卡”使用,目标是华佗和曹操表现在游戏界面上,就是貂蝉弃置了【闪】(4),对华佗和曹操
22、发动了技能“离间”,场景2:响应请求,根据请求类型找到对应的处理方案登记表根据请求原因在登记表中找到处理该请求的处理方案采用该方案处理请求,得出处理结果并进行响应,请求类型及相应的处理方案登记表,询问技能发动:sgs.ai_skill_invoke表询问卡牌使用:sgs.ai_skill_use表询问卡牌响应:sgs.ai_skill_cardask表询问卡牌分配:sgs.ai_skill_askforyiji表询问弃牌或卡牌交换:sgs.ai_skill_discard表询问卡牌展示:sgs.ai_cardshow表询问拼点:sgs.ai_skill_pindian表,请求类型及相应的处理方
23、案登记表(续),询问选择:sgs.ai_skill_choice表询问花色选择:sgs.ai_skill_suit表询问角色选择:sgs.ai_skill_playerchosen表询问卡牌选择:sgs.ai_skill_cardchosen表询问五谷丰登选牌:sgs.ai_skill_askforag表询问观星(集中处理,无对应登记表)询问无懈可击(集中处理,无对应登记表)询问濒死求桃(集中处理,无对应登记表),响应举例,已知目前正在进行【万箭齐发】的结算,当前场上形势如下:主公:标准版孙权(5体力1手牌,1号位)忠臣:标准版孙尚香(1体力0手牌,青釭剑,2号位)火庞统(1体力2手牌,未涅槃
24、,4号位)新标准版华佗(3体力3手牌,爪黄飞电,8号位)【当前回合角色】反贼:标准版马超(2体力3手牌,方天画戟,3号位)标准版张辽(4体力2手牌,八卦阵,5号位)林曹丕(2体力3手牌,6号位)【当前决策角色】新风周泰(4体力3手牌,未不屈,7号位)内奸不明此时曹丕因受到1点伤害正在被询问选择“放逐”的目标,应如何进行响应?,响应举例,现在曹丕该如何作出响应?,响应处理过程,这是一个“询问角色选择”类型的请求对应的处理方案登记表为sgs.ai_skill_playerchosen表请求的原因是“放逐”(代码中表示为“fangzhu”)确定处理方案为sgs.ai_skill_playerchos
25、en.fangzhu(是一个回调函数)请求的信息为:(1)当前决策角色:曹丕(2)可选目标角色:孙权、孙尚香、马超、庞统、张辽、周泰、华佗采用该处理方案处理请求,得出处理结果,处理方案的具体决策过程,更新角色身份和局势信息,得知此时的队友:马超、张辽、周泰敌人:孙权、孙尚香、庞统、华佗局势:反贼优势(局势评分: -13.100241 )对所有队友按手牌数从少到多进行排序排序结果:张辽(2)、马超(3)、周泰(3)依次分析每名队友,看是否有需要翻面的队友(结果:没有)根据摸牌数是否不少于3张采取不同的策略此时摸牌数为1,所以将采取少于3张时的策略,处理方案的具体决策过程(续),采用摸牌数少于3张
26、时的策略:对所有敌人按防御力从小到大进行排序排序结果:孙尚香、庞统、华佗、孙权依次分析每个敌人,看是否有不希望被翻面且拥有技能“漫卷”的敌人结果:没有依次分析每个敌人,看是否有不希望被翻面且拥有首要技能的敌人结果:孙尚香(拥有技能“结姻”)于是产生处理结果:选择孙尚香,并以此作出响应,首要技能(sgs.priority_skill)名单,缔盟好施青囊集智固政奇袭结姻国色断粮举荐反间离间漫卷突袭巧变庸肆制衡洛神仁德明策完杀同心极略安恤奇策银铃倾城后援昭心双刃诈降陷嗣峻刑笔伐燕语甚贤天陨,技能按效果分类,需要失去装备的技能(sgs.lose_equip_skill):枭姬、旋风等需要空城的技能(s
27、gs.need_kongcheng):连营、空城等需要受伤的技能(sgs.masochism_skill):归心、遗计等可以从判定中受益的技能(sgs.wizard_skill):鬼才、天妒等可以改判的技能(sgs.wizard_harm_skill):鬼才、鬼道等首要技能(sgs.priority_skill):缔盟、青囊等可以救人的技能(sgs.save_skill):急救、补益等需要回避的技能(sgs.exclusive_skill):挥泪、断肠等,技能按效果分类(续),需要卡牌的主动技能(sgs.Active_cardneed_skill):咆哮、天义等需要卡牌的被动技能(sgs.no
28、tActive_cardneed_skill):看破、鬼才等能从他人处获得桃的技能(sgs.drawpeach_skill):突袭、巧变回复技能(sgs.recover_skill):仁德、狂骨等可以使用白银狮子的技能(sgs.use_lion_skill):断粮、奇袭等需要装备牌的技能(sgs.need_equip_skill):神速、明策等直接造成伤害的技能(sgs.straight_damage_skill):强袭、旋风等可以多次使用杀的技能(sgs.double_slash_skill):咆哮、父魂等依靠体力上限的技能(sgs.need_maxhp_skill):再起、英魂等负面技能(
29、sgs.bad_skills):崩坏、无谋等,场景3:弃牌阶段弃牌,其实只是场景2“响应请求”在特定场合下的具体应用而已对应的处理方案为sgs.ai_skill_discard.gamerule函数首先对所有手牌按卡牌的保留价值由小到大进行排序然后依次分析每张手牌,判断其是否可以弃置选取前N张可以被弃置的手牌进行弃置这里N为需要弃置牌的数目如果当前角色有技能“琴音”,则N为本次至少应弃置牌的数目,卡牌的保留价值,卡牌的保留价值包括预设的“卡牌保留值”、“技能保留值”、“花色保留值”、“点数保留值”和游戏中实时确定的“动态保留值”五类“卡牌保留值”只与卡牌类型有关(记录在sgs.ai_keep_
30、value表中)“技能保留值”与当前角色技能和卡牌类型有关(记录在sgs.技能名_keep_value表中)“花色保留值”与当前角色技能和卡牌花色有关(记录在sgs.技能名_suit_value表中)“点数保留值”与当前角色技能和卡牌点数有关(记录在sgs.技能名_number_value表中)“动态保留值”是综合了上述因素并结合角色自身情况得出的卡牌保留价值,弃牌举例,已知场上局势如下(未提到的角色均已阵亡):主公:新标准版曹操(2体力2牌,古锭刀、仁王盾、紫骍,1号位)忠臣:标准版甄姬(2体力4牌,诸葛连弩、八卦阵、的卢,5号位)内奸:火太史慈(1体力0牌,4号位)反贼:标准版马超(2体力
31、1牌,青龙偃月刀、白银狮子,7号位)标准版大乔(1体力0牌,8号位)当前为甄姬的弃牌阶段,四张手牌为:【桃】(2)、【酒】(3)、【酒】(9)、【酒】(9)甄姬应选择哪两张牌进行弃牌?,弃牌举例,现在甄姬应如何弃牌?,获取预设的“卡牌保留值”,桃:7(数据来自:游戏目录/lua/ai/standard_cards-ai.lua)酒:4.1(数据来自:游戏目录/lua/ai/maneuvering-ai.lua)闪:5.2(数据来自:游戏目录/lua/ai/standard_cards-ai.lua),获取预设的其它保留值,甄姬拥有技能“洛神”(代码“luoshen”)和“倾国”(代码“qing
32、guo”)从表sgs.qingguo_suit_value中可以得到与“倾国”相关的花色保留值:黑桃:4.1草花:4.2(数据来自:游戏目录/lua/ai/standard-ai.lua)没有与这些技能有关的“技能保留值”或“点数保留值”,计算“动态保留值”,首先初步计算出每张卡牌的动态保留值:【桃】(2):7【酒】(3):max(4.1, 5.2)4.19.3【酒】(9):max(4.1, 5.2)4.29.4【酒】(9):4.1然后根据卡牌花色、同类卡牌数目等信息进行调整,计算“动态保留值”(续),然后根据卡牌花色、点数、同类卡牌数目等信息进行调整:【桃】(2):70.0010.0027.
33、003【酒】(3):9.30.0040.0039.307【酒】(9):9.40.0030.0091.28.212【酒】(9):4.10.0010.0091.21.32.910最终AI将建议玩家弃掉两张红色牌,留下两张黑色的【酒】。,场景4:身份判断,根据角色行为推断其对其他角色的敌意程度由此判断其当前行为跳何种身份统计其跳各种身份的次数根据统计结果及各身份剩余人数等信息推测其真实身份注意:所有AI共享使用同一套身份判断有关的数据唯一执行身份判断的AI称为“记录者”(sgs.recorder),身份的种类,游戏中的身份:主公(lord)忠臣(loyalist)内奸(renegade)反贼(reb
34、el),AI视角的身份:主忠(loyalist)内奸(renegade)反贼(rebel)待定(neutral),仇恨值(intention),用于表示一名角色对另一名角色敌意程度的量值为正数表示敌视(攻击行为),为负数表示友好(示好行为)每当一名角色做出一次决策而导致游戏中的某个事件发生AI会记录此事件的相关信息并分析该角色在此事件中表现出来的对相关角色的动机倾向然后以此更新该角色对相关目标角色的仇恨值此功能由SmartAI:filterEvent函数组织完成(游戏目录/lua/ai/smart-ai.lua),filterEvent函数,功能:用于记录和分析当前发生的事件的相关信息参数:事
35、件名(event)、当前视角角色(player)、信息数据(data)这里我们重点关注两个事件:做出决定(sgs.ChoiceMade)卡牌确认目标后(sgs.TargetConfirmed),做出决定(sgs.ChoiceMade),是一个具有超前性的时机AI根据决定的具体类型调用对应的分析函数进行分析所有分析函数事先被写进sgs.ai_choicemade_filter表中其中“决定的具体类型”包括:,使用卡牌(cardUsed)卡牌响应(cardResponded)发动技能(skillInvoke)做出选择(skillChoice)使用无懈可击(Nullification)选择角色(pl
36、ayerChosen)选择卡牌(cardChosen)分配卡牌(Yiji)观看卡牌(viewCards)拼点(pindian),仇恨值在“做出决定”中的体现,在smart-ai.lua中集中处理的、与仇恨值密切相关的决定类型有选择角色(playerChosen)使用无懈可击(Nullification)分配卡牌(Yiji)其余类型与上述三种类型的处理方式类似分布在各个扩展包的AI文件中,与“做出决定”有关的两类仇恨值,角色选择仇恨值:表示一名角色进行角色选择时对目标角色的敌意程度记录在sgs.ai_playerchosen_intention表中卡牌分配仇恨值:表示一名角色进行卡牌分配时对目标
37、角色的敌意程度记录在sgs.ai_Yiji_intention表中仇恨值还有一类卡牌使用仇恨值,后面再谈,决定使用无懈可击的仇恨值,与被无懈可击的锦囊牌所具有的仇恨值有关无懈可击层级:当前场上已经连续使用无懈可击的次数如果被无懈可击的锦囊牌不为【无懈可击】:层级:重置为1仇恨值:该锦囊牌的卡牌使用仇恨值的相反数如果被无懈可击的锦囊牌为【无懈可击】:层级:增加1仇恨值:变为前一仇恨值的相反数,卡牌确认目标后(sgs.TargetConfirmed),在卡牌即将生效之前,指定完目标之后的一个时机对应“卡牌使用仇恨值”分别更新卡牌使用者对每一个目标角色的敌意程度,卡牌使用仇恨值,表示一名角色对目标角
38、色使用某类卡牌时体现出的敌意程度记录在sgs.ai_card_intention表中角色选择仇恨值、卡牌分配仇恨值和卡牌使用仇恨值虽然名为“值”但是都可以写成函数形式,从而分情况表现不同的敌意程度,敌意程度与跳身份之间的关系,每名角色都有“偏忠”、“偏反”和“偏内”三个计量对主忠角色表示敌意(仇恨值为正),“偏忠”计量下降对主忠角色表示友好(仇恨值为负),“偏忠”计量上升对反贼角色表示敌意(仇恨值为正),“偏反”计量下降对反贼角色表示友好(仇恨值为负),“偏反”计量上升如果场上存在内奸,根据实际情况更新“偏内”计量根据三个计量的值确定角色所跳的身份,更新“偏内”计量、判定内奸的原则,主忠内局面
39、,没人跳过内奸,忠臣之间相互攻击:不更新原跳忠臣或内奸,攻击主忠:“偏内”计量上升原跳反贼,示好主忠:“偏内”计量上升原跳忠臣或内奸,示好反贼:“偏内”计量上升原跳反贼,攻击反贼:“偏内”计量上升,特殊的跳身份行为,游戏第一轮,若所有角色未跳过身份,对其他非主公角色使用火攻、杀、决斗或发动技能“银铃”,且不会对目标角色造成收益的,视为对主公表示友好,“偏忠”计量上升游戏前三轮,若未跳过身份,在弃牌阶段弃牌时,被发现弃杀,而本可以杀主公:“偏忠”计量上升或者本可以杀其他已跳身份的角色:更新仇恨,进而影响计量被发现弃乐不思蜀、兵粮寸断思路类似,身份判断举例,当前局势如下:主公:风张角(4体力4牌,
40、白银狮子,1号位)【主视角角色】忠臣:神赵云(2体力3牌,紫骍,2号位)【当前回合角色】标准版孙权(4体力3牌,方天画戟、仁王盾,5号位)新标准版吕蒙(4体力2牌,朱雀羽扇、赤兔,8号位)反贼:风夏侯渊(3体力2牌,3号位)新风于吉(1体力0牌,4号位)新标准版郭嘉(3体力2牌,6号位)标准版甄姬(3体力3牌,7号位)内奸不明此时赵云用紫骍发动“龙魂”对张角使用了【杀】,这说明什么?,身份判断举例,原跳忠臣的赵云忽然开始杀主公?他是在跳内奸么?,分析过程,首先排除流离、借刀杀人等特殊情况然后,由于杀的目标角色(张角)有技能“雷击”并且从使用者(赵云)的角度,张角手牌中有【闪】同时此【杀】不能造
41、成2点以上的大伤害以及场上存在明确的反贼角色(夏侯渊等)而且赵云没有技能“烈弓”,而张角需要发动技能“雷击”所以认为这是在与张角做配合,是对主公张角示好的行为结果:赵云的“偏忠”计量上升,在当前局面下不会被认为是内奸,事后验证,赵云的身份是忠臣,判断正确其他角色的身份如下:3号位:风夏侯渊反贼4号位:新风于吉反贼5号位:标准版孙权内奸6号位:新标准版郭嘉反贼7号位:标准版甄姬反贼8号位:新标准版吕蒙忠臣,身份判断举例(二),游戏第一轮,还没有角色跳过身份,目前场上形势如下:1号位:标准版刘备(主公,5体力5牌)2号位:火诸葛亮(3体力3牌,爪黄飞电,赤兔)3号位:标准版孙权(4体力6牌,朱雀羽
42、扇)【当前回合角色】4号位:标准版甘宁(4体力4牌)5号位:新标准版司马懿(3体力4牌)6号位:风周泰(4体力4牌)7号位:标准版貂蝉(3体力4牌)【主视角角色,反贼】8号位:神司马懿(4体力4牌)此时孙权在其弃牌阶段弃牌时弃置了两张【杀】,这意味着什么?,身份判断举例,如何评价孙权的这一行为?,分析过程,孙权弃置了【杀】而孙权装备有【朱雀羽扇】是可以杀到刘备主公的而且刘备也没有影响其他角色使用【杀】的技能但孙权还是把【杀】弃掉了所以认为这是对刘备主公表示友好的行为结果:孙权的“偏忠”计量上升,在当前局面下被视为忠臣,事后验证,孙权的身份是内奸,在第一轮可以认为偏忠,判断正确其他角色身份为:2
43、号位:火诸葛亮忠臣4号位:标准版甘宁反贼5号位:新标准版司马懿反贼6号位:风周泰反贼8号位:神司马懿忠臣,场景5:分析局势,首先统计场上忠臣和反贼的人数如果没有反贼、有忠臣存活:主忠优势(评分:99分)如果没有忠臣、有反贼存活:反贼优势(评分:99分)然后根据所有存活角色的体力、防御力,以及主公状态等情况为局势进行评分最后根据评分得出当前局势评分越高,局势越倾向于主忠方;越低,越倾向于反贼方,两个评分公式,局势评分公式:局势评分主忠评分和反贼评分和(主忠人数反贼人数)3角色评分公式:角色评分体力max(防御力体力2,0)0.5,局势分类,主忠优势(loyalist)主忠稍优(loyalish)
44、反贼优势(rebel)反贼稍优(rebelish)局势平衡(neutral)局势纠结(dilemma),局势评分与局势分类的关系,角色防御力,与角色的体力、手牌数、技能、装备、座次等信息有关用于评估一名角色的生存能力主要指对【杀】的防御能力首先计算基本防御力,其值为:体力2手牌数然后根据角色的装备情况和拥有的技能等信息在基本防御力的基础上进行适当的调整得出最终的角色防御力(参考:游戏目录/lua/ai/smart-ai.lua中的sgs.getDefense函数),局势分析举例,现在是标准版甄姬的出牌阶段,目前场上形势如下:主公:标准版孙权(5体力0牌,方天画戟、八卦阵、的卢,1号位)忠臣:标
45、准版孙尚香(1体力1牌,2号位)新标准版马超(2体力2牌,大宛,3号位)反贼:新标准版貂蝉(2体力3牌,古锭刀、紫骍,乐不思蜀,6号位)风夏侯渊(1体力0牌,7号位)风周泰(4体力4牌,8号位)内奸:标准版甄姬(3体力3牌,雌雄双股剑,5号位)【主视角角色】另有反贼:标准版周瑜(4号位)已阵亡那么作为内奸,甄姬应该如何评价场上局势?,局势分析举例,现在局势如何?,初步判断,目前忠臣有孙尚香、马超,共2名角色反贼有貂蝉、夏侯渊、周泰,共3名角色主公孙权非常健康,没有危险当前角色甄姬的是5号位,但因4号位周瑜已阵亡,故座次为4同理,之后的貂蝉、夏侯渊、周泰的座次依次为5、6、7,计算各角色防御力(
46、孙权),基本防御力:5(体力)20(手牌数)10装备了防具【八卦阵】:防御力212装备了防御马【的卢】:防御力113身份是主公:防御力0.412.6座次加成:防御力7(人数)1(座次)4(当前座次)%7(人数)/413.35技能加成:防御力2(技能数)/413.85因此,孙权的防御力是13.85。,计算各角色防御力(孙尚香),基本防御力:1(体力)21(手牌数)3拥有技能“结姻”:防御力2.35.3体力不足2:防御力0.44.9座次加成:防御力7(人数)2(座次)4(当前座次)%7(人数)/45.4技能加成:防御力2(技能数)/45.9因此,孙尚香的防御力是5.9。,计算各角色防御力(马超),基本防御力:2(体力)22(手牌数)6体力不足2:防御力0.45.6座次加成:防御力7(人数)3(座次)4(当前座次)%7(人数)/45.85技能加成:防御力2(技能数)/46.35因此,马超的防御力是6.35。,