Search code examples
phpalgorithmround-robin

PHP - Round Robin and 3rd person (2 players and one writer / refugee)


I have the following code

poule = ['Jason', 'Raymond', 'Rupert', 'Mike', 'Simon', 'Jeremy'];

$games = [];
$cnt_players = count($poule);
$players = $poule;

if ($cnt_players % 2 != 0)
{
    array_push($players, ['name' => 'bye', 'uid' => FALSE, 'alias' => NumToChar($cnt_players + 1), TRUE]);
    $cnt_players++;
}

$away = array_splice($players, $cnt_players / 2);
$home = $players;

$write = [];

for ($i = 0; $i < count($home) + count($away) - 1; $i++)
{
    for ($j = 0; $j < count($home); $j++)
    {
        //Get the writer
        $writer = $this->GetWriter($home, $away, $j, $i);

        //Remove the dummy games (where one player is bye)
        if ($home[$j]['name'] !== 'bye' && $away[$j]['name'] !== 'bye')
        {
            $games[] = [['uid' => $home[$j]['uid'], 'name' => $home[$j]['name'], 'alias' => $home[$j]['alias']], ['uid' => $away[$j]['uid'], 'name' => $away[$j]['name'], 'alias' => $away[$j]['alias']], $writer];
        }   

        //echo 'I:' . $i . ' - J: ' . $j . ' - ' . $home[$j]['alias'] . ' : ' . $home[$j]['name'] . '  -  ' . $away[$j]['alias'] . ' : ' . $away[$j]['name'] . '  ==>  ' . $writer['alias'] . ' : ' . $writer['name'] . "\n\r";

        $write[$writer['name']][] = $writer['name'];
    }

    if (count($home) + count($away) - 1 > 2)
    {
        array_unshift($away, current(array_splice($home, 1, 1)));
        array_push($home, array_pop($away));
    }
}

//print_r($write);

return $games;

-- The function GetWriter should give us the player who will note the scores for that particulair game.

private function GetWriter($home, $away, $j, $i)
        {
            if ($j > 0)
            {
                if ($j == 1)
                {
                    $writer = (isset($home[$j + 1]['alias']) ? $home[$j + 1] : $home[$j + 1]);
                }
                else
                {
                    $writer = (isset($home[$j - 1]['alias']) ? $home[$j - 1] : $home[$j + 1]);
                }

                //Check if writer is a bye, this is not possible
                if ($writer['name'] == 'bye')
                {
                    $writer = (isset($away[$j - 2]['alias']) ? $away[$j - 2] : $home[$j - 1]);
                }
            }
            else
            {
                $writer = (isset($home[$j + 1]['alias']) ? $home[$j + 1] : $away[$j]);

                if ($writer['name'] == 'bye')
                {
                    $writer = (isset($away[$j + 1]['alias']) ? $away[$j + 1] : $home[$j]);
                }
            }

            return $writer;
        }

Above code gives me all games with each player playing once to another player (round robin). However I need to find a third player who will be the writer / refugee. Like in Darts, 1 player is the person who writes the scores on the scoreboard. I do get a writer, but it isn't nicely divided per player. Is there an formula to get the correct player who is writer / refugee ?

Some examples

Jason vs Mike Raymond Raymond vs Simon Rupert Rupert vs Jeremy Mike etc

So Jason plays against Mike and Raymond notes the scores. Raymond plays against Simon and Rupert notes the scores etc etc

My GetWriter returns writes, but not well divided. Eg: Player Jason writes never and Raymond writes the most scores.


Solution

  • I have the following solution which works well. Because player A and player B always start, we set the key as default index 3. Now we loop with GetCounter though all players and get the writer / refugee which is first available.

    $games = [];
    $cnt_players = count($poule);
    $players = $poule;
    $key = 3;
    
    if ($cnt_players % 2 != 0)
    {
        array_push($players, ['name' => 'bye', 'uid' => FALSE, 'alias' => NumToChar($cnt_players + 1, TRUE), TRUE]);
        $cnt_players++;
    }
    
    $away = array_splice($players, $cnt_players / 2);
    $home = $players;
    
    for ($i = 0; $i < count($home) + count($away) - 1; $i++)
    {
        for ($j = 0; $j < count($home); $j++)
        {
            //Remove the dummy games (where one player is bye)
            if ($home[$j]['name'] != 'bye' && $away[$j]['name'] != 'bye')
            {
                //Get the writer
                $writer = $this->GetCounter($home, $away, $j, $poule, $key);
    
                $games[] = [['uid' => $home[$j]['uid'], 'name' => $home[$j]['name'], 'alias' => $home[$j]['alias']], ['uid' => $away[$j]['uid'], 'name' => $away[$j]['name'], 'alias' => $away[$j]['alias']], $writer['array']];
                $key = $writer['key'];
            }
            $key++;
        }
    
        if (count($home) + count($away) - 1 > 2)
        {
            array_unshift($away, current(array_splice($home, 1, 1)));
            array_push($home, array_pop($away));
        }
    }
    
    
    return $games;
    

    And the GetCounter

    private function GetCounter($home, $away, $j, $writers, $key)
    {
        if (isset($writers[$key]['alias']))
        {
            $writer['array'] = $writers[$key];
            $writer['key'] = $key;
    
            if ($home[$j]['alias'] == $writer['array']['alias'] || $away[$j]['alias'] == $writer['array']['alias'])
            {
                $key++;
                return $this->GetCounter($home, $away, $j, $writers, $key);
            }
        }
        else {
            $key = 0;
            return $this->GetCounter($home, $away, $j, $writers, $key);
        }
    
        return $writer;
    }