3

さて、私はしばらくの間これに頭を悩ませてきました、そしてグーグル検索は私を無駄に正しい方向に導くために何かを見つけようとしています。

だから私は次のようなランク付けされたリーダーボード配列を持っています:

[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つの配列を一致させ、配列キーに基づいてポイントを付与します。しかし、私は同点を考慮しているので、同点の報酬ポイントをすべての同点のユーザー間で分割しようとしています。したがって、上記の参照では、2位で同点のプレーヤー2と3は、報酬ポイント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');

リーダーボードは一日の終わりまで絶えず変化する可能性があるので、複雑になりすぎないようにしています。誰かが私を助けてくれると彼らが見た何かを私に指摘できるかどうか、または彼らが実装のアイデアを持っているかどうか疑問に思っています。

私の試みで最も苦労しているのは、リーダーボード配列をループし、「ランク」が同じになることを継続的に楽しみにして、何を合計して分割する必要があるかを知ることです。先読みで行った次の項目で同じテストを実行する代わりに、先の配列をスキップします。混乱している場合は申し訳ありませんが、明らかに混乱しています。

4

2 に答える 2

3

これはおそらくあなたが望むものです:

コード

$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
        )

)
于 2013-03-26T18:39:23.330 に答える
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より8.5ポイントと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
)

各ランクの合計ポイントと各ランクのカウントを単純に割ることで、1人あたりのリワードポイントを獲得できます。

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
于 2013-03-26T20:16:18.067 に答える