Предполагая, что у вас есть шестнадцатеричная карта n
ячеек и p
игроков, где p <= n
лучший способ справиться с этим - через круговое распределение через клеточные автоматы (CA).
Инициализация
Случайным образом (и / или с использованием той или иной эвристики, такой как расстояние от центра карты), выберите начальную ячейку для каждого игрока. Так как p <= n
, это не должно быть проблемой.
Сотовые автоматы
Вам требуется полная связь между вашими шестнадцатеричными ячейками. Я бы предложил 6-соседний массив на ячейку:
class Cell
{
//... other members...
Cell[6] neighbours = new Cell[6];
}
Использование массивов фиксированного размера позволяет существовать концепции топографических направлений между ячейками, чего нет в списке или векторе. Я рекомендую это, поскольку это может упростить некоторые операции навигации.
Вы также можете сохранить свою шестнадцатеричную карту в двумерном массиве со смещением на строку. Однако это может быть немного менее интуитивно понятно, чем сохранение соседнего массива на ячейку, только из-за геометрического смещения в каждой другой строке.
Убедитесь, что каждая ячейка связана со всем, что является соседом. Вы можете делать это строка за строкой, ячейка за ячейкой, генерируя полную шестнадцатеричную карту. PS Если вы в конечном итоге захотите не прямоугольную ограниченную шестнадцатеричную карту, вы можете просто удалить отдельные ячейки и ссылки на эти ячейки, чтобы сформировать отрицательные пространства, что позволит вам создать органический контур карты.
Распределение по кругу
псевдокод:
count number of neutral cells in entire map, minus those starting cells taken by players
while neutral cells remain (or while true)
for each player
if player has not yet reached expected territory size in cells
for each cell already constituting this player's territory
if territory can grow by one cell into a neutral neighbour
grow into neighbour
reduce neutral cell count for entire map by one
if no more neutral cells remain in map
break out of outermost while loop immediately
else
continue to next player immediately
begin game
Этот алгоритм даст каждому игроку возможность увеличить свою территорию на единицу, в виде круговой схемы, при условии, что на территории игрока все еще есть действительное пространство для роста. Если определенные игроки заблокированы от дальнейшего роста, алгоритм, несмотря на это, продолжит увеличивать территории игроков, у которых все еще есть действительное место для роста. Вы можете легко ограничить каждого игрока одним и тем же количеством ячеек, как только одна из них достигнет предела, но это должно быть достаточно легко для вас, если хотите.
Это обеспечит максимальные размеры «домашних территорий» для каждого игрока. Если вы хотите иметь «островные» территории дополнительно, чтобы выполнить квоту подсчета клеток для этого игрока, то, когда игроку не хватает локального пространства для роста, вы можете выбрать новую начальную ячейку из списка нейтральных ячеек и продолжить тот же процесс "роста", оттуда. Таким образом, вы получите в конечном итоге красивые, согласованные наборы островов для каждого игрока, а не случайный шум.