敵を倒した時に15%の確率でランクAのアイテムをドロップし、25%の確率でランクBのアイテム、60%の確率でランクCのアイテムをドロップする、といった分岐処理に役立つクラスを試作。クラス名は適当。
探せば同様のものが既にあるかもしれませんが…。
結果を返す所でUniLinqを利用しているので注意。
ProbabilityRatio.cs
using UnityEngine;
using System;
using System.Collections.Generic;
using UniLinq;
static public class ProbabilityRatio<T>{
static public T GetResult(Dictionary<T,int> events){
int sum = 0;
foreach (var e in events) {
sum += e.Value;
}
int rnd = UnityEngine.Random.Range (0, sum);
int tmp = 0;
foreach (var e in events) {
tmp += e.Value;
if (rnd < tmp) {
return e.Key;
}
}
return events.FirstOrDefault (x => x.Value > 0).Key;
}
}
使い方はまず結果となる型を用意し、その発生確率を整数比で表したものを値としてDictionary変数に追加します。 あとは変数を先程の関数に代入するのみです。
例:ドロップアイテムのランクとドロップ確率の比
RankA : RankB : RankC = 15 : 25 : 60
sample
using UnityEngine;
using System.Collections.Generic;
public class sample : MonoBehaviour {
public enum SampleRank{
C,B,A
}
void Start () {
var tmp = new Dictionary<SampleRank,int> ();
tmp.Add (SampleRank.C, 60);
tmp.Add (SampleRank.B, 25);
tmp.Add (SampleRank.A, 15);
var res = ProbabilityRatio<SampleRank>.GetResult (tmp);
Debug.Log (res);
}
}
発生確率が小数点以下だったとしても、比が整数比になるように値をかけてやれば問題なく使えます。
例 A : B = 0.1 : 99.9 = 1 : 999
var tmp = new Dictionary<SampleRank,int> (); tmp.Add (SampleRank.A, 1); tmp.Add (SampleRank.B, 999);