吳佳驊
摘 要 游戲的爆率影響著游戲的用戶體驗,使用變動式隨機概率能提供較好的用戶體驗,本文運用閾值逼近的方法給出了一種變動式隨機概率的實現方式。
關鍵詞 游戲 隨機概率 閾值逼近
中圖分類號: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