PHP奖励指向排行榜并说明关系

时间:2013-03-26 18:31:30

标签: php arrays multidimensional-array leaderboard reward-system

好吧,我已经在这个问题上打了一会儿谷歌搜索试图找到任何可以引导我朝正确方向发展的事情无济于事。

所以我有一个如此排名的排行榜数组:

[1] = array('points' => '99', 'rank' => '1');
[2] = array('points' => '90', 'rank' => '2');
[3] = array('points' => '90', 'rank' => '2');
[4] = array('points' => '80', 'rank' => '4');
[5] = array('points' => '70', 'rank' => '5');
[6] = array('points' => '70', 'rank' => '5');

然后我有一个奖励积分系统,带有一个预定义的数组,根据等级奖励积分:

[1]=10;
[2]=9;
[3]=8;
[4]=7;
[5]=6;
[6]=5;

如果不是为了关系,我只是将两个阵列匹配,并根据数组键奖励积分。但是,因为我允许绑定,所以我试图在所有绑定的用户之间拆分并列奖励积分。因此,上面提到的参赛者2和3将在第2名并列第9和第8分......所以两者都将获得8.5分。

因此,在合并两个数组时,我正在寻找的最终结果是:

[1] = array('points' => '99', 'rank' => '1', 'reward' => '10');
[2] = array('points' => '90', 'rank' => '2', 'reward' => '8.5');
[3] = array('points' => '90', 'rank' => '2', 'reward' => '8.5');
[4] = array('points' => '80', 'rank' => '4', 'reward' => '7');
[5] = array('points' => '70', 'rank' => '5', 'reward' => '5.5');
[6] = array('points' => '70', 'rank' => '5', 'reward' => '5.5');

排行榜可以不断变化,直到一天结束,所以我不想让它变得太复杂。我只是想知道是否有人可以指出我看到的可以帮助我的东西,或者他们是否有任何实施想法。

我在尝试中最努力的部分是循环排行榜阵列并不断期待'等级'是相同的,然后知道我需要总结和拆分,同时也知道我可以跳过前面的阵列,而不是在我前瞻中所经历的下一个项目上执行相同的测试。对不起,如果我很困惑,但我显然很困惑。

2 个答案:

答案 0 :(得分:2)

这可能是你想要的:

<强>代码

$persons = array(
    array('points' => '99', 'rank' => '1'),
    array('points' => '90', 'rank' => '2'),
    array('points' => '90', 'rank' => '2'),
    array('points' => '80', 'rank' => '4'),
    array('points' => '70', 'rank' => '5'),
    array('points' => '70', 'rank' => '5')
);

$ranks = array(
    1 => 10,
    2 => 9,
    3 => 8,
    4 => 7,
    5 => 6,
    6 => 5
);

foreach($persons as $person => $prop) {
    $reward = $ranks[$prop['rank']];

    if (isset($persons[$person+1])) {
        if ($persons[$person+1]['rank'] == $prop['rank']) {
            $reward = $reward - 0.5;
        }
    }

    if (isset($persons[$person-1])) {
        if ($persons[$person-1]['rank'] == $prop['rank']) {
            $reward = $reward - 0.5;
        }
    }

    $persons[$person]['reward'] = $reward;
}

echo '<pre>';
print_r($persons);
echo '<pre>';

这里发生的是您创建奖励密钥并根据$ranks数组中的索引填写此人的排名。这个例子不安全。如果密钥甚至存在于$ranks数组中,您可能需要先检查。

这个例子非常“原始”,可能没有不同的排名,所以你必须自己做最后的测试。

<强>输出

Array
(
    [0] => Array
        (
            [points] => 99
            [rank] => 1
            [reward] => 10
        )

    [1] => Array
        (
            [points] => 90
            [rank] => 2
            [reward] => 8.5
        )

    [2] => Array
        (
            [points] => 90
            [rank] => 2
            [reward] => 8.5
        )

    [3] => Array
        (
            [points] => 80
            [rank] => 4
            [reward] => 7
        )

    [4] => Array
        (
            [points] => 70
            [rank] => 5
            [reward] => 5.5
        )

    [5] => Array
        (
            [points] => 70
            [rank] => 5
            [reward] => 5.5
        )

)

答案 1 :(得分:0)

如果超过2个人可以拥有相同的等级

$persons = array(
    array('points' => '99', 'rank' => '1'),
    array('points' => '90', 'rank' => '2'), // <---
    array('points' => '90', 'rank' => '2'), // <---
    array('points' => '90', 'rank' => '2'), // <---
    array('points' => '70', 'rank' => '5'),
    array('points' => '70', 'rank' => '5')
);

然后这个@Allendar算法会给你错误的结果(对于上面输入的等级为2的人,将给予8.5分8分和8.5分的奖励。)

如果总是有相同数量的人数和定义的排名数量(在这种情况下为6),您可以使用以下内容:

$persons = array(
    array('points' => '99', 'rank' => '1'),
    array('points' => '90', 'rank' => '2'),
    array('points' => '90', 'rank' => '2'),
    array('points' => '90', 'rank' => '2'),
    array('points' => '70', 'rank' => '5'),
    array('points' => '70', 'rank' => '5')
);

$ranks = array(
    1 => 10,
    2 => 9,
    3 => 8,
    4 => 7,
    5 => 6,
    6 => 5
);

$current_ranks = $ranks;
$rank_pool = array();
$rank_counter = array();

$i = 1; // person counter, start with 1 because $ranks start with 1

// distribute reword equally for all ranks
foreach($persons as $person => $prop) {
  if(!isset($ranks[$i])){
    exit("no reword for this much persons [$i]");
  }

  $rank = $prop['rank'];
  if(!isset($rank_pool[$rank])){
    $rank_pool[$rank] = 0;
  }
  $rank_pool[$rank] += $ranks[$i];
  if(!isset($rank_counter[$rank])){
    $rank_counter[$rank] = 0;
  }
  $rank_counter[$rank]++;

  $i++;
}

// set reword according to equally distributed reword
// points for all ranks
foreach($persons as $person => $prop) {
  $rank = $prop['rank'];
  if(!isset($rank_pool[$rank]) || !isset($rank_counter[$rank])){
    exit('something is wrong!');
  }
  $persons[$person]['reword'] = $rank_pool[$rank]/$rank_counter[$rank];
}


echo '<pre>';
print_r($rank_counter);
print_r($rank_pool);
print_r($persons);
echo '<pre>';

如上所述输入你会得到:

$rank_counter=
Array
(
  [1] => 1// --- 1 with rank 1
  [2] => 3// --- 3 with rank 2
  [5] => 2// --- 2 with rank 5
)

$rank_pool
Array
(
  [1] => 10// --- 10 points for persons with rank 1
  [2] => 24// --- 24 points for persons with rank 2
  [5] => 11// --- 11 points for persons with rank 5
)

你可以通过简单划分每个等级的总积分和每个等级的数量来获得每人的重新点数

10/1 = 10 points for each person with rank 1
24/3 = 8 points for each person with rank 2
and
11/2 = 5.5 points for each person with rank 5