Задача №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

Delphi: Шаблон проекта и API

Шаблон проекта состоит из двух файлов: Файла проекта 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;
        

С++: Шаблон проекта и АPI

В шаблонный проект включено два файла: основной код в файле 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; // Размер памяти вашего муравья
        

Python 3: Шаблон проекта и АPI

В шаблонный проект включено два файла: основной код в файле 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;# оттенок оставляемого муравьем запаха
        

Отправка программы-муравья

Готовую программу необходимо сдать в тестирующую систему, а затем запустить ее на сервере.

Красивый пример работы стратегий можно посмотреть тут:

Константы: Размер поля: 31х31, Количество муравьёв: 10.
Сдать: для сдачи задач необходимо войти в систему