Я реализовал циклический генератор на PHP для создания приспособлений между пользователями в лиге. Это сопоставляет всех пользователей в лиге и сталкивает их друг с другом каждую игровую неделю.
Код выглядит так;
/**
* Rotates an array for the round robin algorithm
*/
function round_robin_array($array)
{
// we always keep index 0
$top = array_shift($array);
$last = array_pop($array);
$rotate = [$last];
foreach ($array as $_value) {
$rotate[] = $_value;
}
array_unshift($rotate, $top);
return $rotate;
}
/**
* Runs a round robin to make a schedule.
*/
function round_robin($users, $weeks)
{
$schedule = [];
$count = count($users);
foreach ($users as $_u) {
$schedule[$_u] = array_fill(0, $weeks, []);
}
for ($i=0;$i<$weeks;$i++) {
for ($a=0;$a<($count / 2) + 1;$a++) {
$vs = $users[$a];
$opp = $users[($count - $a) - 1];
$at = rand(0,4);
$pg = [$opp, $at];
$og = [$vs, $at];
$schedule[$vs][$i] = $pg;
$schedule[$opp][$i] = $og;
}
$users = $this->round_robin_array($users);
}
return $schedule;
}
public function generateFixtures($league, $users, $weeks)
{
$array = [];
foreach($users as $user) {
array_push($array, $user['id']);
}
if(count($array) % 2 != 0) {
array_push($array, '0');
}
$fixtures = $this->round_robin($array, $weeks);
$gameweek = 1;
foreach($fixtures as $key => $val) {
if($key != 0) {
foreach($val as $opponent) {
LeagueFixture::firstOrCreate([
'gameweek' => $gameweek,
'league_id' => $league,
'user_id' => $key,
'opponent_id' => $opponent[0],
]);
$gameweek = $gameweek+1;
}
}
$gameweek = 1;
}
return $fixtures;
}
В функцию generateFixtures передаются пользователи лиги, сама лига и количество недель.
Проблема в том, что это создает «дубликаты» для каждого прибора, поскольку, по сути, у каждого пользователя есть представление - например;
Игровая неделя 1
- Пользователь_1 VS Пользователь_2
- Пользователь_3 VS Пользователь_4
- Пользователь_2 VS Пользователь_1
- Пользователь_4 VS Пользователь_3
Как видите, последние два фикстура там разные; но то же самое!
Мой вопрос заключается в том, является ли это проблемой циклического перебора или я могу/должен отфильтровывать эти дубликаты при их извлечении в контроллере/представлении.