いい方法はありますか?
少し前にPHPおみくじの機能を作ることがありました。
まぁ確率によってランダムで出てくるガチャガチャみたいな感じのものですね。
今日はそのときの実装方法を書き残しておきます。
PHPで抽選おみくじ機能を作りました
作った機能はいかのような特徴をもつおみくじです。
・条件によって確率が変動
・確率によってランダムに○等があたる(1~7等)
・等級に応じてポイントゲット
ちなみに確率とポイントはDBのほうで管理しています。
そこからの抽出に関しての処理はここでは紹介していません。
今回は「与えられた配列」をもとに「ランダムで抽選する」という処理の紹介になります。
与えられる配列の想定
さっそくですが抽選おみくじ(ガチャ)で使う配列は以下のとおりです。
(
[レート] => 確率
[ポイント] => ゲットポイント
[ランク] => 何等
)
Array
(
[0] => Array
(
[rate] => 0.05
[point] => 300
[rank_num] => 1
)
[1] => Array
(
[rate] => 0.1
[point] => 200
[rank_num] => 2
)
[2] => Array
(
[rate] => 0.5
[point] => 100
[rank_num] => 3
)
[3] => Array
(
[rate] => 1.05
[point] => 50
[rank_num] => 4
)
[4] => Array
(
[rate] => 1.2
[point] => 25
[rank_num] => 5
)
[5] => Array
(
[rate] => 1.5
[point] => 10
[rank_num] => 6
)
[6] => Array
(
[rate] => 10.6
[point] => 5
[rank_num] => 7
)
[7] => Array
(
[rate] => 85
[point] => 1
[rank_num] => 8
)
)
上記の配列はあらかじめ確率の昇順で並べておいてください。
(上記の配列はソート後です)
並び替える処理は以下のコードでOKです。
//確率の低いものから昇順にする
//$dataにさきほどの配列が入ります
foreach((array) $data as $key => $value){
$sort[$key] = $value['rate'];
}
if(isset($sort)){
array_multisort($sort,SORT_ASC,$data);
}
ちなみに今回のデータでは1等は300ポイントで、出る確率は5%ということですね。
このへんはあなたが作りたいものに合わせて調節してください。
関係ないですけど一般的には1等は1~3%内におさまるのかな?と思います。
僕が好きな某スマホゲームとかでもそうですね。
実際の抽選を行う関数
与えられた配列をもとに実際の抽選(ガチャ)を行う関数です。
//当たりのデータのキーを返します
public function doLottery($data){
//最小確率の少数桁数
$minRate = $data[0]['rate'];
$minRateDigits = strlen(substr(strrchr($minRate, '.'), 1));
$multiplicationNum = pow(10, $minRateDigits);
//確率の合計値
$max = 0;
foreach($data as $record){
$max += $record['rate'];
}
$max = $max * $multiplicationNum;
//当たりの数値決定
$hit = mt_rand(1, $max);
//確率に応じて当たりを判定
foreach($data as $key => $record){
$max -= ($record['rate'] * $multiplicationNum);
if($max < $hit){
return $key;
}
}
}
処理の中身としては以下のような流れになっています。
①最小確率に応じて対象の個数を設定
②ランダムな数字を設定した個数の中から1つ選択
③確率に応じて設定した個数から引いていきランダムな数字より小さくなった時点のキーを返す
文字にするとわかりにくいですが考え方はシンプルです。
たとえば1%が1等、10%が2等、89%が3等の場合は100個玉を用意します。
つぎに1~100の中でランダムな数字を決めます。
たとえば44としましょう。
最後に1、10、79の順に100から引いていきます。
100-1=99 → 44より大きいのでスルー
99-10=89 → 44より大きいのでスルー
89-89=0 → 44より小さいのであたり
今回は89%のデータに決定
というわけです。
今回の関数では別に合計の確率が100でなくても成り立つようになっています。
抽選おみくじ(ガチャ)を実装して感じたこと【おわりに】
ガチャガチャって気軽に実装できて、かつユーザーにかなりの楽しさを与えることができるので個人的には結構良い機能だなと思います。
最初にも話したとおり、確率をDBに入れておいて(固定でもいいけど)ユーザーの状況によって可変的に確率を変えることができるようになるとさらに盛り上がる機能になるかもしれません。
ぜひ試してみてください。