Структура данных для турнира Double Elmination
Я нахожусь в процессе преобразования своего программного обеспечения Tournament Organizer, которое позволяет создавать турниры с двойным выбыванием и управлять ими, чтобы использовать шаблон проектирования MVVM, чтобы его было легче протестировать. При этом я отделяю «модель» от некоторого кода в пользовательском интерфейсе, который напрямую управляет структурой скобок.
Это будет третья версия программного обеспечения, которое я написал для проведения турниров. Первый был написан на PHP и хранил данные в базе данных. Вторая версия - это версия WPF, которую я сделал, и она хранит данные в памяти, а затем сериализует их в файл XML. Однако в обеих версиях есть аспекты реализации, которые, как мне кажется, не чисты и нарушают закон DRY.
Если бы вы создавали структуру данных с нуля для обработки скобок с двойным исключением, как бы вы это сделали?
Обратите внимание, что нет необходимости иметь возможность автоматически генерировать скобки алгоритмически (загрузка из предварительно сделанного двойного исключения с 4/8/16/32 людьми - это то, как я делаю сейчас), просто основной вариант использования определения победителей матчей и «продвижения» их по сетке.
Изменить: чтобы прояснить, структура данных должна обрабатывать турниры с двойным выбыванием, поэтому потенциально победитель одного матча может в конечном итоге конкурировать с проигравшим в другом.
Ответов (4)4
Мое решение состояло в том, чтобы иметь два набора структур данных. Один для кронштейна и один для сидений.
class Match
{
string Id;
MatchSeat red;
MatchSeat blue;
MatchSeat winner;
MatchSeat loser;
}
class MatchSeat
{
string Id;
Entry Entry;
}
А затем, чтобы настроить его, я создал несколько вспомогательных функций, которые взяли информацию о скобках и построили структуры.
{ "1", "seed1", "seed4", "W1", "L1" },
{ "2", "seed2", "seed3", "W2", "L2" },
{ "3", "W1", "W2", "W3", "L3" },
{ "4", "L1", "L2", "W4", "L4" },
{ "5", "W4", "L3", "W5", "L5" },
{ "F", "W3", "W5", "WF", "WF" }
Затем, когда заполняются семена и победители / проигравшие, значение устанавливается только в одном месте.
Итак, в конечном итоге у вас 64 команды. Итак, каким-то образом существует коллекция из 64 команд.
Но они разделены на пары, и в каждой паре есть победитель. И в средних скобках этот победитель фактически вышел из скобки, поэтому я думаю, что ваш объект скобки на самом деле выглядит так:
public class Bracket
{
Team winner; //if this is null or whatever, then we don't have a winner yet
Bracket topBracket;
Bracket bottomBracket;
}
... и когда вы создаете экземпляры своих концов, вы просто оставите две вложенные скобки нулевыми, только с победителем.
Чтобы справиться с двойным выбыванием, есть вторая сетка, которая является сеткой проигравших. Было бы неплохо, если бы вы могли автоматически обрабатывать добавление проигравших в эту сетку (создать сетку, которая начинается с 32, которые уменьшаются до 16, добавляют 16 проигравших из раунда 2 победителя и т. Д.), Но это все реализация. Структуру данных не нужно менять, чтобы приспособиться к этому, вам просто нужно их больше.
Я только что заметил этот вопрос на боковой панели другого вопроса, на котором я был, и подумал, что буду вмешиваться:
Я разрабатываю полнофункциональный Tournament API и открываю его исходный код.
Он еще не создает турниры с двойным выбыванием, но структура данных для турниров с одиночным выбыванием была недавно пересмотрена для поддержки древовидной структуры с двойным выбыванием.