Заготовка для написания ботов CodinGame.com
- Сделайте копию репозитория для конкретной игры.
- Пишите код в проекте bot.
- Начните с того, что скопируйте код ввода из шаблона codingame в StateReader: инициализационный ввод в ReadStateInit, а ввод для каждого раунда в ReadState.
- Опишите команды бота в файле BotCommands.cs
- Напишите алгоритм в Solver.cs
- builder сделайте стартовым проектом, при каждом запуске он собирает все файлы bot и lib в один файл и копирует его содержимое в буфер обмена.
- Тесты запускайте в проекте tests. На каждом раунде ваш бот будет писать на StdErr введённое состояние в компактном виде, удобном для того, чтобы скопировать его и перенести в тесты.
- Обобщённые алгоритмы ищите в lib.
- После окончания соревнования, все новое полезное обобщённое, что можно было бы поместить в lib, оформите в виде pull request к этому репозиторию. Не присылайте реализацию обобщённых алгоритмов поиска, только вспомогательные примитивы, которые могут оказаться полезными в будущем.
- ISolver — общая абстркция для алгоритмов поиска.
- State — состояние игры, StateInit — часть состояния, которое неизменно и вводится перед началом игры.
- StateReader — чтение State и StateInit.
- App — точка входа. Создает Solver, организует ввод и вывод.
Абстракция позволяет комбинировать разные солверы друг с другом. Некоторым солверам нужен другой солвер, для работы. Можно делать солверы обёртки. Например, вот так можно добавить логгирование 10 лучших найденных решений к любому солверу:
var solver = new MyCustomSolver(new SomeOtherSolver(...), ...).WithLogging(bestSolutionsCountToLog: 10);
Многие фичи лучше добавлять не в конкретный солвер, а делать оберткой, которую можно будет применить к любым солверам в будущем.
В проекте реализованы несколько базовых классов для алгоритмов: жадного алгоритма, случайного поиска и поиска восхождением.
ISolver возвращает решения. У каждого решения есть отладочная информация, как правило помогающая в отладке:
- Время и номер итерации, на которой было найдено решение.
- Количество улучшений найденного решения (не для всех алгоритмов поиска имеет смысл, но для HillClimbing и MonteCarlo —— имеет)
- Имя солвера (ISolver.ShortName), который нашел решение (удобно, когда вы начинаете комбинировать солверы)
Кроме того, уже реализованные солверы собирают статистику в течение всей игры про свою работу и на ToString возвращают строковое представление этой статистики.
В разных контестах CG команды, которые вы отдаёте боту устроены однообразно. Поэтому есть общий класс BotCommand для всех команд, который за вас реализует форматирование команды в строку. Вам остается только определить класс команды с публичными полями или свойствами вот так:
// MOVE X Y
public record Move(V Destination) : BotCommand;
// WAIT
public record Wait : BotCommand;
// USE BOOSTER
public class UseCommand(Bonus bonus) : BotCommand
Регистрируйте в объекте StatValue наблюдаемые значения случайной величины, а он посчитает матожидание, стандартное отклонение, доверительный интервал для матожидания и т.п.
Для того, чтобы код, активно манипулирующий векторами не был громоздким, класс вектора называется супер-кратко: V. В нем реализованы все операции, над целочисленными двумерными векторами, которые обычно нужны.
Из необычного — рассчет времени до столкновения с другим объектом, к которому мы движемся со скоростью speed: double GetCollisionTime(V speed, V obstacle, double radius)
Иногда нужен нецелочисленный вектор. Для этого есть аналогичный класс VD.
Много мелочей пригождаются постоянно во многих играх. Они собраны в файле Extensions.cs и оформлены методами расширения.
Бинарная куча. Её нет в net5, но нужна в некоторых алгоритмах. Вероятно, станет не нужна, когда CodingGame перейдет на net6 с его PriorityQueue.
- Архитектура: App + State + StateReader + Countdown + Solver + BotCommand — получается использовать всегда.
- Часто пригождаются StatValue, V, VD, некоторые Extension-методы.
- ISolver и его готовые реализации — получается применять далеко не в каждом контесте. Но когда они подходят, сразу получаешь кучу отладочной информации из коробки.