Задача №112583. Ants-submit
Игровой тур Чемпионата Урала по спортивному программированию 2006
Турнир программ даёт Вам возможность посоревноваться в несколько иных навыках, нежели требуются для классических олимпиад по программированию. Вам предстоит померяться силами с самой эволюцией. Только в отличие от неё у вас времени будет заметно меньше нескольких миллионов лет... Как Вы, наверное, уже догадались, Вам предстоит разработать программу, управляющую муравьём.
Все муравьи живут в небольшом квадратном мире заданных размеров, окружённом стеной. По углам игрового мира расположены муравейники - Ваш, и Ваших соперников. Ваша программа-муравей будет использована для управления каждым муравьём Вашего муравейника. С рассветом муравьи выходят из муравейника и отправляются на работу - искать еду. Их задача проста: Им необходимо до заката перенести как можно больше разбросанной по игровому полю еды в свой муравейник. Вот, собственно, и всё!
Игровой мир представляет собой квадратную сетку некоторого размера, окружённую стеной. В каждой клетке может находиться произвольное количество муравьёв, а также лежать несколько миллиграммов еды. В начале игры еда некоторым особым образом распределена по игровому полю.
В начале игры муравьи один за другим появляются на клетке своего муравейника.
У муравья есть набор сенсоров, которые позволяют ему определять следующую информацию для ближайших к нему 9 клеток:
-
isMyHill
: является ли клетка своим муравейником -
isEnemyHill
: является ли клетка чужим муравейником -
isFood
: есть ли на клетке еда -
isFriend
: есть ли в клетке свои муравьи (отличные от того, кому принадлежит сенсор) -
isEnemy
: есть ли чужие муравьи -
isWall
: является ли клетка стеной, которой огорожен игровой мир -
оттенок (
smell
) и интенсивность (smellIntensity
) запаха, оставленного на клетке.
У каждого муравья есть память размером 32 байта, которую он может использовать как угодно. Кроме того, муравей всегда знает, есть ли у него в лапах еда.
Муравей за каждую единицу времени может сделать одно из следующих действий:
-
Передвинуться на одну из четырёх соседних ячеек.
-
Укусить другого муравья, находящегося на одной из четырёх соседних ячеек.
-
Если у муравья нет еды, то он может поднять один миллиграмм еды с той ячейки, где находится он сам.
-
Если у муравья есть еда, то он может положить её на ту же ячейку, где находится он сам.
Одновременно с этим муравей может пометить клетку, на которой находится, некоторым запахом с интенсивностью 100 единиц. Помечивание запахом происходит до передвижения муравья. Старый запах клетки полностью перекрывается новым. В начале игры все клетки имеют интенсивность запаха равную 0.
Муравей, кусая в одну из сторон, обездвиживает на 8 ходов одного из находящихся там чужих муравьёв. Муравей, на которого придётся укус, всегда выбирается по такому алгоритму:
-
Если в клетке есть муравей, способный двигаться, то укус приходится на него. Если таких несколько, то выбирается произвольный из них.
-
Если способных двигаться муравьёв нет, то укус приходится на того, к которому способность двигаться вернётся раньше других.
-
Если в клетке, куда направлен укус, вообще нет муравьёв, то ни один муравей не обездвиживается.
Если у укушенного муравья была с собой еда, она падает на ту клетку, где находится укушенный муравей. Обездвиженному в результате укуса муравью управление не передаётся до тех пор, пока, к нему не вернётся способность двигаться.
В процессе игры ход по очереди передаётся каждому муравью в следующем порядке:
-
всем муравьям первого игрока в порядке появления муравьёв на игровом поле;
-
всем муравьям второго игрока в порядке появления муравьёв на игровом поле;
-
и так далее.
Состояние игры обновляется после каждого хода каждого муравья. Как только все муравьи совершили ход, считается, что прошла одна единица игрового времени.
У каждой ячейки может быть некоторый запах.
Запах характеризуется двумя неотрицательными числами: оттенком запаха (smell
) и интенсивностью (smellIntensity
).
За единицу времени интенсивность запаха всех ячеек (с интенсивностью запаха отличной от нуля) уменьшается на единицу.
Алгоритм поведения одного муравья реализуется в программе-муравье. Эта программа используется для управления всеми муравьями одного муравейника.
Программа-муравей представляет собой библиотеку, в которой содержится
функция GetAction
, возвращающая очередной ход муравья.
В качестве параметров в эту функцию передаётся информация с органов,
а также содержимое памяти муравья.
Алгоритм должен быть достаточно прост, так как на работу этой функции отводится ~0.5 секунды времени.
Жюри оставляет за собой право дисквалифицировать программы, нарушающие это ограничение.
Библиотека игрока загружается в память в начале игры и выгружается в конце игры.
На каждый ход каждого муравья вызывается функция GetAction
.
Для создания программы-муравья всем участникам предоставляются шаблоны проектов, которые уже представляют собой корректные программы. Вам необходимо будет только подкорректировать код соответствующих функций, чтобы они работали в соответствии с Вашей задумкой.
В своих решениях вы можете использовать только локальные переменные.
Шаблоны находятся по ссылке: samples.zip
Шаблон проекта состоит из двух файлов: Файла проекта DelphiSample.dpr
и модуля Ants.pas
.
Все свои изменения нужно вносить исключительно в файл проекта.
Модуль Ants.pas
менять не рекомендуется, потому что жюри со своей стороны будет компилировать
ваш проект с модулем Ants.pas
в его первоначальном виде.
Чтобы создать программу-муравья Вам следует
написать тело процедуры GetAction
так, чтобы она реализовывала вашу задумку. Вот ее прототип:
procedure GetAction(sensors: TSensors; hasFood: Boolean; memory: PMemory; var result: TAntAction); cdecl;
Далее приводятся определения и описания всех необходимых типов.
const MAX_MEMORY = 32; // Размер памяти вашего муравья type // Все возможные действия муравья TAntActionType = ( aaMoveUp, aaMoveLeft, aaMoveDown, aaMoveRight, // передвижение aaBiteUp, aaBiteLeft, aaBiteDown, aaBiteRight, // кусание aaGet, aaPut); // манипуляция с едой // Показания органа чувств муравья. // Орган чувств возвращает информацию об одной клетке игрового поля TAntSensor = record smell: Integer; // оттенок запаха smellIntensity: Integer; // интенсивность запаха isFriend: Boolean; // наличие "своего" муравья isEnemy: Boolean; // наличие "чужого" муравья isMyHill: Boolean; // наличие "своего" муравейника isEnemyHill: Boolean; // наличие "чужого" муравейника isFood: Boolean; // наличие еды isWall: Boolean; // наличие стены end; // Действие муравья на текущем ходу TAntAction = record actionType: TAntActionType; // передвижение, кусание или манипуляция с едой putSmell: Boolean; // оставить ли запах на клетке smell: Integer; // оттенок оставляемого муравьём запаха end; // Показания всех сенсоров муравья для ближайших 9 клеток к муравью. // sensors[-1, -1] - информация о левой верхней соседней клетке // sensors[1, -1] - информация о правой верхней соседней клетке // sensors[1, 1] - информация о правой нижней соседней клетке // и т.д. TSensors = array[-1..1, -1..1] of TAntSensor; // Память муравья PMemory = ^TMemory; TMemory = array[0..MAX_MEMORY-1] of Byte;
В шаблонный проект включено два файла: основной код в файле main.cpp
и заголовочный файл IAntLogic.hpp
.
Все свои изменения нужно вносить исключительно в файл main.cpp
.
Остальные файлы менять не рекомендуется, потому что жюри со своей стороны будет компилировать
ваш проект с этими файлами в их первоначальном виде.
Чтобы создать программу-муравья Вам следует
написать тело функции GetAction
так, чтобы она реализовывала вашу задумку. Вот ее прототип:
AntAction GetAction(const Ant &ant, AntSensor sensors[3][3])
ant - состояние муравья
sensors - показания всех сенсоров муравья для ближайших 9 клеток к муравью.
-
sensors[0][0] - информация о левой верхней соседней клетке
-
sensors[2][0] - информация о правой верхней соседней клетке
-
sensors[2][2] - информация о правой нижней соседней клетке
-
sensors[1][1] - информация о клетке, в которой находится муравей
-
и т. д.
Далее приводятся определения и описания всех необходимых типов.
// Все возможные действия муравья enum AntActionType{ // передвижение: MOVE_UP = 0, MOVE_LEFT = 1, MOVE_DOWN = 2, MOVE_RIGHT = 3, // кусание: BITE_UP = 4, BITE_LEFT = 5, BITE_DOWN = 6, BITE_RIGHT = 7, // манипуляция с едой: GET = 8, PUT = 9, }; // Действие муравья на текущем ходу struct AntAction { AntActionType actionType; // передвижение, кусание или манипуляция с едой bool putSmell; // оставить ли запах на клетке int smell; // оттенок оставляемого муравьём запаха }; // Показания органа чувств муравья. // Орган чувств возвращает информацию об одной клетке игрового поля struct AntSensor{ int smell; // оттенок запаха int smellIntensity; // интенсивность запаха bool isFriend; // наличие "своего" муравья bool isEnemy; // наличие "чужого" муравья bool isMyHill; // наличие "своего" муравейника bool isEnemyHill; // наличие "чужого" муравейника bool isFood; // наличие еды bool isWall; // наличие стены }; // Класс, описывающий состояние муравья class Ant { public: virtual char* getMemory() const = 0; // память муравья virtual bool hasFood() const = 0; // есть ли у муравья еда virtual ~Ant() {} }; const int MAX_MEMORY = 32; // Размер памяти вашего муравья
В шаблонный проект включено два файла: основной код в файле GetAction.py
и модуль InterGetAction.py
.
Все свои изменения нужно вносить исключительно в файл GetAction.py
.
Остальные файлы менять не рекомендуется, потому что жюри со своей стороны будет компилировать
ваш проект с этими файлами в их первоначальном виде.
Внимание: в связи с особенностями реализации программы на языке Python будут выполняться дольше, чем можно ожидать!
Чтобы создать программу-муравья Вам следует
написать тело функции GetAction
так, чтобы она реализовывала вашу задумку. Вот ее прототип:
AntAction GetAction(Ant, Sensor[3][3])
Ant - состояние муравья.
Sensors - показания всех сенсоров муравья для ближайших 9 клеток к муравью.
-
Sensors[0][0] - информация о левой верхней соседней клетке
-
Sensors[2][0] - информация о правой верхней соседней клетке
-
Sensors[2][2] - информация о правой нижней соседней клетке
-
Sensors[1][1] - информация о клетке, в которой находится муравей
-
и т. д.
Далее приводятся определения и описания всех необходимых типов.
#Все возможные действия муравья: ActionType = { #Передвижение: "MOVE_UP":0, "MOVE_LEFT":1, "MOVE_DOWN":2, "MOVE_RIGHT":3, #Кусание: "BITE_UP":4, "BITE_LEFT":5, "BITE_DOWN":6, "BITE_RIGHT":7, #Манипуляции с едой: "GET":8, "PUT":9 } # Класс, описывающий состояние муравья class Ant(): def __init__(self, _memory, _hasFood, _teemId): self.memory = _memory; # память муравья, список из 32 чисел от 0 до 255 # если записанное число не лежит в этом диапазоне, сохранность данных не гарантируется self.hasFood = _hasFood; # несет ли еду # Показания органа чувств муравья. # Орган чувств возвращает информацию об одной клетке игрового поля class Sensor(): def __init__(self, _smell, _smellIntensity, _isFriend, _isEnemy, _isMyHill, _isEnemyHill, _isFood, _isWall): self.smell = _smell # оттенок запаха self.smellIntensity = _smellIntensity # интенсивность запаха self.isFriend = _isFriend # наличие "своего" муравья self.isEnemy = _isEnemy # наличие "чужого" муравья self.isMyHill = _isMyHill # наличие "своего" муравейника self.isEnemyHill = _isEnemyHill # наличие "чужого" муравейника self.isFood = _isFood # наличие еды self.isWall = _isWall # наличие стены #Действие муравья на текущем ходу class AntAction(): def __init__(self, _actionType, _putSmel, _smell): self.actionType = _actionType;# передвижение, кусание или манипуляция с едой self.putSmell = _putSmel;# оставить ли запах на клетке self.smell = _smell;# оттенок оставляемого муравьем запаха
Готовую программу необходимо сдать в тестирующую систему, а затем запустить ее на сервере.
Красивый пример работы стратегий можно посмотреть тут: