勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

ソシャゲのガチャのように当選確率が異なる抽選システムをPHPで作成する方法

   2024/01/28  PHP

ソシャゲのガチャみたいな当選確率が異なる抽選システムをPHPで作成したかった。具体的にはレア度が1~6まであり、レア度が低いものは当たりやすくレア度が高いものは当たりにくいというもの。また、レア度それぞれの当たりやすさ(当選確率)も制御したい。以下に実装方法をメモ。

 

ソース

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
//ガチャ用データ
$data = array(
0 => array('name' => '星1', 'rate' => 30),
1 => array('name' => '星2', 'rate' => 25),
2 => array('name' => '星3', 'rate' => 20),
3 => array('name' => '星4', 'rate' => 15),
4 => array('name' => '星5', 'rate' => 9),
5 => array('name' => '星6', 'rate' => 1),
);
echo $data[gacha($data)]['name']; //当たった配列のnameを出力
function gacha( $data = array() ){
//確率の合計値
$max = 0;
foreach( $data as $record ) $max += $record['rate'];
//当たりの決定
$hit = mt_rand( 0, ($max - 1) );
//当たった乱数がどの部分になるのか調べてヒットしたら返す
foreach( $data as $key => $record ){
$max -= $record['rate'];
if( $max <= $hit ) return $key;
}
}
?>
<?php //ガチャ用データ $data = array( 0 => array('name' => '星1', 'rate' => 30), 1 => array('name' => '星2', 'rate' => 25), 2 => array('name' => '星3', 'rate' => 20), 3 => array('name' => '星4', 'rate' => 15), 4 => array('name' => '星5', 'rate' => 9), 5 => array('name' => '星6', 'rate' => 1), ); echo $data[gacha($data)]['name']; //当たった配列のnameを出力 function gacha( $data = array() ){ //確率の合計値 $max = 0; foreach( $data as $record ) $max += $record['rate']; //当たりの決定 $hit = mt_rand( 0, ($max - 1) ); //当たった乱数がどの部分になるのか調べてヒットしたら返す foreach( $data as $key => $record ){ $max -= $record['rate']; if( $max <= $hit ) return $key; } } ?>
<?php
//ガチャ用データ
$data = array(
    0 => array('name' => '星1', 'rate' => 30), 
    1 => array('name' => '星2', 'rate' => 25), 
    2 => array('name' => '星3', 'rate' => 20), 
    3 => array('name' => '星4', 'rate' => 15), 
    4 => array('name' => '星5', 'rate' => 9), 
    5 => array('name' => '星6', 'rate' => 1), 
);
echo $data[gacha($data)]['name']; //当たった配列のnameを出力


function gacha( $data = array() ){

    //確率の合計値
    $max = 0;
    foreach( $data as $record ) $max += $record['rate'];

    //当たりの決定
    $hit = mt_rand( 0, ($max - 1) );

    //当たった乱数がどの部分になるのか調べてヒットしたら返す
    foreach( $data as $key => $record ){
        $max -= $record['rate'];
        if( $max <= $hit ) return $key;
    }

}
?>

当選確率について

rateが確率の部分。整数値でも小数値でも良い。合計を100にするとパーセンテージとして分かりやすい。100を超えても問題ない。

実運用について

実運用としては予めMySQLにレア度1~6のガチャ商品(アイテムやキャラクタ等)のデータをレア度と共に保存しておき上記のガチャで抽選後、以下のようなSQL文で取り出す形になりそう。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//指定したレア度のデータをランダムで1件取得
SELECT *
FROM `gacha`
WHERE `rate` = 'レア度'
ORDER BY RAND()
LIMIT 1;
//指定したレア度のデータをランダムで1件取得 SELECT * FROM `gacha` WHERE `rate` = 'レア度' ORDER BY RAND() LIMIT 1;
//指定したレア度のデータをランダムで1件取得
SELECT * 
FROM `gacha` 
WHERE `rate` = 'レア度'
ORDER BY RAND() 
LIMIT 1;

 

その他

最初は確率分の配列を作って、そこからランダムに引けば良いのかと思った。例のソースの場合だと計100個の値が入った配列を作ってそこから引くというもの。ただこれだとデータ数が多い場合に負荷がかかるみたい。

 - PHP

  関連記事

wp_mail関数でエンベロープFrom(Return-Path)が指定できない場合の対応方法

WordPress内に設置されたお問い合わせのフォームようなシステムでエンベロー ...

フォームからCSVファイルをアップロードしてPHPの配列に格納する方法

formからcsvファイルをアップロードさせて、PHPで色々処理したかった。とり ...

PHPで指定月の月末日を取得

今月の、だったらdate('t')でいくけど指定月の場合は どうしたらいいのか分 ...

PHPで配列のキーの最大値を取得する方法

配列のキーに整数値が入っていて、その中から最大値を取得したいケースがあった。調べ ...

PHPページングテンプレ

使いやすいのがあったのでメモ。   $page            ...

S