吳佳驊
摘 要 游戲的爆率影響著游戲的用戶體驗(yàn),使用變動式隨機(jī)概率能提供較好的用戶體驗(yàn),本文運(yùn)用閾值逼近的方法給出了一種變動式隨機(jī)概率的實(shí)現(xiàn)方式。
關(guān)鍵詞 游戲 隨機(jī)概率 閾值逼近
中圖分類號:TN948.7 文獻(xiàn)標(biāo)識碼:A
如今的信息時代下,在人們的日常休閑娛樂方式中,游戲已經(jīng)成為相當(dāng)普遍的一個選擇。各種游戲?qū)映霾桓F,市場競爭也相當(dāng)激烈。從最近的調(diào)查結(jié)果來看,游戲的良好用戶體驗(yàn)是一款游戲留住用戶的根本。除了游戲本身的設(shè)計(jì)公平性和趣味性之外,游戲中的爆率也是很重要的一環(huán)。游戲如果使用固定爆率則等于把用戶完全扔進(jìn)了看臉拼人品的世界,很不利于使用戶擁有良好體驗(yàn)。所以如何設(shè)計(jì)實(shí)現(xiàn)變動式的隨機(jī)爆率,是游戲設(shè)計(jì)中需要考慮的一環(huán)。閾值逼近方法就是適合解決變動式隨機(jī)爆率的一種方式。
所謂閾值逼近方法,其核心就是設(shè)定一個基本的閾值,然后一次一次向閾值逼近的過程。在逼近過程中得到逐漸趨近于閾值的幾率。比如原始幾率10%,閾值為50%,一次事件發(fā)生后該幾率增加1%,下一次事件發(fā)生時的實(shí)際幾率為11%,依此類推,直到成為50%的不變值。
游戲中爆率類的幾率性事件很多,除了基本的掉裝備材料的爆率之外,卡牌類的抽卡概率,游戲技能的觸發(fā)概率,游戲角色暴擊概率,都屬于這類事件。
以游戲技能的觸發(fā)概率為例,比如某游戲中的技能A有30%的額外傷害概率,可以設(shè)置初始概率為5%,設(shè)置閾值為60%,如果當(dāng)次未觸發(fā),則下次使用時概率乘以2,如果再次沒有觸發(fā),則繼續(xù)該算法計(jì)算,最終達(dá)到60%。如果某次觸發(fā)了技能A的額外傷害,則將下一次的概率重置為初始概率。如此一來,最糟情況下3次未觸發(fā)之后就擁有60%的高概率,比恒定30%的概率用戶體驗(yàn)要好很多。
為了使這個概率變動模型能夠復(fù)用,可以考慮在程序中將其寫成類,
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是實(shí)際概率,toprate是閾值,step是實(shí)際概率的變動步進(jìn)值。
如此這般,在技能A第一次使用前即可建立Randomrate的對象one,之后只需要每一次調(diào)用one對象的getrate()方法即可獲得當(dāng)次技能A的額外傷害概率,將每一次額外傷害發(fā)生與否的布爾值作為參數(shù)傳入one對象的initrate()方法,如果剛剛發(fā)生過額外傷害,則下一次的傷害概率就會還原為原始的basicrate的值。為了節(jié)省游戲資源,可以在進(jìn)入戰(zhàn)斗場景時建立對象one,而在離開戰(zhàn)斗場景時釋放對象one,下一次進(jìn)入時再重新建立。
除此之外,閾值逼近還有另外一種形式,即得到一個逐步縮小的隨機(jī)區(qū)間,從而變相地獲得高概率。
這種形式用來解決卡牌類游戲的高級卡抽牌概率最為合適,因?yàn)檫@類游戲的用戶通常希望在若干抽之后就必定能獲得一張高級卡。
這種形式下的概率實(shí)現(xiàn),可以使用隨機(jī)數(shù),比如概率15%,實(shí)際操作中可以看做是隨機(jī)取得1-10000之間某個數(shù),若取得的數(shù)是1-150,則使隨機(jī)事件發(fā)生。將其寫成類,
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是隨機(jī)范圍的下限值,max是初始上限值,maxnow是實(shí)際上限值,top是閾值,step是實(shí)際上限值變動的步進(jìn)值。
如此這般,當(dāng)用戶第一次抽卡時建立Randomrate2類型的對象one,抽卡時按one.getmin()--one.getmaxnow()這個范圍獲得隨機(jī)值,如果不中,則執(zhí)行one的discreasemax()方法減小實(shí)際上限值maxnow,下一次抽卡時的隨機(jī)范圍便降低了,也就等于變相增大的發(fā)生概率。實(shí)際上限值減小到閾值top時將保持不變。每一次抽到高級卡與否的結(jié)果會作為參數(shù)傳入one的initmaxnow()中,若某次用戶抽中了高級卡,則實(shí)際上限值maxnow會重置為初始上限值max。
在實(shí)際操作中,如想盡快達(dá)到閾值,可以設(shè)置較大的數(shù)為step,也可以把步進(jìn)方式改為除法或其他數(shù)學(xué)運(yùn)算,比如2分法。如果想要確保若干次后必定可以抽到高級卡,可以將閾值設(shè)定為min或者有效區(qū)間的上限值。endprint