SLG手游卡牌类游戏机器人逻辑算法

        初入游戏服务端开发行业,分享一下自己在做机器人功能时候的一些心得,欢迎各路大神指教。

        根据策划的需求,策划希望生成的机器人非常逼真,不仅拥有类人的战斗逻辑思维,而且要求机器人的各项可展示信息也要极尽所能匹配正常玩家,也就是说,不能让玩家感觉他打的是机器人。所以在做逻辑之前,我在配表的时候也花了很多心思。

        直接上表图。

        

        这是其中的阵容表,因为培养线比较多,所以就不一一列举了。

        简单描述一下各个字段的含义,第一个规则id字段是生成索引用的。因为最后的排列组合出现了200多万种可能,不采用索引方式,而直接添加所有数据进入内存,会导致宕机或者溢出。

        二三字段中的等级上下限是用来规范机器人的等级,只有等级在这个范围以内的机器人才能拥有这种阵容。

        余下的字段分为武将id和小伙伴id(玩过养成的朋友都知道,有的游戏的机缘或者缘分系统是由上阵武将和小伙伴提供的)。

        其余表不做太多解释。直接进入生成索引的环节。

        下面是我的索引源码,话说写这个源码的时候被公司的反编译大哥一顿嘲笑。但是没办法啊= =。我的递归写的太烂了。想递归的时间这个10多层的for循环我早就写完了。反正这个算法只是为了生成索引表,就用一次,所以就很粗暴的这样写了。

        

        每次看到这串代码的时候,我都只想说一句话,我就是我,看到自己都上火。哭

        这段是模拟91-120级的机器人可能会遇到所有培养情况。

        因为我比较菜,从java直接生成的xlsx表,生成之后打不开,所以就采取了先生成txt,再从txt转换为xlsx。

        在这里要说一句题外话,xlsx单个sheet表的行数的上限大概是在一百零几万,超过这个行数会无法保存,所以我在生成txt的时候也是做了计数统计,尽量保证每一次生成的txt不超过这个上限,所以就分成了三个区间段进行生成。

        不过这仅仅是索引表的第一步。因为这个按策划需求来讲是要求对玩家的战斗力进行匹配,所以最后服务端加载的索引表形式应该是战斗力+索引的两字段xlsx表。

        所以在第一步的索引表里我详细的加载了所有可能性的详细数据,这也导致踩了不少大坑,第一次加载这个200多mb的大表时候进行战斗力生成演算的时候,我的服务器直接宕机= =。

        解释一下为什么会宕机,因为我索引表的生成逻辑和生成机器人的逻辑是一样的。都是要先生成机器人,然后根据该机器人各项属性值进行战斗力生成,所以我在生成200多万个索引的时候,实际要先生成200多万个机器人,而且是和玩家数据相差无几的机器人,各位大神可以想象一下,服务器瞬间进入200多万玩家的感觉= =。而且我这个开发服务器只有8g内存,所以当场就挂掉了。后来还是采取老办法,进行区间生成,最后好歹把这个表弄出来了。

        上图看成果。


        这是1万多战斗力和60多万战斗力的索引数值。因为我们这套架构到我手上的时候已经十几手了,有些培养线没有很方便的逻辑可以直接进行调用生成,而任务急迫,所以有些玩家看不见的展示信息并且还没有调用逻辑的,我选择了暂时性忽略,准备在接下来的热更中慢慢完善。但这也导致了。有几百万战斗力的土豪玩家在进行对战匹配的时候,没有合适的机器人给他打。但是接下来我做了一套战力补偿机制进行修正,也是解决了这个问题,这个机制会在接下来进行描述。

        先上生成逻辑。

        浮动比例,根据策划的需求进行设置的,本来想写在表里的。一时间懒癌犯了,就写在程序里了。

        这个功能目前是在活动中根据玩家战斗力生成24个机器人队伍。前12个机器人分别从玩家战斗力的0.3到1进行递增操作。后12个机器人分别从玩家战斗里的1到1.2进行递增,但是写到后面我发现这两个参数我没用,直接写在生成逻辑里了。哈哈。

     

       当玩家进入活动时候,会通过pb中code信息进入该逻辑。

       先判断玩家等级是否达到55,如果达不到,回传错误提示给客户端。

       再对玩家战力进行判断,达不到也默认无法进入。

       通过以上判断之后,才能进入同步回调。

        

        进入回调后,首先会对已经在数据库加载好的json信息进行比对,判断这个老哥json中敌军字段是否为空,如果为空,则判断为第一次进入,并计入getIdList1(Player player)这个方法进行生成操作,这个方法下面会贴源码。并对生成后的机器人list集合每个元素进行赋值操作,当前赋值的有关卡id,战力,角色头像,名称等。并统一打包进pb回复的repeated修饰的类进行客户端回复。

     

        如果不是第一次进入的话,则直接加载之前的敌军字段信息,并安装0.3到1的递增区间生成这12种战斗力情况,和1到1.2的12种战斗力情况,调用机器人生成函数robotGenerate()进行生成,并在这个方法中考虑玩家战斗力大于索引表战斗力的情况,进行战力补偿机制。


        这段不做详细描述,和上述的添加玩家可见信息方式一致。


        对客户端进行回复操作。包括奖励预览。不同vip重置次数和可连斩关卡。


        生成第一次进入活动的玩家的对手列表算法,突然发现之前的代码有一部分写冗余,有一段其实是可以复用这个方法的。

这个方法也是先比对玩家战斗力,先获取玩家在本次活动中出现过的最高战斗力,如果为默认值0,则认为第一次进入并加载当前战斗力。再判断当前战斗力是否大于之前存在过的最高战斗力,如果是,则认为当前战斗力为最高战斗力,并在后面进行数据库存储,做这个机制的原因,主要是防止以低战力阵容进入活动,中断换上强力阵容,导致游戏公平性失衡,所以按照玩家在活动中出现过的最高战斗力进行匹配。

        对机器人索引表中战斗力的匹配采取了万年不变的二分查找,简单粗暴,指数下降。

        但目前面临的一个隐患是,由于索引表中的战力字段并不连续,有一定几率会出现当前匹配精度匹配不到的情况,结果会取到两边的情况,而且这一块由于缺乏有效的统计手段,我暂时没有办法得出合适的精度进行匹配操作,暂时采取了0.999到1.0001的匹配操作,好在战斗力我判断的基本都是20000以上的操作,战力的上下波动暂时能控制在200左右的范围,但在低战力(20000-100000)的情况下可能会出现连续匹配两个形同机器人的情狂,所以后来我干脆写了一个接口,在最后的生成阶段会强行改变这个机器人的名字和战力,不过好在都是1000以内的战力误差,在对打过程中影响并不明显,当然如果是数据狂或者大哥那我暂时没有太好的办法 = =。所以这一块也请各位大神多多指教小弟。


        在生成机器人玩家的方法中,由于我没有求出适应各个sheet表的读取规律,所以采取了比较蠢得一个sheet一个读取脚本的方式进行读取,搞出了好多写死的数据,估计后面接手这个大坑的大哥要遭殃了。哈哈。这两页主要是一些读表操作。



        ok,读完这几张表并赋值结束,开始进入最后的生成环节。其实总体来讲,生成的整体逻辑并不复杂,主要就是调用其他各个功能板块的外接接口,但写这些外接接口的时候真的是痛苦的一笔= =。

        一步步阐述,这一段主要是玩家天命和官职,但是估计各位大哥看注释也能看懂,就不做多赘述了= =。

        由于我们游戏在技能设置这块是主角拥有4个技能,和其他的一个武将一个技能不一样,所以主角技能走的是单独的逻辑,所以在设置机器人玩家主角技能的时候因为之前忘了考虑这条培养线,就很粗暴的写死了 = =。

        

        我一直觉得我的这个随机名字生成和之前的索引表第一步生成都是一个大大的败笔= = 但没办法,谁叫小弟我菜呢。

        本来想复用游戏开始的随机名字算法的,但是发现mysql中的json字段我死活没存进去中文。就很难受。所以最后就采取了一个折中的方式,自己写了一个随机,然后根据索引中的数字部分进行抽取操作,这样既不会重复又解决了姓名存储的问题。


        这一段是战力补偿机制的初始化,我根据玩家战力获取到的24种战力情况,我都会一一与我的索引表中的最高战力进行减法操作,如果结果为负数,说明战力还在可以控制的范围,就不进行战力补偿操作,如果结果为正,则进行战力补偿机制。下面这段对属性的赋值主要是根据我们游戏中各项属性对战力加成的情况进行比对。最后得出以目前的战力差,我该对这些属性进行什么样的操作。


        这一段没什么好讲的,不同游戏不同开发者的装备宝物系统逻辑都差不多。只是在优化效率安全性上有所差异。


        这一段根据宝物机缘的配置可以简单说一下,因为很多养成类的游戏是附带机缘系统的,就是说你不同的武将阵容和宝物阵容会触发队伍中的不同机缘,而机缘往往是按照百分比进行加成,所以加成的战力非常之高,而很多玩家,也会在机缘系统上认真的进行调配。而这个需求设计的初衷就是为了更加类人。但是机缘这个东西我如果全写在表里,要写好久。所以就又加了这套机缘匹配方法。在这个逻辑下。我会先从上阵的武将中获取这个武将的所有机缘信息,并根据机缘信息中所需要的物品信息,获取物品id并生成该物品,赋给该武将,这样每个武将都会穿戴与自己有机缘的宝物装备等等,使更加类人。但是在数值方法我还是比较蠢得写死了。后期会慢慢优化。


        最后我采取了一个非常流氓的操作,来填补我之前做二分查找中的大坑。就是强行设置机器人的战斗力和名字,以达到连续递增还不一样的效果= =。不过这个问题我目前已经想到了解决办法。会在后面的更新中解决。


        最后一段算是一个彩蛋吧。加上了一个匹配真人玩家数据的方法。这个方法是在根据24种战力情况进行匹配的时候,会在在线玩家或者数据库玩家中的数据再进行一轮比对,如果真人玩家的比对通过,则会强行覆盖这个位置的机器人玩家。以达到99.9%逼真的效果。但是后来在测试的过程中发现游戏中存在坏档玩家数据。一旦匹配到会把正常玩家的数据卡死,甚至丢档。所以就先没上。

        后来发现用try catch可以先非常流氓的不管这个问题,使程序接着跑下去。但是治标不治本。还是得找到问题所在才行啊。


            初次发帖,请各位大哥多多指教。

                                                                                                                                        作者:董泽民

                                                                                                                                        2018.3.12

                                                                                                                                        转载的大哥帮忙注明一下出处


  • 2
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

weixin_41827232

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值