Skip to content

chegoryu/auralux

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Auralux

Основная часть для запуска игр турнира по Auralux для ЛОШ.

Визуализатор в отдельном репозитории.

Правила

Описание игры

Карта игры

На плоскости расположены n <= 20 планет пронумерованных от 1 до n.

Расстояния между каждой парой планет вычислены и округлены до ближайшего целого, гарантируется, что все полученные расстояния больше нуля и не превышают 100).

Игроку дается таблица dist[i][j] из целых чисел, где dist[i][j] - расстояние между планетами i и j (1 <= i, j <= n, dist[k][k] = 0 для 1 <= k <= n).

Ходы игроков и процесс игры

Игроки делают ходы по очереди - игрок 1, игрок 2, …, игрок m.

В начале игры у каждого игрока есть одна планета уровня 1 на которой находится StartShipsCount = 100 кораблей.

На своем ходу игрок может отправить группу кораблей из любой планеты где у него есть корабли на любую другую. Если расстояния между планетами равно x корабли прилетят ровно перед x следующим ходом этого игрока. Например, если расстояние между планетами равно 1, то корабли прилетят сразу перед следующим ходом этого игрока.

Можно отправлять группы кораблей с разных планет и с одной планеты на разные в рамках одного хода.

Действует ограничение - в полете должно быть не более MaxShipGroupsInSpace = 1000 различных групп кораблей одного игрока. Если в полете находится MaxShipGroupsInSpace групп кораблей одного игрока, а он отправит еще одну группу, то эта группа немедленно погибает из-за проблем с навигацией.

Игрок может захватить нейтральную планету нулевого уровня если на ней находится хотя бы ShipsToCapturePlanet = 100 кораблей игрока. При этом действии все ShipsToCapturePlanet разрушаются. Это действие происходит мгновенно в тот ход игрока, когда он решил совершить это действие.

Если состояние защиты планеты не равно максимуму для своего уровня, то игрок может чинить защиту. Для починки защиты на один пункт надо потратить один корабль. Это действие происходит мгновенно в тот ход игрока, когда он решил совершить это действие.

Игрок может улучшить планету 1 или 2 уровня если на ней находится хотя бы ShipsToUpgradePlanet[level] (100, 200) кораблей игрока и состояние защиты равно максимуму для своего уровня. При этом действии все ShipsToUpgradePlanet[level] разрушаются. Это действие происходит мгновенно в тот ход игрока, когда он решил совершить это действие.

Игрок может одновременно починить защиту планеты и улучшить её.

Улучшать планету более чем на один уровень за ход запрещено. Улучшать планету после захвата запрещено.

Если за один ход попробовать совершить больше MaxPlayerShipMovesPerStep = 1000 действий, игрок будет немедленно дисквалифицирован. Во всех остальных случаях невалидные ходы (например игроку не хватает кораблей на планете чтобы их отправить или на планете с которой игрок хочет отправить корабли ему не принадлежит) игнорируются.

Если игра закончилась и у неё есть победитель, то он получает 1 балл независимо от количества кораблей и захваченных планет.

Если после MaxSteps = 10000 - 100000 (зависит от карты) ходов игра не окончилась, то результат определяется пропорционально количеству кораблей и планет у игроков: 0.5 * (playerShipsCount / allShips) + 0.5 * (playerPlanetsCount / allPlanetsCount).

Планета считается принадлежащей игроку если её уровень хотя бы 1, просто наличия кораблей на планете недостаточно.

Планеты

Каждая планета имеет уровень от 0 до 3. Нулевой уровень означает что планета нейтральная и не производит корабли (даже если на этой планете находятся корабли какого-то игрока). На любом другом уровне большим нуля планета производит (PlanetProductionMultiply = 1) * PlanetLevel кораблей между ходами игрока, которому она принадлежит (все корабли появляются одновременно ровно перед ходом игрока).

У планеты с уровнем хотя бы 1 есть PerLevelPlanetArmor[level] (100, 200, 300) очков защиты.

После улучшения планеты с уровня x до уровня x + 1 её очки защиты становятся равны PerLevelPlanetArmor[x + 1].

На планете может находится неограниченно количество кораблей одного игрока.

Если на планету прилетают корабли другого игрока происходит следующее:

  1. За каждый корабль прилетевшего игрока уничтожается один корабль "владельца" планеты (при этом корабль прилетевшего игрока тоже уничтожается, игрок, чьи корабли находятся на планете может не быть полноправным её владельцем, т.к. не захватил её)
  2. Если все корабли владельца планеты уничтожены, начинает повреждаться защита планеты, по одному пункту за каждый корабль прилетевшего игрока (корабли прилетевшего игрока тоже уничтожаются)
  3. Если защита планеты пала, планета переходит другому игроку, её уровень становится равен нулю

Если планета была нулевого уровня, она сразу переходит другому игроку после уничтожения всех кораблей на ней.

Дисквалификация

После дисквалификации игроку не дают делать ходы.

Отправленные группы кораблей и планеты остаются на карте. Планеты дисквалифицированного игрока продолжают производить корабли.

В конце игры дисквалифицированный игрок в любом случае получает 0 баллов (независимо от количества кораблей и планет у него).

Корабли дисквалифицированного игрока не учитываются в общем количестве кораблей.

Протокол взаимодействия

Взаимодействие происходит через стандартный ввод/вывод (не забывайте про std::endl).

После запуска вашей программе дают описание игровой карты в следующем формате:

Первая строчка содержит PlayerId PlayerCount PlanetCount - ваш номер, общее количество игроков и количество планет (1 <= PlayerId <= PlayerCount, 2 <= PlayerCount <= 4, PlayerCount <= PlanetCount <= 20)

Далее идет PlanetCount строк, каждая из которых содержит PlanetCount чисел. j-е число в i-й строке dist[i][j] означает расстояние между планетами i и j (1 <= dist[i][j] <= 100 для i != j, 1 <= i, j <= PlanetCount и dist[i][i] = 0 для 1 <= i <= n).

Перед каждым ходом игроку предоставляется следующая информация:

В первой строке идет число NumberOfLastMoves - количество отправленных групп кораблей между планетами между вашим прошлым и текущем ходом.

Если это число равно -1, то это означает что игра закончена и ваша программа должна немедленно завершиться. Если ваша программа не завершится, вас могут дисквалифицировать.

Если же число неотрицательно, то следующие из NumberOfLastMoves строк содержат PlayerId FromPlanetId ToPlanetId Count - какой игрок отправил, с какой планеты, на какую планету, сколько кораблей (1 <= PlayerId <= PlayerCount, 1 <= FromPlanetId, ToPlanetId <= PlanetCount, 1 <= Count)

Среди этих действий нет информации о захватах, улучшениях и починке защиты. Её можно узнать из состояния планет.

Следующие PlanetCount строк описывают состояния планет. Каждая строчка содержит

PlayerId ShipCount Level Armor

Если планета никому не принадлежит и на ней нет кораблей, все числа будут равны нулю.

Если планета имеет уровень 0 (никому не принадлежит), но на ней есть корабли игрока x, то

  1. PlayerId = x
  2. ShipCount = количество кораблей игрока
  3. Level = 0
  4. Armor = 0

Если планета имеет уровень хотя бы 1, то

  1. PlayerId = id владельца планеты, число от 1 до PlayerCount
  2. ShipCount = количество кораблей её владельца на планете (может быть равно нулю)
  3. Level = уровень планеты, число от 1 до 3
  4. Armor = Текущее состояние защиты планеты

Далее нужно сделать ход.

Для этого выведете число 0 <= NumberOfMoves <= MaxPlayerShipMovesPerStep в отдельной строке.

Далее выведете NumberOfMoves строк.

FromPlanetId ToPlanetId Count

  1. Если FromPlanetId != ToPlanetId, то с планеты FromPlanetId на планету ToPlanetId будет отправлена группа кораблей размера Count

  2. Если FromPlanetId == ToPlanetId то корабли пойдут на починку защиты планеты или её улучшение или захват

Операции будут выполняться последовательно.

Если какая-то операция невалидна, то она пропускается (например не хватает кораблей для улучшения, планета не принадлежит игроку, на планете недостаточно кораблей).

Очень важно не забывать выводить перевод строки и очищать буфер (std::endl).

Если превысить MaxPlayerShipMovesPerStep или нарушить протокол взаимодействия игрок будет немедленно дисквалифицирован.

Изначально у вашей стратегии есть ProcessPlayerStartTimeout = 2 секунд чтобы сделать все свои ходы. После каждого вашего хода это время увеличивается на ProcessPLayerTimeoutAdditionPerTurn = 0.001. Т.е. если вы сделаете 1000 своих мгновенно, у вас будет 3 секунды чтобы сделать текущий ход, а если же вы сделаете свой первый ход за одну секунду, у вас останется только 1.001 секунды на следующий ход.

Если выйти за лимит времени к какому-то ходу игрок будет дисквалифицирован без дальнейшей возможности продолжить игру.

Любые константы могут быть изменены.

Установка

Установка под MacOS

  1. Если у вас нет brew, установите его, введя в терминал команду
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. Установите и обновите нужные версии пакетов (на linux возможно подойдут те же команды, но со своим менеджером пакетов)
brew install cmake && brew upgrade cmake && brew install qt5 && brew upgrade qt5 && brew link qt5 --force
  1. Скачайте репозиторий
git clone https://github.com/chegoryu/Auralux.git
  1. Соберите репозиторий
cd Auralux && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="/usr/local/opt/qt5/" .. && make
  1. В вашей папке будет находится ранер стратегии. Можете запустить его командой
./game_runner example_runner_config.txt

About

Auralux tournament for losh

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •