1

我正在尝试计算高尔夫球手在比赛中并列时的获胜顺序。

这些高尔夫比赛使用“stableford”积分系统,您在每洞得分,最高分获胜。与最低分获胜的普通高尔夫“比杆赛”相比(虽然这也有倒计时系统,只计算平局时的最低分......)

规则是使用“倒计时”。即,如果在 9 洞之后比分打成平手,则平局中最好的成绩是最后 8 洞的最好成绩。然后是 7 个孔,等等。

我能想到的最好的是2个数组。

  1. 包含在给定回合中并列的所有玩家的数组。(美元领带)
  2. 一个包含所有 9 个洞的完整得分数据(参考数据库 playerid)。($tie_perhole)

我遍历数组 1,从数组 2 中提取数据并使用以下公式创建一个得分最高的临时数组:

$max = array_keys($array,max($array));

如果 $max 只有 1 个项目,则该玩家是最高得分者。通过第一个数组的循环是“通过引用”的,因此在循环的下一次迭代中,他的 playerid 现在在数组中更长,因此被忽略。这一直持续到第一个数组中只剩下 1 个 playerid。

但是,它只有在每次迭代中单个玩家获胜时才有效。不起作用的情况是,如果玩家子集与任何迭代/倒计时相关。

我认为我的问题是我拥有的当前结构将需要原始 $ties 数组进行拆分,然后以相同的方式继续遍历拆分数组...

举个例子...

$ties 数组如下:

Array 
( 
    [18] => Array 
        ( 
            [0] => 77 
            [1] => 79 
            [2] => 76 
            [3] => 78 
        ) 
)

$tie_perhole(分数数据)数组如下:

Array 
( 
    [18] => Array 
        ( 
            [77] => Array 
                ( 
                    [9] => 18 
                    [8] => 16 
                    [7] => 14 
                    [6] => 12 
                    [5] => 10 
                    [4] => 8 
                    [3] => 6 
                    [2] => 4 
                    [1] => 2 
                ) 
            [79] => Array 
                ( 
                    [9] => 18 
                    [8] => 17 
                    [7] => 15 
                    [6] => 14 
                    [5] => 11 
                    [4] => 9 
                    [3] => 7 
                    [2] => 5 
                    [1] => 3 
                ) 
            [76] => Array 
                ( 
                    [9] => 18 
                    [8] => 16 
                    [7] => 14 
                    [6] => 12 
                    [5] => 10 
                    [4] => 8 
                    [3] => 6 
                    [2] => 4 
                    [1] => 2 
                ) 
            [78] => Array 
                ( 
                    [9] => 18 
                    [8] => 17 
                    [7] => 15 
                    [6] => 13 
                    [5] => 11 
                    [4] => 9 
                    [3] => 7 
                    [2] => 5 
                    [1] => 3 
                ) 
        ) 
) 

所以在本次比赛中,选手的 78 和 79 杆在第 8 洞倒数时得分最高(17 分),所以第 1 和第 2 应该在他们之间。球员 79 应该是第 6 洞倒计时的第一名(14 分,相比 13 分)。第 3 和第 4 名与其余 2 名其他玩家的情况相同。

这里还可能发生其他情况,即在一场比赛中,可能会有许多组(不同数量的)玩家通过排行榜处于不同的平局点。

另请注意,排行榜上会有一些玩家没有并列并保持在当前的绝对位置。

我拥有的工作代码的基础是:

foreach ($ties as $comparekey => &$compareval) {
$tie_loop = 0;
for ($m = 9; $m >= 1; $m--) {
    $compare = array();
    foreach ($compareval as $tie) {
        $compare[$tie] = $tie_perhole[$comparekey][$tie][$m];
    }
    $row = array_keys($compare,max($compare));

    if (count($row) == 1) {
        $indexties = array_search($row[0], $ties[$comparekey]);
        unset($ties[$comparekey][$indexties]);
        // Now update this "winners" finishing position in a sorted array
        // This is a multidimensional array too, with custom function...
        $indexresults = searchForId($row[0], $comp_results_arr);
        $comp_results_arr[$indexresults][position] = $tie_loop;
        $tie_loop++;
    }
    // I think I need conditions here to filter if a subset of players tie
    // Other than count($row) == 1
    // And possibly splitting out into multiple $ties arrays for each thread...

    if (empty($ties[$comparekey])) {
        break;
    }
}
}
usort($comp_results_arr, 'compare_posn_asc');
foreach($comp_results_arr as $row) {
    //echo an HTML table...
}

提前感谢您提供任何有用的见解、提示、想法等...

Robert Cathay 要求提供更多场景。所以这里是另一个...

排行榜实际上有更多的参赛者(玩家 26 的一轮不好......),但我需要帮助的代码只关心排行榜内的关系。

摘要排行榜:

Points  Player
21      48
21      75
20      73
20      1
13      26

此示例生成一个 $tie_perhole 数组:

Array 
( 
    [21] => Array 
        ( 
            [75] => Array 
                ( 
                    [9] => 21 
                    [8] => 19 
                    [7] => 16 
                    [6] => 14 
                    [5] => 12 
                    [4] => 9 
                    [3] => 7 
                    [2] => 5 
                    [1] => 3 
                ) 
            [48] => Array 
            ( 
                [9] => 21 
                [8] => 19 
                [7] => 16 
                [6] => 13 
                [5] => 11 
                [4] => 9 
                [3] => 8 
                [2] => 5 
                [1] => 3 
            ) 
    ) 
[20] => Array 
    ( 
        [73] => Array 
            ( 
                [9] => 20 
                [8] => 18 
                [7] => 16 
                [6] => 13 
                [5] => 11 
                [4] => 8 
                [3] => 6 
                [2] => 5 
                [1] => 3 
            ) 
        [1] => Array 
            ( 
                [9] => 20 
                [8] => 17 
                [7] => 16 
                [6] => 14 
                [5] => 12 
                [4] => 9 
                [3] => 7 
                [2] => 4 
                [1] => 2 
            ) 
    ) 
) 

在此示例中,数组显示球员 75 和 48 获得了 21 分,球员 75 最终将在第 6 洞倒计时中获胜(14 分与 13 分相比),而球员 48 排名第 2。在下一个并列的小组中,73号和1号选手得到20分,73号选手将在第8洞倒计时赢得本组第3名(18分对比17分),选手1获得第4名。玩家 26 则排在第 5 位。

注意,$tie_loop 被添加到另一个数组中以计算第 1 到第 5 名的完成位置,这样就可以了。

希望这足以提供帮助。

4

1 回答 1

1

好吧,所以我根本不懂高尔夫……哈哈哈但是!我想我明白了这个问题的要点,所以这是我的解决方案。

<?php
/**
* Author    : Carlos Alaniz
* Email     : Carlos.glvn1993@gmail.com
* Porpuse   : Stackoverflow example
* Date      : Aug/04/2015
**/


$golfers = [
"A" => [1,5,9,1,1,2,3,4,9],
"B" => [2,6,4,2,4,4,1,9,3],
"C" => [3,4,9,8,1,1,5,1,3],
"D" => [1,5,1,1,1,5,4,5,8]
];

//Iterate over scores.
function get_winners(&$golfers, $hole = 9){
    $positions = array();                               // The score numer is the key!
    foreach ($golfers as $golfer=>$score ) {            // Get key and value
        $score_sub = array_slice($score,0,$hole);       // Get the scores subset, first iteration is always all holes
        $total_score = (string)array_sum($score_sub);   // Get the key 
        if(!isset($positions[$total_score])){
            $positions[$total_score] = array();         // Make array
        }
        $positions[$total_score][] = $golfer;           // Add Golpher to score.
    }
    ksort($positions, SORT_NUMERIC);                    // Sort based on key, low -> high
    return array(end($positions), key($positions));     // The last shall be first
}

//Recursion is Awsome
function getWinner(&$golfers, $hole = 9){
    if ($hole == 0) return;
    $winner = get_winners($golfers,$hole);              // Get all ties, if any.
    if(count($winner[0]) > 1){                          // If theirs ties, filter again!
        $sub_golfers = 
        array_intersect_key($golfers, 
            array_flip($winner[0]));                    // Only the Worthy Shall Pass.
        $winner = getWinner($sub_golfers,$hole - 1);    // And again...
    }
    return $winner;                                     // We got a winner, unless they really tie... 
}

echo "<pre>";
print_R(getWinner($golfers));
echo "</pre>";

好的......现在我解释一下我的方法......因为我们需要知道最高分并且可能是平局,所以将所有这些都保存在单独的数组中对我来说毫无意义,相反我只是颠倒了

高尔夫球手 => 得分Tota_score => 高尔夫球手

这样我们就可以对数组进行按键排序,得到所有得分最高的高尔夫球手。

现在 total_score 是孔分数数组子集的总和。所以......这个函数第一次运行时,它将添加所有 9 个洞,在这种情况下,有 3 个高尔夫球手最终得到相同的分数。

Array
(
    [0] => Array
        (
            [0] => A
            [1] => B
            [2] => C
        )

    [1] => 35
)

由于高尔夫球手的总数不是 1 并且我们还在第 9 洞,我们再次运行这个,但这次只针对这 3 名高尔夫球手和当前洞 - 1,所以我们这次只加到第 8 洞.

Array
(
    [0] => Array
        (
            [0] => B
            [1] => C
        )

    [1] => 32
)

我们又打了一个平局……这个过程将一直持续到我们到达最后一个洞或获胜者。

Array
(
    [0] => Array
        (
            [0] => C
        )

    [1] => 31
)

编辑

<?php
/**
* Author    : Carlos Alaniz
* Email     : Carlos.glvn1993@gmail.com
* Porpuse   : Stackoverflow example
**/


$golfers = [
"77" => [2,4,6,8,10,12,14,16,18],
"79" => [3,5,7,9,11,14,15,17,18],
"76" => [2,4,6,8,10,12,14,16,18],
"78" => [3,5,7,9,11,13,15,17,18]
];

//Iterate over scores.
function get_winners(&$golfers, $hole = 9){
    $positions = array();                               // The score numer is the key!
    foreach ($golfers as $golfer => $score) {            // Get key and value
        //$score_sub = array_slice($score,0,$hole);     // Get the scores subset, first iteration is always all holes
        $total_score = (string)$score[$hole-1];         // Get the key 
        if(!isset($positions[$total_score])){
            $positions[$total_score] = array();         // Make array
        }
        $positions[$total_score][] = $golfer;           // Add Golpher to score.
    }
    ksort($positions, SORT_NUMERIC);                    // Sort based on key, low -> high
    return [
            "winner"=> end($positions),
            "score" => key($positions),
            "tiebreaker_hole"  => [
                "hole"=>$hole,
                "score"=> key($positions)],
            ];                                          // The last shall be first
}

//Recursion is Awsome
function getWinner(&$golfers, $hole = 9){
    if ($hole == 0) return;
    $highest = get_winners($golfers,$hole);             // Get all ties, if any.
    $winner = $highest;
    if(count($winner["winner"]) > 1){                   // If theirs ties, filter again!
        $sub_golfers = 
        array_intersect_key($golfers, 
            array_flip($winner["winner"]));             // Only the Worthy Shall Pass.
        $winner = getWinner($sub_golfers,$hole - 1);    // And again...
    }
    $winner["score"] = $highest["score"];
    return $winner;                                     // We got a winner, unless they really tie... 
}

echo "<pre>";
print_R(getWinner($golfers));
echo "</pre>";

结果:

Array
(
    [winner] => Array
        (
            [0] => 79
        )

    [score] => 18
    [tiebreaker_hole] => Array
        (
            [hole] => 6
            [score] => 14
        )

)
于 2015-08-04T19:50:47.203 回答