Для турнира по настольному футболу у меня есть следующий запрос:
- Есть два типа игроков A (студенты) и B (учителя). (Для простоты мы предполагаем одинаковое количество игроков A и B). например. 16 учеников и 16 учителей.
- Турнир по настольному футболу должен включать как можно больше раундов
- Раунд означает: каждый игрок вместе с товарищем по команде играет против двух других игроков.
- Для каждого раунда игроку нужен товарищ по команде, с которым он никогда раньше не играл. «Новый» игрок.
- Товарищ по команде должен быть другого типа (ученик всегда играет с учителем).
- Каждый игрок из команды противника также должен быть «новым» ( не будь ни предыдущим противником, ни предыдущим товарищем по команде).
Пример: я студент (игрок типа A) и играю с учителем T_John (игрок типа B) в качестве партнера по команде. Мы играем против студента S_Mike и учителя T_James. После окончания игры начинается новый раунд. В этом новом раунде (и во всех последующих раундах) я больше не должен играть с (или против) T_John, T_James или S-Mike, ни как напарник, ни как противник.
Идея состоит в том, чтобы встретить как можно больше новых люди во время турнира, насколько это возможно.
Я создал первый прототип, где у каждого игрока есть список всех игроков, с которыми он никогда не играл (или против) раньше. Теперь для каждой игры я начинаю со списка всех игроков и для каждого игрока выбираю следующего подходящего игрока в качестве партнера по команде и двух противников. Хотя это работает, комбинации очень ограничены. Я не знаю, как получить лучшие и последовательные результаты.
Вот эта основная процедура в классе Player:
for (var i = 0; i < availablePlayers.length; i++) {
var player = availablePlayers[i];
if (player == this || player.hasPlayedWith(this))
continue;
if (!teamMate && player.type != this.type &&
(!opponent1 || !player.hasPlayedWith(opponent1))) {
teamMate = player;
count++;
}
else if (!opponent1 && (!teamMate || !player.hasPlayedWith(teamMate))) {
opponent1 = player;
count++;
}
else if (opponent1 && !opponent2 &&
player.type != opponent1.type &&
!player.hasPlayedWith(opponent1)) {
opponent2 = player;
count++;
}
if (count == 3) {
return [
new Team(this, teamMate),
new Team(opponent1, opponent2)
];
}
}
Вот скрипка со всем прототипом, которая визуализирует игроки, команды, игры и раунды. http://jsfiddle.net/q6e2pymL/
Я почти уверен, что должен быть какой-то шаблон или алгоритм для вычисления наилучших комбинаций. Идеи или предложения?
Любая помощь высоко ценится.