1

I am creating a game which marks the top 2 highest "scores" from each game as winners.

If two of the scores are the same, there will have to be a tiebreaker (unless the two matching scores are first and second place).

How can I (efficiently) make a function which returns these results for the following possibilities:

Possible game results for 6 different games:

$a = array(20,19,18,17,16,15); // no tie breaker needed - [1], [2] win
$b = array(20,20,18,17,16,15); // no tie breaker needed - [1], [2] win
$c = array(20,19,19,17,16,15); // tie breaker needed for [2], [3] values
$d = array(20,20,20,17,16,15); // tie breaker needed for [1], [2], [3] values
$e = array(20,19,19,19,16,15); // tie breaker needed for [2], [3], [4] values
$f = array(20,20,20,20,20,20); // tie breaker needed for all values

EDIT: THE SOLUTION:

<?php
$score = array("green"=>10, "pink"=>10, "orange"=>9, "blue"=>8, "yellow"=>7);
$count = 0;

foreach ($score as $value) {

    $count++;

    // if the count is 2
    if ($count === 2) {

        // save the value as a variable
        $second = $value;

    // if the count is 3
    } else if ($count === 3) {

        // if 2nd place and 3rd place have the same score - tiebreaker
        if ($second === $value) {

            // add matches to array for tiebreaker
            $result = array_keys($score, $value);

        // if 2nd place and 3rd place have different scores - no tiebreaker
        } else {

            // split first 2 places from the array
            $result = array_slice($score, 0, 2);                

        }

    }

}
?>
user2217162
  • 897
  • 1
  • 9
  • 20
  • 2
    I've noticed in many games, if there is a tie then the place is given to the last player to get points. – jonhopkins Jul 29 '13 at 14:37
  • As another consideration, if there's a three-way tie for first place, then would it be a three-way tiebreaker with one winner, then a two-way tiebreaker with one winner? Or would it be a three-way tiebreaker with two winners? – Chris Forrence Jul 29 '13 at 14:37
  • @ChrisForrence - three way tiebreaker with two winners. – user2217162 Jul 29 '13 at 14:38
  • Possible duplicate: http://stackoverflow.com/questions/1170807/how-to-detect-duplicate-values-in-php-array – diegoperini Jul 29 '13 at 14:39
  • @diegoperini While there's probably some relevant info that can be gleaned from that question, I'd say the two questions are different enough not to be considered duplicates – StephenTG Jul 29 '13 at 14:40
  • [array_intersect()](http://www.php.net/manual/en/function.array-intersect.php) will probably help you out to determine if there is a tie. I would create two checks, one to check for a win/loss and one to check for a tie. – Mattiavelli Jul 29 '13 at 14:40
  • To make it fair, additional information would have to be sent to form a basis for a tiebreaker. For example, a timestamp for jonhopkins scenario. If the score is the same, then compare the last time that the player earned points. – Chris Forrence Jul 29 '13 at 14:41
  • @StephenTG not duplicate questions but answers probably. :) – diegoperini Jul 29 '13 at 14:44
  • You should actually probably post your solution as an answer, not just as part of the question. SO is fine with people answering their own questions when the need arises. – StephenTG Jul 29 '13 at 18:00

1 Answers1

3

My guess is that you have more than scores as part of the objects you're ranking (otherwise, does it matter "which" raw score is first?). In the comparator you're using to compare the results, you can take in to consideration any of the additional data. So, if your object really looks like this (JSON object format, not PHP. Forgive):

{
"name":"frank",
"score":20,
"class":"wizard",
"level":44
}

You can decide to use the alpha name, or the level, or place "wizard" classes higher than others when you sort object arrays using the usort() PHP routine. Just provide a function which implements those rules, whatever they might be. This answer has an example.

UPDATE: OP wants to detect ties

You can iterate through the list to detect sets where there are score ties. In psuedocode:

for each item in scorelist:
    // create hash of score->list of items
    scoreRef[item.score].append(item)

// scoreRef is a hash of scores => list of 
// items that share that score.

for each item in scoreRef:
    // item is an array
    if item.size > 1:
        tiebreakerList.append( item);

// tiebreakerList is a list of lists where 
// the subordinate list items all share the same 
// number of points
Community
  • 1
  • 1
PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56
  • I actually *want* to check for ties because there will be a separate tiebreaker game when two of the scores are tied and there arent two clear winners. – user2217162 Jul 29 '13 at 14:49
  • Instead, then iterate through the sorted list, to find pairs/sets where there are ties and add the pairs/sets to the tiebreaker game list. – PaulProgrammer Jul 29 '13 at 14:50