Created
August 16, 2012 07:28
-
-
Save ModernTimes/3368046 to your computer and use it in GitHub Desktop.
Lottery: simulates unfair/weighted die rolls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Beware: Returns a winner even if the collective drop chance is below 100%. | |
* If that behavior is undesired, add some logic in getWinner to prevent it. | |
*/ | |
class Lottery { | |
/** | |
* list of entries in the lottery. Elements are of the form | |
* array('participant' => (mixed), | |
* 'lots' => (float)), | |
*/ | |
private $_entries = array(); | |
/** | |
* total number of lots in the pool | |
* Lots can come in decimals as well, like 0.02 | |
* @var float | |
*/ | |
private $_lotsTotal = 0; | |
/** | |
* Adds a new entry to the lottery, | |
* i.e. a participant with a given number of lots | |
* @param mixed $participant | |
* @param float $lots | |
*/ | |
public function addEntry($participant, $lots = 1) { | |
$this->_entries[] = array( | |
'participant' => $participant, | |
'lots' => $lots, | |
); | |
$this->_lotsTotal += $lots; | |
} | |
/** | |
* Determines the winner of the lottery based on the number of lots that | |
* each participant has. Lots and their owners are all lined up, then | |
* the RNG determines the position of the winning lot. | |
* @return mixed | |
*/ | |
public function getWinner() { | |
if($this->_lotsTotal == 0) { return false; } | |
// * 1,000,000, to make sure that lots in decimal form are handled correctly | |
$rand = mt_rand(0, $this->_lotsTotal * 1000000); | |
$currentLot = 0; | |
foreach($this->_entries as as $entry) { | |
$currentLot += $entry['lots'] * 1000000; | |
if($currentLot >= $rand) { | |
return $entry['participant']; | |
} | |
} | |
return false; // should never happen | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment