С чего начать

  1. Ознакомьтесь с правилами
  2. Скачайте себе игровой сервер, настройте и запустите
  3. Скачайте один из стартовых пакетов и запустите локально. Убедитесь что все отработало как надо, изучите код
  4. Если стартового пакета для вашего языка не предусмотрено, то вы можете создать его с нуля, руководствуясь описанием протокола
  5. Разработайте стратегию, реализуйте и протестируйте локально. Простейшая стратегия реализована в клиенте для javascript. Для начала попробуйте справиться с этим ботом :)
  6. Гововы? Запускайте своего бота на официальном сервере и следите за его схватками

Стратегия

Здесь будут подсказки и замечания по стратегии, когда таковая будет выработана

Правила игры

smart-dog - пошаговая игра. Каждая партия ограничена по числу ходов, по достижению которого (и не раньше) игра заканчивается и определяется победитель

Карта

Есть двухмерная карта размерами от 2х2 до 1000х1000 клеток. Каждая клетка карты представляет собой один из следущих элементов ландшафта:

  • Трава - по траве могут перемещаться игровые объекты
  • Забор, Дерево - по ним перемещаться нельзя
  • Загон - специальная область, привязанная к определенному игроку. Загон всегда имеет прямоугольную форму. На карте может быть более одного закона.

Кроме того на карте находятся игровые объекты, которые могут перемещаться:

  • Собаки - от 1 особи на каждого игрока. Именно собаками управляет игрок.
  • Овцы - от 1 особи на каждого игрока. Овцы перемещаются самостоятельно, на их движение можно влиять только косвенно.

Цель игрока

На момент последнего хода собрать как можно больше овец в своем загоне.

Подсчет очков

Очки подсчитываются по следующей формуле:

I = <изначальное кол-во овец в загоне игрока>;
M = <изначальное кол-во овец на территории игрока>;
C = <кол-во овец в загоне на конец игры>;
if (C == I) {
    score = 0;
}
else if (C < I) {
    score = -10 * (I - C) / I
}
else {
    score = 10 * C / M;
}

Если по-простому, то:

  • 0 очков - если в загоне столько же овец, сколько было на начало игры
  • -10 очков - если в загоне вообще не осталось овец, но они были там на начало игры
  • 10 очков, если в загоне все овцы, что были на территории игрока на начало игры
  • 20 очков, если в загоне в 2 раза больше овец, чем было на территории игрока на начало игры,

Поведение собак

  1. За один ход собака может переместиться на 1 клетку в любую сторону (но не по диагонали), если на этой клетке нет собаки, овцы, забора или дерева.
  2. За один ход собака может гавкнуть один раз, причем можно сделать это до или после движения
  3. Если вражеская собака находится на расстоянии dogBarkingR и меньше от вашей и ваша собака гавкает, то:
    • Если ваша собака находится на территории вражеской собаки, то та обалдевает от такой наглости (indignant) и не может гавкать ближайшие dogScaryTurns ходов, начиная со следующего
    • иначе вражеская собака пугается (panic) и не может ходить и гавкать ближайшие dogScaryTurns ходов, начиная со следующего
  4. Если две собаки гавкают одновременно, находясь на расстоянии dogBarkingR и меньше, то указанное в пунктах 2 и 3 работает для обеих. Возможно, обе испугаются и застынут. Возможно одна из них только потеряет дар речи.
  5. Напуганная собака может быть перенапугана другой собакой. При этом предыдущее состояние забывается, т.к. у собак не очень с памятью - напуганную собаку вполне может отпустить, если она услышит лай со своей территории
  6. Собаки одного игрока не пугают друг друга
  7. Собака, гавкнувшая на расстоянии dogBarkingR от другой собаки того же игрока, отменяет испуг сделанный на предыдущих ходах.
  8. Если в один ход собака попадает под действие лая вражеской и своей собак, то приоритет у вражеской - собака пугается.
Внимание: игроки делают ход одновременно, поэтому если две собаки пытаются делать ход в одну и ту же клетку, то более быстрый игрок сделает это, а второму в ответ на команду move вернется предвпреждение

Поведение овец

  1. Овцы в загоне послушно стоят и самопроизвольно не перемещаются.
  2. Овцы вне загонов ждут sheepStandBy ходов от начала игры, потом делают ход, потом сново ждут то же число ходов, и т.д. Зная sheepStandBy можно рассчитать будет ли овца ходить в ход N или нет по формуле: N % (sheepStandBy+1) == 0. Подразумевается что номер хода N отсчитывается с 1
  3. На начало игры все овцы собираются двигаться вниз
  4. Если движение по выбранному направлению невозможно, то овца пробует:
    • Повернуть налево (относительно оригинального направления)
    • Повернуть направо
    • Пойти назад
  5. Порядок, в котором овцы совершают ход, зависит от обстановки. Система старается сделать так, чтобы все овцы совершили перемещение и не мешали друг другу.
  6. Овца движется строго в одну сторону и меняет направление только если прямо не пройти, или если напугана
  7. Если собака гавкает на расстоянии dogBarkingR от овцы, овца пугается и ближайшие sheepScaryTurns ходов двигается без остановок в сторону противоположную той, откуда раздался лай.
  8. Уже испуганная овца может быть испугана другой или той же собакой по тем же правилам.
  9. Испуганная овца пугает овец в соседних клетках с ней (в том числе по диагонали), и те бегут в ту же сторону в течение sheepScaryTurns - 1 ходов.
  10. Испуганная овца не может быть испугана испуганной овцой
  11. Испуганная овца не меняет направление, пока испуг не пройдет
  12. Если овца А была напугана вследствие испуга овцы Б (прямо или опосредованно через других овец), то овца Б не может быть испугана овцой А (для предотвращения цикличепских испугов). Считаем, что овцы неплохо помнят то, чего испугались.

API

Игровой сервер слушает порт 3002. Клиент должен подключиться к этому порту (используя обычные сокеты), после чего клиент и сервер могут обмениваться командами

Команда со стороны клиента - это строка, состоящая из имени команды и аргументов, разделенных пробелами, завершающаяся символом перевода строки (\n)

<команда>[ <аргумент 1>[ ...]]\n

do 4 move left\n
end\n

Команда со стороны сервера - это строка, состоящая из имени команды и одного аргумента, представляющего собой JSON-подобную структуру одного из двух видов:

Массив строк
Задается в виде строк, разделенных запятой.
<команда> "<строка 1>"[,"<строка 2>"[...]]
Для того чтобы превратить аргумент в JSON массив достаточно обрамить его квадратными скобками - [ и ]
Структура
Задается в виде пар ключ/значение. Ключ и значение разделены знаком равно (=), как ключ так и значение заключены в кавычки. Пары разделены запятой
<команда> "<ключ 1>"="<значение 1>"[,"<ключ 2>"="<значение 2>"[...]]
Для того чтобы превратить аргумент в JSON объект достаточно обрамить его фигурными скобками - { и }

Все команды и их аргументы регистрозависимы!

Ниже приведен список всех команд и их синтаксиса, а так же пример общения сервера и клиента

join Клиент Сервер

join <username>
join <username> #<hub>

Клиент регистрируется на сервере, изъявляя желание играть от имени игрока <username> в хабе <hub>. Если хаб не задан, то подразумевается хаб по умолчанию

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

Сервер возвращает либо error либо wait и подбирает подходящую игру и соперников для клиента

wait Клиент Сервер

wait

Сервер сообщает, что клиент успешно зарегистрирован и теперь должен ждать, пока сервер подберет подходящую игру и соперников

start Клиент Сервер

start "rows":"<rows>","cols":"<cols>",...

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

rows
Размер карты по вертикали
cols
Размер карты по горизонтали
players
Количество игроков
you
Ваш идентификатор (>= 1 и <= players)
dogVisibilityR
Радиус на который видят собаки
dogBarkingR
Радиус на который распространяется лай собаки. Меньше или равен dogVisibilityR
sheepScaryTurns
Сколько ходов овца напугана лаем, включая тот ход, в который она была напугана
dogScaryTurns
Сколько ходов собака напугана или возмущена лаем, НЕ включая тот ход, в который она была напугана/возмущена
sheepStandBy
Раз в какое кол-во ходов овцы делают ход
turnsLimit
Максимальное количество ходов, на которое запланирована игра
x1, x2, y1, y2
Координаты вашей территории. Лай вражеской собаки с этой територии возмущает вашу собаку, но не пугает.

landscape Клиент Сервер

landscape "<строка 1>"[,"<строка 2>"[...]]

Сервер присылает полную карту местности, но без местоположения овец и собак, в виде массива строк. Каждая строка - это строка карты, каждый символ - ячейка карты

Для карты используются следующие символы:

#
Забор
^
Дерево
.
Трава
1, 2, 3, 4
Загон, принадлежащий игроку с соответствующим номером. Ваш номер передается с командой start как аттрибут you

state Клиент Сервер

state "turn":"<turn>"

Сервер присылает сообщение state перед очередным ходом, указывая номер хода. Номер хода начинается с 1, последний ход имеет номер turnsLimit

obj Клиент Сервер

#Собака
obj "id":"<id>","x":"<x>","y":"<y>","type":"Dog","owner":"<playerId>","action":"move|panic|indignant"[,"voice":"barking"]
#Овца
obj "x":"<x>","y":"<y>","type":"Sheep","action":"standBy|move|panic","direction":"left|down|right|up"
#Неизвестный лающий объект
obj "x":"<x>","y":"<y>","voice":"barking"

Сервер присылает по одной команде obj для каждого объекта, который:

  • попал в поле видимости одной из собак игрока (расстояние <= dogVisibilityR)
  • издал звук. В текущей версии звуки издают только собаки, следовательно лающая собака раскрывает свое местоположение

В качестве аргумента передается структура, содержащая следующую информацию об объекте:

x, y обязательные
Координаты объекта
type
Тип объекта - Dog или Sheep. Может отсутствовать, если объект не видим, но только слышен
owner
Идентификатор владельца, от 1 до players. Только для собак
action
Состояние объекта. Может отсутствовать, если объект не видим, но только слышен.
action может принимать следующие значения
actionДля собакиДля овцы
standBy Не бывает Овца в этот ход собирается остаться на месте
move Обычное состояние для собаки Овца в этот ход собирается перемещаться в сторону direction
panic Собака напугана, и не может двигаться и лаять в этот ход Овца напугана в этот ход и собирается перемещаться в сторону direction
indignant Собака возмущена, и не может лаять в этот ход Не бывает
direction
Направление, куда собирается двигаться овца, если ничего не случится. Только для овец
voice
Звук, который издает объект. Может отсутствовать, если объект не издает звуков. В текущей версии может иметь значение barking и присутствовать только для собак

turn Клиент Сервер

Сервер извещает клиента о том, что информация обо всех объектах была передана, и теперь клиент может совершать ход

do Клиент Сервер

#Двигаться
do <dogId> move left|right|up|down
#Гавкать
do <dogId> bark

Клиент сообщает серверу действие, которое совершает собака игрока с указанным идентификатором. Идентификатор берется из сообщения obj пришедшее с сервера.

За один ход игрок может переместить каждую собаку один раз и гавкнуть каждой из собак

warning Клиент Сервер

<dogId> <warning>

Присылается сервером если команда do не может быть выполнена. Например, эта собака уже ходила в этот ход, или она напугана и не может перемещаться

end Клиент Сервер

Клиент сообщает серверу, что ход завершен

finished Клиент Сервер

Сервер сообщает клиенту о том, что игра окончена

error Клиент Сервер

Сервер присылает это сообщение при любой ошибке. Может возникнуть в любой момент

Пример обмена сообщениями

 > join bot1
 < wait
 < start "you":1,"rows":40,"cols":40,"players":2,"x1":0,"x2":19,"y1":0,"y2":19,"waitForTurn":300000,"dogVisibilityR":"4","dogBarkingR":"4","sheepStandBy":"4","sheepScaryTurns":"4","turnsLimit":100,"dogScaryTurns":"4","ownSheepsCount":10,"maxSheepsCount":12
{cols=40, waitForTurn=300000, sheepStandBy=4, dogBarkingR=4, y1=0, y2=19, you=1, x2=19, rows=40, x1=0, dogScaryTurns=4, turnsLimit=100, players=2, sheepScaryTurns=4, ownSheepsCount=10, dogVisibilityR=4, maxSheepsCount=12}
 < landscape "........................................","........................................","........................................","........................................","######..................................","#1111#..................................","#1111...................................","#1111#..................................","######..................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","....................######..............","....................#2222#..............","....................#2222...............","....................#2222#..............","....................######..............","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................","........................................"
 < state  "turn":1
 < obj  "id":134,"type":"Dog","x":5,"y":6,"owner":1,"action":"move"
 < turn
 > do 134 move down
 > do 134 bark
 > end
 < warning 134 Cannot move to 5, 7  - there is a non traversable landscape or another object
 < state  "turn":2
 < obj  "id":134,"type":"Dog","x":5,"y":6,"owner":1,"action":"move","voice":"barking"
 < turn
 > do 134 move right
 > do 134 bark
 > end
 < state  "turn":3
 < obj  "id":134,"type":"Dog","x":6,"y":6,"owner":1,"action":"move","voice":"barking"
 < obj  "voice":"barking","x":24,"y":26
 < turn
 > do 134 move up
 > do 134 bark
 > end
 < finished
                

Официальный сервер

Доступен по адресу http://ai.actimind.com/. Для игроков используется порт 3002

Хабы, работающие на официальном сервере:

default
Хаб по-умолчанию. Используются все виды карт, минимальное количество игроков для игры 2, максимальное - 4.
solo
Используются все виды карт. Каждый подключившийся играет в одиночку, без соперников
duet
Используются все виды карт. Во всех играх участвуют 2 игрока
trio
Используются все виды карт. Во всех играх участвуют 3 игрока
quartet
Используются все виды карт. Во всех играх участвуют 4 игрока

Фазы соревнования

Соревнование проходит в несколько фаз:

  1. Бета-тестирование (идет сейчас)

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

    цель этапа: тестирование сервера, оценка адекватности правил и предлагамых карт

    окончание этапа: 31 декабря 2012

  2. Подготовка

    Публикуется окончательная версия правил и игровой сервер, дальнейшие изменения в них исключаются, за исключением фикса багов.

    Цель этапа: дать участникам время подготовить и потестировать бота для соревнования

  3. Турнир

    Создаются турнирные карты, производится запись на турнир. После чего проводится серия игр со всеми участниками турнира.

    Цель этапа: определить победителя!

Помощь и участие

Нужна ли нам помощь? Конечно же да!. Если у вас есть желание && возможность помочь - то вот что можно сделать:

  • Потестировать сервер и сообщить нам об ошибках
  • Предложить улучшения по коду, по игровым правилам, по формату соревнования - по всему
  • Улучшить графику и рендеринг
  • Написать стартовый пакет для другого языка
  • Вычитать, проверить и исправить документацию
  • Дописать юнит-тестов - неплохой способ потренироваться, кстати
  • ... любая другая помощь - предлагайте, не откажемся :)

Пишите - alexey.grishin@actimind.com. Баги можно постить прямо на github