infocyph / game-draw
Generates Item and Item count for winners.
3.1
2024-11-08 08:59 UTC
Requires
- php: >=8.0
- ext-bcmath: *
Requires (Dev)
- captainhook/captainhook: ^5.23
- laravel/pint: ^1.18
- pestphp/pest: ^3.5
- rector/rector: ^1.2
- symfony/var-dumper: ^7.1
README
Unified draw engine with one request contract and one response contract for every draw method.
Requirements
- PHP 8.4+
- BCMath extension
Install
composer require infocyph/game-draw
Unified API
Use Infocyph\Draw\Draw as the only public draw entrypoint.
Request shape
[
'method' => '...', // required
'items' => [...], // required
'candidates' => [...], // required for grand + campaign.*
'sourceFile' => '...', // optional alternative for grand
'options' => [...], // optional
]
Response shape
[
'method' => '...',
'entries' => [
[
'itemId' => ?string,
'candidateId' => ?string,
'value' => mixed,
'meta' => array
]
],
'raw' => mixed,
'meta' => [
'mode' => 'single|multi',
'requestedCount' => int,
'returnedCount' => int
]
]
Single-pick and multi-pick methods both return entries[].
Supported methods
luckygrandprobabilityeliminationweightedEliminationroundRobincumulativebatchedtimeBasedweightedBatchsequentialrangeWeightedcampaign.runcampaign.batchcampaign.simulate
Examples
use Infocyph\Draw\Draw; $draw = new Draw();
lucky
$result = $draw->execute([ 'method' => 'lucky', 'items' => [ ['item' => 'gift_a', 'chances' => 10, 'amounts' => [1]], ['item' => 'gift_b', 'chances' => 20, 'amounts' => [2]], ], 'options' => ['count' => 2], ]);
grand
$result = $draw->execute([ 'method' => 'grand', 'items' => ['gift_a' => 5, 'gift_b' => 2], 'candidates' => ['u1', 'u2', 'u3', 'u4'], 'options' => ['retryCount' => 50], ]);
probability
$result = $draw->execute([ 'method' => 'probability', 'items' => [ ['name' => 'item1', 'weight' => 0.2], ['name' => 'item2', 'weight' => 0.8], ], 'options' => ['count' => 3], ]);
elimination
$result = $draw->execute([ 'method' => 'elimination', 'items' => [ ['name' => 'item1'], ['name' => 'item2'], ], 'options' => ['count' => 2], ]);
weightedElimination
$result = $draw->execute([ 'method' => 'weightedElimination', 'items' => [ ['name' => 'item1', 'weight' => 10], ['name' => 'item2', 'weight' => 20], ], 'options' => ['count' => 2], ]);
roundRobin
$result = $draw->execute([ 'method' => 'roundRobin', 'items' => [ ['name' => 'item1'], ['name' => 'item2'], ], 'options' => ['count' => 3], ]);
cumulative
$result = $draw->execute([ 'method' => 'cumulative', 'items' => [ ['name' => 'item1'], ['name' => 'item2'], ], 'options' => ['count' => 3], ]);
batched
$result = $draw->execute([ 'method' => 'batched', 'items' => [ ['name' => 'item1'], ['name' => 'item2'], ['name' => 'item3'], ], 'options' => ['count' => 2, 'withReplacement' => false], ]);
timeBased
$result = $draw->execute([ 'method' => 'timeBased', 'items' => [ ['name' => 'item1', 'weight' => 10, 'time' => 'daily'], ['name' => 'item2', 'weight' => 20, 'time' => 'weekly'], ], 'options' => ['count' => 2], ]);
weightedBatch
$result = $draw->execute([ 'method' => 'weightedBatch', 'items' => [ ['name' => 'item1', 'weight' => 10], ['name' => 'item2', 'weight' => 20], ], 'options' => ['count' => 3], ]);
sequential
$result = $draw->execute([ 'method' => 'sequential', 'items' => [ ['name' => 'item1'], ['name' => 'item2'], ], 'options' => ['count' => 3], ]);
rangeWeighted
$result = $draw->execute([ 'method' => 'rangeWeighted', 'items' => [ ['name' => 'item1', 'min' => 1, 'max' => 50, 'weight' => 10], ['name' => 'item2', 'min' => 5, 'max' => 25, 'weight' => 15], ], 'options' => ['count' => 2], ]);
campaign.run
$result = $draw->execute([ 'method' => 'campaign.run', 'items' => [ 'gold' => ['count' => 1, 'group' => 'premium'], 'silver' => ['count' => 2, 'group' => 'basic'], ], 'candidates' => ['u1', 'u2', 'u3', 'u4'], 'options' => [ 'rules' => [ 'perUserCap' => 1, 'perItemCap' => ['gold' => 1], 'groupQuota' => ['premium' => 1, 'basic' => 2], ], 'retryLimit' => 100, 'withExplain' => true, ], ]);
campaign.batch
$result = $draw->execute([ 'method' => 'campaign.batch', 'items' => ['bootstrap' => ['count' => 1]], 'candidates' => ['u1', 'u2', 'u3', 'u4'], 'options' => [ 'rules' => ['perUserCap' => 1], 'phases' => [ ['name' => 'phase_1', 'items' => ['item_a' => ['count' => 2]]], ['name' => 'phase_2', 'items' => ['item_b' => ['count' => 2]]], ], 'retryLimit' => 100, ], ]);
campaign.simulate
$result = $draw->execute([ 'method' => 'campaign.simulate', 'items' => ['gold' => ['count' => 1], 'silver' => ['count' => 2]], 'candidates' => ['u1', 'u2', 'u3', 'u4'], 'options' => ['iterations' => 1000, 'retryLimit' => 100], ]);