Skip to content

Instantly share code, notes, and snippets.

@okumurakengo
Last active August 4, 2024 09:36
Show Gist options
  • Select an option

  • Save okumurakengo/76e43c3096bb573ff638eecb52df4dec to your computer and use it in GitHub Desktop.

Select an option

Save okumurakengo/76e43c3096bb573ff638eecb52df4dec to your computer and use it in GitHub Desktop.
ガチャのマスタから重みを考慮して抽選する
CREATE TABLE gacha_items (
id INT AUTO_INCREMENT PRIMARY KEY,
item_name VARCHAR(255) NOT NULL,
weight INT NOT NULL,
UNIQUE (item_name)
);
INSERT INTO gacha_items (item_name, weight) VALUES
('レアアイテムA', 10000),
('レアアイテムB', 15000),
('レアアイテムC', 12000),
('レアアイテムD', 20000),
('レアアイテムE', 18000),
('レアアイテムF', 16000),
('レアアイテムG', 13000),
('レアアイテムH', 17000),
('レアアイテムI', 11000),
('レアアイテムJ', 14000);
<?php
declare(strict_types=1);
require __DIR__ . '/sample/path/vendor/autoload.php';
use App\DB\DBAccess;
$db = DBAccess::singleton();
$gachaItems = $db->select('gacha_items');
$item = draw($gachaItems, 'weight');
var_dump($item);
/**
* ガチャアイテムから重みに基づいてランダムにアイテムを選択します。
*
* @param array $items アイテムの配列。各アイテムは連想配列であり、少なくとも `weightkeyName` キーを含む必要があります。
* @param string $weightkeyName アイテムの重みを示すキー名。
* @return array 選択されたアイテム
*/
function draw(array $items, string $weightKeyName) {
// 重みの合計
$totalWeight = array_sum(array_column($items, $weightKeyName));
$random = mt_rand(1, $totalWeight);
$cumulativeWeight = 0;
foreach ($items as $item) {
$cumulativeWeight += $item[$weightKeyName];
if ($random <= $cumulativeWeight) {
return $item;
}
}
// どのアイテムにもマッチしない場合(理論的にはありえない)
throw new Exception('ロジックが間違っている可能性');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment