柴游伤害测试的实验方法
前言
各位好,这里是面粉敌对。
两年半以前,敌对做了一个粗糙的火柴人攻略,在那里有说一些枪械、空手以及扔枪的伤害,在之后的攻略中也多次提到一些结论是由这些数据得来的。
关于这些数据的由来,敌对好像之前有写过一篇专栏,又好像没有。
今天看到有评论提到这一点,就说一下吧。
初始信息的获得
原问题是这样的:
“我很好奇up主是怎么知道大约伤害呢,游戏里没有显示扣的血量,只知道打人正常5拳就打死了,为什么空手不是20是22很好奇。”
是的,通过5拳能打死人我们只能得到以下两个信息:
5拳能打死,所以伤害大于等于20。
4拳打不死,所以伤害小于25。
但这仅仅是正常100HP下的结论,如果设置为300HP,你会发现需要14拳才能打死,同样,我们得到了两个信息。
14拳能打死,所以伤害大于等于21.43
13拳打不死,所以伤害小于23.08
这样我们就将范围缩小了,但仍然不能得到一个确定的值。
从开发者的角度来说,将伤害数据设置成一个很复杂的数显然不是一件明智的事,因此这里提出了一项假定。
假定:伤害为整数。
在接受了整数假定之后,空手出拳的伤害就缩小到了22和23两个整数了,但仍然不能确定是哪一个,我们还需要进一步测试。
既然测不出空手的伤害,那其他的呢?能不能先测出一个?
相信你已经发现了,在空手这种中等伤害的攻击下,最终被锁定范围在300/14到300/13之间,那如果是更低伤害的攻击方式,那这个范围的长度就更小了,再结合整数的假定,我们就能得到第一个确切的数据了。
于是第一个有确切伤害的数据被测试出来了——UZI,300HP下22发子弹能击杀敌人,伤害为14。
缩小范围
接下来就是这项测试的关键了,我们该如何利用已经得到在整数假设下拥有确切伤害数据的武器去得到其他中等甚至是高伤害的武器伤害呢?
我们再来回顾一下空手伤害数据的测试:在空手的攻击下,伤害范围最终被锁定在300/14到300/13之间。
要如何缩小这个区间呢?
300已经是最高HP了,换句话说21.43到23.08这个区间的长度,已经是HP/13-HP/14中的最小值了。
但这仅仅是Min(HP/(次数-1)-HP/次数),而我们最终要得到的,是Min(HP/(次数-1))-Max(HP/次数)。是的,通过改变HP,我们能够刷新范围上下限,最终从所有下限中找到最大那个,从所有上限中找到最小那个,从而达到范围的缩小。
而如何改变HP,答案已经呼之欲出了——利用已经测出伤害的武器。譬如要测试空手,我们只需要在用空手攻击工具人之前,用UZI给他来上几枪,这样就能改变HP。
像UZI这样的已知整数假定下的确切伤害的,我们称之为“探针武器”,通过探针改变初始HP,就能对伤害范围进行缩小。
HP虽然减少了,但相应的,最终击杀工具人所需的攻击次数也在减少。
这里将击杀所需次数记为X,那么伤害H=Min(HP/(x-1))-Max(HP/x).
而HP=300-a1*n1-a2*n2-a3*n3……
此处a1等为使用的探针武器的伤害,n1等为使用的探针武器的次数。
探针使用次数的确定
那么问题又来了,这里的n到底要取多少呢?具体到空手伤害的测定,就是“给工具人打拳之前,我要用uzi射他几次呢?”。
如果每一次的HP都是凭感觉得到的,新得到的区间就不一定能够缩小范围,也就是“无效测试”。为了避免测试次数过多,我们需要找到一个稳定的测试方法,即得到一个好的n。
要想得到一个合理的n,我们就得知道加入探针之后的测试到底是做了一件怎样的事。
探针使得HP减少,因此我们一次测试得到的结果——击杀工具人所需攻击次数X是不可能大于最初的X的。
那么对于单个探针的测试,将n从1开始罗列,我们会发现一件事。
以空手伤害的测试为例,n=1,a=14,HP=286.
我们期望得到的X有可能是多少?
从先前无探针的结果已知空手伤害的粗略上下限。
可能的X必须满足,(X-1)*(下限)<=HP<=X*(上限)
因此当n=1,X可以取14、13。
当n=2,HP=272,X可以取13、12。
当n=3,HP=258,X只能取12。
……
对每个n,我们对其带来的效果进行评估。
对于n=1,若X为14,则区间为20.43-22,降低了上限。若为13,则区间为22-23.83,下限并没有提高。这是因为最初的范围经过整数假定修改为了22-23.
对于n=2,若X为13,则区间为20.92-22.67,降低了上限。若为12,则区间为22.67-24.72。提高了下限
对于n=3,X只能为12,区间为21.5-23.45,上下限都没有缩小,排除。(我不用实验都能推测出X只能取一个值了,还可能缩小范围吗?)
我们可以选择从n=1开始,寻找第一个可能满足缩小范围的n,(或者设置为先寻找一个无论X取多少都能缩小范围的n,找不到就选可能缩小范围的n中数值最小那个)只要满足了,就用这个n进行试验。得到的结果用于生成新的范围,再将新的范围设为选取新n的标准,就能保证每次都在缩小范围,直到范围内的整数只有一个或者无法缩小范围。
这就是n选取的方法,这个过程可以用一些简单的编程实现,实验时我们只用更新伤害的范围,然后让程序告诉我们有效的n。
一些别的
虽然用到了一些简单的C,但整体还是属于实验方法,获得的数据用来解释现象是足够的,但精确性就是另一个问题了。敌对测试伤害那个时候还没有发现什么解包啊显示HP之类的高科技。后来那些方法也有人测了下,得到的结果应该比敌对更加精确,一些数据也得到了互相印证,据说有些伤害是带0.5的,但敌对的数据用来解释现象已经完全足够了。
敌对的这套方法包括当时写的小程序都是两年多以前的了,而且没写注释(已经看不懂了,噔噔咚),当时怎么想的现在只能说是复原一下,肯定有区别,并且当时后面测试大伤害武器的时候用了新的探针武器,又或者是几个探针一起上,估计还有一些纰漏什么的。
当时测完大概半年之后,又用这个方法测了下BOSS伤害,然后发现了BOSS的秘密(大小球伤害变化之类的),于是拉着剑杨试验了好久单挑BOSS方法,最终总结出来了一些心得,还对每个BOSS的弱点进行了评估,然而我咕了。