Created
January 27, 2022 04:52
-
-
Save MrStonedOne/838d551036af7aae63499962e1633be4 to your computer and use it in GitHub Desktop.
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
<?php | |
//Record the votes: | |
$votes = array(); //array of ckeys assoicated to an array of dicts with vote metadata for each pick the player picked | |
$candidates = array(); //array of dicts | |
//grab each vote from the db | |
while ($row = $res->fetch_assoc()) { | |
$vote = array(); | |
$ckey = $row['ckey']; | |
$cid = $row['optionid']; | |
$cname = $row['text']; | |
$vid = $row['id']; //saved because the voteid is used to determine their ranked choice ordering | |
//is this the first vote we've seen for a given candidate? | |
if (!isset($candidates[$cid])) { | |
//set up their metadata array for use later | |
$candidates[$cid] = array(); | |
$candidates[$cid]['CANDIDATE'] = $cname; | |
$candidates[$cid]['CANDIDATE_ID'] = $cid; | |
$candidates[$cid]['VOTES'] = 0; | |
$candidates[$cid]['VALUE'] = 0; | |
$candidates[$cid]['VALUE_STR'] = ''; | |
} | |
//is this the first vote we've processed for this ckey? | |
if (!isset($votes[$ckey])) | |
$votes[$ckey] = array(); | |
$vote['CID'] = $cid; | |
$vote['ID'] = $vid; | |
$votes[$ckey][$cid] = $vote; | |
} | |
$res->free(); | |
//This function will handle sorting candidates by their first picks. | |
$candidatecmp = function ($a, $b) { | |
global $totalsort, $reversesort; | |
if ($reversesort) { | |
$aa = $a; | |
$a = $b; | |
$b = $aa; | |
} | |
if ($totalsort) | |
return $b['VALUE'] - $a['VALUE']; | |
if ($b['VOTES'] == $a['VOTES']) { | |
if ($b['VALUE'] == $a['VALUE']) | |
return 0; | |
$val = $b['VALUE'] - $a['VALUE']; | |
while ($val < 1 && $val > -1) | |
$val *= 10; | |
return $val; | |
} | |
return $b['VOTES'] - $a['VOTES']; | |
}; | |
//this function handles making sure a user's votes are sorted by their ranked choice | |
$votecmp = function ($a, $b) { | |
return $a['ID'] - $b['ID'] ; | |
}; | |
//tie breaker record keeping | |
$initalvalue = count($candidates); | |
//first round special prep code: loop thru each user who voted | |
foreach ($votes as &$vote) { | |
//sort their picks to match how the user sorted them when voting | |
if (!uasort($vote, $votecmp)) | |
die ('Error sorting votes'); | |
//record their top pick on the candidate's array. | |
$candidates[array_keys($vote)[0]]['VOTES']++; | |
//tie breaker record keeping | |
$value = $initalvalue; | |
foreach ($vote as $pick => $array) { | |
$candidates[$pick]['VALUE'] += $value; | |
if ($lineartotal) | |
$value -= 1; | |
else | |
$value /= 2; | |
} | |
} | |
//sort candidates by the number of top picks they got. | |
if (!uasort($candidates, $candidatecmp)) | |
die ('Error sorting canidate list'); | |
//round the tie breaker metric into a new datafield for displaying to the user. | |
foreach ($candidates as &$candidate) { | |
$candidate['VALUE_STR'] = round($candidate['VALUE']); | |
} | |
$roundcount = 0; | |
$rounds = array(); | |
//set up the first "round". | |
$round = array(); | |
$round['ROUND_NUMBER'] = ++$roundcount; | |
$round['IPV_ROUND_RES'] = $candidates; | |
$rounds[] = $round; | |
if ($finalize) //save it to the database if told to do so. | |
submit_finalized_round($candidates, $finalize_token, $id, $roundcount); | |
//kill off the bottom candidate and re-sort as long as there are mutiple candidates. | |
while (count($candidates) > 1) { | |
$round = array(); | |
$round['ROUND_NUMBER'] = ++$roundcount; | |
//grab the bottom candidate | |
$loser = array_keys($candidates)[count($candidates)-1]; | |
//reset the 'votes gained this round' metric from what it was to 0 | |
foreach($candidates as &$candidate) { | |
$candidate['DIFF'] = 0; | |
} | |
//go thru each player and see if their top pick is the loser. | |
foreach ($votes as &$vote) { | |
if (array_keys($vote)[0] == $loser) { | |
unset($vote[$loser]); //remove their vote for the loser. | |
$candidates[array_keys($vote)[0]]['VOTES']++; //look at who the new top pick is, and add one to that candidate's top pick count. | |
$candidates[array_keys($vote)[0]]['DIFF']++; //also add one to said candidate's 'votes gain this round' metric | |
} else { //they picked somebody else, but we still got to remove the loser from their priority list. | |
unset($vote[$loser]); | |
} | |
} | |
//delete the loser. | |
unset($candidates[$loser]); | |
//resort the candidate by number of top picks. | |
if (!uasort($candidates, $candidatecmp)) | |
die ('Error sorting candidate list'); | |
//save the the new sorted candidate list to the round. | |
$round['IPV_ROUND_RES'] = $candidates; | |
//save this round to the list of rounds. | |
$rounds[] = $round; | |
if ($finalize) //save this round to the database if requested to do so. | |
submit_finalized_round($candidates, $finalize_token, $id, $roundcount); | |
} | |
//make the rounds list available to the html engine. | |
$tpl->setvar('IPV_ROUNDS', $rounds); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment