游戏命中判定:圆桌算法和程序实现

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

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

圆桌算法是将这些属性(命中普通攻击、未命中、招架、命中致命攻击)放在一起,构成一个圆桌。如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、通过输入参数能够调整一个系数。

 

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

 

posted @ 2012-02-07 11:35  CodeGize  阅读(1941)  评论(0编辑  收藏  举报
CodeGize的个人博客