三国志9吧 关注:110,640贴子:5,298,312
  • 21回复贴,共1

【转载】兵法发动的三篇经典文章(转自三国志9电子书)

只看楼主收藏回复

1L喂度娘。


IP属地:北京1楼2014-11-19 17:59回复
    额,


    2楼2014-11-19 18:01
    回复
      三国志九兵法发动机理揭密
      作者:rangzh
      三国志九(以下简记s9)中的兵法,相信是大家讨论得最多的话题之一。设想如果游戏取消了兵法的设计,那么趣味性一定会减少许多。然而s9中的兵法发动,却是比较随机的事情,很难准确地预测部队中的武将会在哪一日发动兵法;或者换句话说,某个武将在某一日会不会发动兵法很难说。不过,根据玩游戏的经验,我们可以知道一些大概的情况,比如按照平均值来计算的话,一个武将差不多一旬会发动一次兵法;受到激励后武将可能会立刻发动兵法。但是这些都只是定性的表面现象。在基于SoftICE一类的动态破解跟踪工具对s9游戏程序汇编代码进行定位、跟踪、揣测之后,终于探索出了s9中关于兵法的一些奥秘——包括兵法发动的最小间隔、兵法的抵挡、兵法攻击时的动画效果、兵法的联动、发动兵法后武将能力值的增加等。除此之外,还跟踪了伪报、扰乱、单挑等处理代码,基本理出了其计算流程。
      一、兵法发动机理框架
      首先有必要介绍一下s9中武将的内存数据。可以猜测s9中850个武将的数据是以全局数组(若不知何为全局数组,请参看C语言)的形式实现的,因此当游戏程序运行后,程序模块基地址一旦确定,武将数据在内存中的地址也就固定了。由于在破解过程中,始终采用的是第一个新武将来做实验,因此这里的叙述也以第一个新武将为例。对于PK1.01,第一个新武将的数据在内存中的起始地址是0x128B840(C语言中的十六进制表示,后面也采用这种形式),而每个武将数据块的大小是0x128字节。因此,可以很容易地算出第二个新武将的内存数据起始地址是0x128B968,余类推。武将内存数据中包括武将姓名、能力、所在部队等等一系列的信息,但是我们所关心的并非这些,而是一个用于记录武将兵法发动时间间隔的数据,这个数据存放在偏移起始地址0x98字节处。对于第一个新武将而言,这个间隔就存放在0x128B8D8处。这个间隔值的含义是:武将发动一次兵法后到下一次再发动时所需要的最小天数。换言之,如果这个间隔值不为0,那么该武将是绝对不可能发动兵法的;只有当这个间隔值变为0时,该武将才有可能发动兵法(注意:是有可能,而不是一定,为什么?——且看后文分解)。知道这个间隔值的存在及其含义是非常重要的。可以做一个很简单的试验来体验这个间隔值对兵法发动的影响:用FPE 2001将0x128B8D8锁定为0,那么你会发现第一个新武将兵法发动次数明显提升,一旬内可以超过2次。通常,在没有受到激励的情况下,一个武将一旬内发动兵法的次数是不能够超过2次的,而且发动2次兵法的情况只有可能是:第一日与最后一日发动。顺便提一下,如果用fpe将这个间隔值锁定为非零值,那么理论上该武将将永远也不会发动兵法,为什么?前面已经说过,只有在该间隔值为0的情况下才会发动嘛。更严格地讲,只有该间隔值为0的武将才有可能发生以下行为:
      1). 发动兵法;
      2). 引发单挑;
      3). 呼应兵法(就是别人发动他呼应,也就是所谓的联动了)
      反过来说,该间隔值不为0的武将将绝对不会发生以上行为。下文中,我们将以上情况都称为“发动兵法”,即广义化。
      明白了有这个间隔值后,让我们来看看s9程序代码中兵法发动机理的框架。对整个框架可以做如下描述:程序计算代码是按天进行计算的,即一天一天地进行,每一天中的计算又是按武将逐个进行计算的,这些计算包括武将是否发动兵法、是否烧抢成功等等等等,一共要计算850个武将。当计算到武将是否发动兵法时,首先要检查该武将的间隔值是否非零,对于间隔值非零的武将,直接跳过兵法的计算,根本不给这些武将发动兵法的机会;而对于那些间隔值为0而且在作战的武将,程序代码将给这些武将发动兵法的机会。接下来,对于拥有兵法发动机会的武将,程序代码将调用SanCalc.dll中的一个伪随机数生成函数来的到一个随机结果,根据这个结果决定武将是否把握住了兵法发动机会(在此之前,还要根据健康状况淘汰一批人)。如果武将把握住了机会,那么该武将将在这一日发动兵法,而且程序代码将立即修改该武将的那个间隔值,至于改成多少,要根据该武将发动的兵法种类类决定:在设施内发动是3;在野战部队内发动一般兵法是9;发动单挑是5(胜利);发动妖、幻是15;呼应兵法也是3;其他情况尚待进一步的代码跟踪查明。结合前面介绍的原理稍加推理一下就可以知道:这些报握住机会发动了兵法的武将在后面一天将不会获得兵法发动的机会(进一步,机会都没有了,兵法自然更不会发动了)。而对于那些没有把握住机会的武将,该间隔值保持为0,这意味着:这些没有把握住机会的武将在后面一天将继续获得兵法发动机会,至于届时能不能把握仍然是个随机问题。在这一天的计算结束的时候,程序代码将所有非零的间隔值统统减1,之后,下一天的计算开始。顺便说一下,激励的作用起始就是直接将被激励部队的武将的间隔值直接设定为0,这一点猜也能猜得到。看到这里,不知道大家看明白没有。如果没明白,没办法,我的表达能力只有如此水平了;如果明白了,恭喜你,继续往下看吧。
      在介绍兵法的其他方面之前,再总结一下兵法发动的框架吧:
      1). 每个武将发动一次兵法后,都会记录下该武将下一次再发动该兵法的最小时间间隔,这个间隔因发动的兵法种类而不同;
      2). 每过一日,所有武将的间隔值都会减1(已经是0的就不减了);
      3). 只有间隔值为0的武将才会获得兵法发动的机会,非0的要等到有朝一日该值变成0后才会获得机会;
      4). 只有获得兵法发动机会而且身体健康的武将才有可能发动兵法,这个可能性由一个随机数来决定;
      5). 没有发动兵法而且间隔值为0的武将将一直获得兵法发动的机会,直达有朝一日兵法发动了,间隔值变成非0,或者是翘了才不会获得机会。
      以上,便是兵法发动频率的秘密。很明显,如果想要作弊,提高兵法发动的频率,可以有2条途径:
      1). 修改间隔值,将它变小。前面提到的那个小试验便是这种办法。不过,这样修改之后,兵法的发动仍然存在随机性;
      2). 当武将获得机会时,让他一定把握住机会发动兵法。这一条,将完全消除兵法发动的随机性。
      二、兵法的抵挡
      对于一般的兵法(指与智力无关的兵法),如果兵法发动者的熟练度低而对方某一人的熟练度高,那么兵法将被抵挡。根据本人的试验,将熟练度改成3000点,便一定可以抵挡1000点及更低数来弩的兵法。实际上,带大概2000多点就可以实现抵挡了。不过有一个例外:象兵阵队步兵兵法低挡不了,这与游戏中对阵行的说明相符。怎么改熟练度,这个不用再说了吧?随便一个存档修改器……不过问题是改了之后会跳回1000点,不知道锁定能否解决。
      三、兵法如何才会出动画
      相信出动画的兵法通常都会带给大家一个惊喜,因为动画并不是很常见。印象中,黄忠发连弩的时候就很容易出动画,不知道是不是特殊设定。如果要想一定出动画,办法也是有的,仍然是修改熟练度。根据本人的试验,熟练度改到9999点以上时一定会出动画(其他人不要联动)。实际上可能更低一点就可以了。


      IP属地:北京3楼2014-11-19 18:02
      回复
        妈蛋楼被吞了。还有一篇链接发不出来……试一下这样行不
        http://文库.百度.com/link?url=jUmBI9CspNGyRKIE63JnTCZ_LD4TW5vFqALxZ87qDFJ3GKiN_UiS08QKALluckQcSOSt_rixK4d1hZr8Lh4ajEV635ura9ZcrXw5bI1rzGu
        感谢rangzh大神


        IP属地:北京6楼2014-11-19 18:12
        收起回复
          暖贴 欢迎楼主编辑更多这样的信息 酒吧的发展需要大家的努力


          7楼2014-11-19 18:17
          收起回复
            好啦我知道上面很长啦,简单浓缩一下~~
            【为了便于阅读故分为三部分,第三部分参考rangzh的总结较多】
            1. 间隔值
            第一、二篇主要谈到间隔值的部分。间隔值会因兵法的不同而不同。但是不变的是只有存在【间隔值为0】武将的部队才有可能分配到随机结果。兵法发动后间隔值会从0调整到第二篇提到的值。
            2. 部队兵法发动机会
            每一旬部队大致有13-20次的机会发动兵法【但是不一定能把握得住】。在自地域、状态高昂会增加部队把握机会的概率。
            一般来说部队每旬能把握住的发动兵法次数为2.25-4.5次。
            3. 兵法发动机会的分配——影响因素有且只有【位置】【兵法与阵型相性】【人数】三个。
            1)武将的位置影响分配到机会的概率,前锋/中锋=1.25倍,中锋/后卫=1.33倍;
            2)阵形对分配到机会的概率的影响很显著,有利/不利=2倍;
            3)人数也会影响分配概率。人数越多,每个人分配到的概率都会降低,不过总的分丢概率却未必会低;
            4)如果兵力允许的话,尽可能拆分组队。举个例子:3个武将30000*1组队与10000*3组队,假设全选有利阵形,全在前锋,而且假设一个部队一旬内一定能够把握住3次机会,则发动3次兵法的概率:3人队:24.4%,3*1人队:100%。
            5)由于所有的部队产生兵法机会的概率都是一样的,因此真正影响兵法发动的因素在于分配时的概率。


            IP属地:北京8楼2014-11-19 18:32
            回复
              不过上面总结的第4点是从rangzh大神那里搬过来的,我不太理解诶……
              按照rangzh大神的算法,如果3个人,有利兵法,全部前锋的话,那么每个人被分配的概率都是
              10(3个人)*2(有利兵法)*5(前锋)=100%啊……
              这个24.4%怎么算出来的……求各路大神解救……


              IP属地:北京9楼2014-11-19 18:38
              收起回复
                补充:优化伴侣里面已经可以明显看到部队武将数对兵法发动概率的影响数值;并且可以调整各个兵法的发动间隔。这样的话将武将概率值全部调成20,且将特定兵法发动间隔设为1的话,部队就可以保证达到可以把握到的次数最大值,也就是每旬1.95-3次。
                症结在于,首先系统每旬默认分配给部队的次数为固定的13-20次,其实这个还好;但是部队把握这个机会的比率基础值为15,造成了兵法发动次数的显著下降。如何突破这一瓶颈是修改器需要继续寻找的问题~


                IP属地:北京来自Android客户端10楼2014-11-20 02:25
                回复
                  好复杂


                  来自Android客户端12楼2014-11-24 19:43
                  回复
                    真是大神啊,好强大。作为一个程序员,我都看不下去,好长啊,怎么可以这么复杂。


                    IP属地:辽宁来自Android客户端13楼2014-11-25 14:07
                    收起回复
                      那么问题来了,如何修改兵法发动间隔呢?


                      14楼2016-03-05 23:22
                      回复