Задача №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;# оттенок оставляемого муравьем запаха
Готовую программу необходимо сдать в тестирующую систему, а затем запустить ее на сервере.
Красивый пример работы стратегий можно посмотреть тут: