知ってるようでしらないガチャロジックの実装
お疲れ様です。バンクです。
今回三度目の投稿と言うことで、今度こそボクの大好きなソーシャルゲームを紹介しようとおも… うわっ、何をすrhjk…
やっぱり、システムはシステムっぽい投稿しないとだめですよね。
ええ、そうですね。
近頃パソコンの水洗いをしたり、忘年会のセッティングしたりと大忙しなボクですが、
今回はソーシャルゲームに欠かせない『ガチャ』をシステム的に考えてお伝えしたいと思います。
一般的なガチャ
日本人なら誰しも一度は回したことのあるガチャですが、世の中一般的にはwikipediaによると
「小型自動販売機の一種で、硬貨を入れレバーを回すとカプセル入りの玩具などが出てくるもの、またその取り出した玩具を指す」
http://ja.wikipedia.org/wiki/カプセルトイ
まあ、読んでいただいているみなさんが思っているのと同じです。
では、まずこれをプログラムでぱぱっと書いてみると。。。
1 2 3 4 5 6 7 8 |
[sourcecode lang="php"] // 中身 $gacha = array("筋肉男消し", "連邦の白い悪魔消し", "裏返すと飛んでくゴム", "超車", "バネ", "汚くなる粘着質のあれ"); // でるやつ $hitkey = rand(0, count($gacha)); echo $gacha[$hitkey]; // でたやつけす unset($gacha[$hitkey]); [/sourcecode] |
あっというま!
あんまり説明いらないくらい簡単ですね
リストがただのarrayですが脳内変換でDBとかに入れ替えてください。。。
これ、全部でちゃったらそのあとどうするの?
そうです。プログラムなのに中身がなくなったら手動で追加するとか面倒なので。。。
最後のunsetとっちゃいます。
(残して、自動追加入れると通称ボックスガチャになるよ!)
で、SSレア入れたいんだけど?
そう、このままだと今はやりの超低確率『SSレア』とか『Uレア』とか『れじぇんど』とかできません。
というわけで仕様追加です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[sourcecode lang="php"] // 中身 $gacha = array( "0" => array( "name" => "筋肉男消し", "percent" => 12), "1" => array( "name" => "連邦の白い悪魔消し", "percent" => 1), "2" => array( "name" => "裏返すと飛んでくゴム", "percent" => 67), "3" => array( "name" => "超車", "percent" => 10), "4" => array( "name" => "バネ", "percent" => 5), "5" => array( name => "汚くなる粘着質のあれ", percent => 5) ); // でるやつ $hitRand = rand(0, 100); echo $hitRand . "\n"; // 初期化 $sumPer = 0; for ($i = 0; $i < count($gacha); $i++) { $sumPer += $gacha[$i]["percent"]; $hitItem = $gacha[$i]; if ($hitRand < $sumPer) { break; } } var_dump($hitItem); [/sourcecode] |
簡単に説明すると中身とその出現パーセントを設定しておき、0〜100までの間で抽選し、 パーセントからでるやつを……ってソース見てもらえばわかります。
これで一通りガチャの機能条件は満たせますね。
で、新カード追加したいんだけど?
えーと最後に一行追加して、パーセントを合計が100になるように好きなように変更してください。
・・・・・・・・・・・・今はいってるデータは変えたくないんだけど。
・・・・・・うん、仕様追加だ!
1 2 3 4 5 6 7 8 9 10 |
[sourcecode lang="php"] // 中身 $gacha = array( "0" => array( "name" => "筋肉男消し", "select_rate" => 12), "1" => array( "name" => "連邦の白い悪魔消し", "select_rate" => 1), "2" => array( "name" => "裏返すと飛んでくゴム", "select_rate" => 67), "3" => array( "name" => "超車", "select_rate" => 10), "4" => array( "name" => "バネ", "select_rate" => 5), "5" => array( "name" => "汚くなる粘着質のあれ", "select_rate" => 5) ); // sum selectRate $sumRate = 0; foreach($gacha as $v) { $sumRate += $v["select_rate"]; } // でるやつ $hitRand = rand(0, $sumRate); echo $hitRand . "\n"; // 初期化 $tmpRate = 0; for ($i = 0; $i < count($gacha); $i++) { $tmpRate += $gacha[$i]["select_rate"]; $hitItem = $gacha[$i]; if ($hitRand < $tmpRate) { break; } } var_dump($hitItem); [/sourcecode] |
すみません。。。本来であればarrayの全回しなんてDBであればいらないですが、今回はこんな感じで。
さっきまでのコードに比べ、仕様把握は面倒になりましたが、(パーセントじゃないので直感的じゃない) 運用エラーでhitしないアイテムなどが発生することはなくなりました。
合計が100超えてても全然平気!1/10000の低確率アイテムもカバー可能ですよ!
と、今回はあくまで一例で、提供割合を変えず中身だけ入れ替えたいとか、逆にカードの入れ替えの度全部の確率を入れ替えたいという要件もあるかとおもいます。
(そんな提供割合表示絶対おかしいけど)
今回はこのくらいで。
次回はレイドガチャとか点数ガチャとかおまけ付きガチャとか、1,2,3ガチャとか紹介するとかしないとか。