吴佳骅
摘 要 游戏的爆率影响着游戏的用户体验,使用变动式随机概率能提供较好的用户体验,本文运用阈值逼近的方法给出了一种变动式随机概率的实现方式。
关键词 游戏 随机概率 阈值逼近
中图分类号:TN948.7 文献标识码:A
如今的信息时代下,在人们的日常休闲娱乐方式中,游戏已经成为相当普遍的一个选择。各种游戏层出不穷,市场竞争也相当激烈。从最近的调查结果来看,游戏的良好用户体验是一款游戏留住用户的根本。除了游戏本身的设计公平性和趣味性之外,游戏中的爆率也是很重要的一环。游戏如果使用固定爆率则等于把用户完全扔进了看脸拼人品的世界,很不利于使用户拥有良好体验。所以如何设计实现变动式的随机爆率,是游戏设计中需要考虑的一环。阈值逼近方法就是适合解决变动式随机爆率的一种方式。
所谓阈值逼近方法,其核心就是设定一个基本的阈值,然后一次一次向阈值逼近的过程。在逼近过程中得到逐渐趋近于阈值的几率。比如原始几率10%,阈值为50%,一次事件发生后该几率增加1%,下一次事件发生时的实际几率为11%,依此类推,直到成为50%的不变值。
游戏中爆率类的几率性事件很多,除了基本的掉装备材料的爆率之外,卡牌类的抽卡概率,游戏技能的触发概率,游戏角色暴击概率,都属于这类事件。
以游戏技能的触发概率为例,比如某游戏中的技能A有30%的额外伤害概率,可以设置初始概率为5%,设置阈值为60%,如果当次未触发,则下次使用时概率乘以2,如果再次没有触发,则继续该算法计算,最终达到60%。如果某次触发了技能A的额外伤害,则将下一次的概率重置为初始概率。如此一来,最糟情况下3次未触发之后就拥有60%的高概率,比恒定30%的概率用户体验要好很多。
为了使这个概率变动模型能够复用,可以考虑在程序中将其写成类,
class Randomrate{
double basicrate,rate,toprate,step;
public Randomrate(double br,double t,double s) {
basicrate = br; rate = basicrate; toprate = t; step = s;
}
public double getrate() {
return rate;
}
public void increaserate() {
if (rate == toprate) return ;
rate *= step;
if (rate >= toprate) rate = toprate;
}
public void initrate(bool ifhandle) {
if(ifhandle) rate = basicrate;
}
}
其中,basicrate是初始概率,rate是实际概率,toprate是阈值,step是实际概率的变动步进值。
如此这般,在技能A第一次使用前即可建立Randomrate的对象one,之后只需要每一次调用one对象的getrate()方法即可获得当次技能A的额外伤害概率,将每一次额外伤害发生与否的布尔值作为参数传入one对象的initrate()方法,如果刚刚发生过额外伤害,则下一次的伤害概率就会还原为原始的basicrate的值。为了节省游戏资源,可以在进入战斗场景时建立对象one,而在离开战斗场景时释放对象one,下一次进入时再重新建立。
除此之外,阈值逼近还有另外一种形式,即得到一个逐步缩小的随机区间,从而变相地获得高概率。
这种形式用来解决卡牌类游戏的高级卡抽牌概率最为合适,因为这类游戏的用户通常希望在若干抽之后就必定能获得一张高级卡。
这种形式下的概率实现,可以使用随机数,比如概率15%,实际操作中可以看做是随机取得1-10000之间某个数,若取得的数是1-150,则使随机事件发生。将其写成类,
class Randomrate2{
int min,max,maxnow,top,step;
public Randomrate2(int mi, int ma, int t,int s) {
min = mi; max = ma; maxnow = max; top = t; step=s;
}
public int getmaxnow() {
return maxnow;
}
public int getmin() {
return min;
}
public void discreasemax() {
if (maxnow <= top) return;
maxnow -= step;
if (maxnow <= top) maxnow = top;
}
public void initmaxnow(bool ifhander) {
if (ifhander) maxnow = max;
}
}
其中,min是随机范围的下限值,max是初始上限值,maxnow是实际上限值,top是阈值,step是实际上限值变动的步进值。
如此这般,当用户第一次抽卡时建立Randomrate2类型的对象one,抽卡时按one.getmin()--one.getmaxnow()这个范围获得随机值,如果不中,则执行one的discreasemax()方法减小实际上限值maxnow,下一次抽卡时的随机范围便降低了,也就等于變相增大的发生概率。实际上限值减小到阈值top时将保持不变。每一次抽到高级卡与否的结果会作为参数传入one的initmaxnow()中,若某次用户抽中了高级卡,则实际上限值maxnow会重置为初始上限值max。
在实际操作中,如想尽快达到阈值,可以设置较大的数为step,也可以把步进方式改为除法或其他数学运算,比如2分法。如果想要确保若干次后必定可以抽到高级卡,可以将阈值设定为min或者有效区间的上限值。endprint