zoukankan      html  css  js  c++  java
  • 游戏命中判定:圆桌算法和程序实现

    游戏中常常要做一个动作的命中判定,比如攻击的命中判定,结果一般为未命中、普通命中,致命命中,命中格挡等(当然复杂起来远不只这些)。一般的,程序上(或策划上)采用的是优先级概率算法或者圆桌算法。

    优先级概率的算法是:先判定是否未命中,如果命中是否闪躲,如果未闪躲是否招架,最后才是普通攻击(有省略)。也就是说按优先级(顺序)进行概率计算和判断。

    圆桌算法是将这些属性(命中普通攻击、未命中、招架、命中致命攻击)放在一起,构成一个圆桌。如20%未命中,5%致命攻击,30%招架,剩余45%为普通攻击。

    从上面的描述来看,圆桌算法输入的参数是一个代表概率的数组,或者,更广泛地说是一组系数。我们完全没有必要将参数固定为合起来为100%的概率值(虽然这么做同样可行)。因为当我们知道一组系数的时候,我们也同时知道了每个系数在这一组数据中所占的比例。如我们可以使用102030来做参数,显然,10所占的比例是10/(10+20+30)1/6,同样的,202/6303/6。所以这扩展了程序员和策划的自由度。而圆桌算法的输出则是一个代表圆桌某一个部分的索引。例如0表示10的部分,1表示20的部分,2表示30的部分。这里要注意的是,这些系数显然必须是一个正数,负值的系数是没有意义的。

    算法的流程是:随机生成一个数字,判断这个数在哪个区间中,然后输出这个区间的编号即可。当然,我们可以生成一个介于01的数字,然后判定分布于哪个概率区间即可。在文章的最后将给出具体C#代码。

    继续,我们讨论关于圆桌算法牺牲属性的问题(吃完普通攻击吃致命一击的问题)。这个问题的描述是(http://baike.baidu.com/view/1927517.htm)

    对于例子:

    目标的躲闪几率……20% 

    目标的招架几率……5% 

    战士的致命一击率……30%

    当闪躲增加50%时按照刚才的圆桌理论算法结果为:

    躲闪几率70%

    招架几率5%

    致命一击几率25%30%-5%

    出现普通攻击的几率0 %

    随着属性的增加,例如当躲闪提高到90%,招架提高到15%的时候,会出现如下的属性:

    出现躲闪字样的几率90%

    出现招架字样的几率10%15%-5%

    出现致命一击的几率0%

    出现普通攻击的几率0%

    这一次,作出牺牲的是普通攻击,致命一击还有招架,其中致命一击已经完全被牺牲掉,这对于结果的公平性是很大的负面影响。

    但是,可以有另外一种计算方法,而不用牺牲个别属性,这就是本文提出的方法。

    同样的例子(我们用X代表属性,第二列的数字表示概率或者说系数):

    X1

    20

    X2

    5

    X3

    30

    X4

    45

    如果X1提高到70%,那么其他属性自然而然地降低。为什么都要降低呢?很合理的,而原来的几率是相对于整个圆桌而言的,当整个圆桌因为一个属性的几率增大时,其他属性就会按比例的缩小,这样才能体现公平性了。因为前面的方法不合理的地方就是在于先牺牲了一种属性。这里有一点要说的是,将一个属性的几率提高到100%以上是没有意义的,因为100%就意味着必然发生。

    那么将X1几率提高到70%后其他应该怎么变化呢?上面已经提到——按比例。在该例子中,原来X2几率为5%X330%,剩余X445%,除去X1后,

    X2占剩余的5%/(1-20%)=5/80

    X330/80

    X445/80

    X1几率提高到70%,剩余30%供其他属性分享。因此结果是:

    X1

    70

    X2

    1.875

    X3

    11.25

    X4

    16.875

    合起来依然是100%。于是在数值上的合理性就可以验证了。(代码依旧在文章的最后。)

    但是在实际上,新问题会不断出现,主要表现在调整的先后顺序上,即先提高X170%,再提高X270%,和先提高X270%再提高X170%,得到的结果完全不同,程序计算结果如下:

    1

     

    原来

    先提高X170%

    再提高X270%

    X1

    20

    70

    21.4012738853503

    X2

    5

    1.875

    70

    X3

    30

    11.25

    3.43949044585987

    X4

    45

    16.875

    5.15923566878981

     

    2

     

    原来

    先提高X270%

    再提高X170%

    X1

    20

    6.31578947368421

    70

    X2

    5

    70

    22.4157303370787

    X3

    30

    9.47368421052632

    3.03370786516854

    X4

    45

    14.2105263157895

    4.55056179775281

    这组数据表明,调整的先后顺序会影响计算的结果。我们不妨想象在真实的游戏中,玩家开启闪躲技能,将闪躲提高到了70%,那么玩家希望的就是不被命中。然后开启招架技能,将招架提高到了70%,这时玩家希望的是同时拥有70%的闪躲和70%的招架。也就是说如果被命中(30%),尽量出现招架。但是表1表明此时闪躲的概率降低了,不满足玩家期望的效果。

    这个问题本质上是优先级问题,圆桌上的所有属性应当是同优先级的。我们可以将命中判定分为2个部分,对于存在优先级的属性采用优先级概率算法,对于同优先级的采用圆桌算法。这样会形成如下图的结构:

     

    实际中可以先做命中和非命中的圆桌运算,然后做其他优先级相同的属性的圆桌运算,输出最终的命中类型。当然如果还有属性中的优先级需要存在,我们可以再做一轮圆桌计算。

    从这样的分析来看,圆桌算法的程序实现上不存在这样的问题。所以圆桌算法类应该有以下几个功能:

    1、通过输入的参数输出结果。2、通过输入参数能够调整一个系数。

    具体代码见链接地址(链接地址

    个人博客请访问:http://www.cnblogs.com/CodeGize/
  • 相关阅读:
    企业级-Shell案例6——查看网卡的实时流量
    匿名内部类--毕向东java基础教程学习笔记
    简单的Windows登陆界面设计
    初学多线程练习1--电子时钟
    内部类--毕向东Java基础教程学习笔记
    异常处理——毕向东Java基础教程学习笔记
    Linux:常用shell命令
    CVE-2019-0708漏洞利用复现
    MS17-010漏洞利用复现
    RIP路由协议:基础设置/通信练习/兼容问题
  • 原文地址:https://www.cnblogs.com/CodeGize/p/2341050.html
Copyright © 2011-2022 走看看