Индивидуальное задание 2
Полиморфизм
1) Модель “Хищник – Жертва”
Разработать систему, моделирующую поведение хищников и жертв в океане. Система должна состоять из следующих классов:
Ocean
Состоит из двумерного массива указателей на Cell. Инициализируется размерами, количеством объектов Obstacle, Prey и Predator заполняя соответствующими объектами двумерных массив указателей на Cell. Имеет счетчик числа ходов. Имеет функцию exec(), вызывающую функции exec() ячеек. Отображает свое содержимое и статистику (номер хода и количество объектов Obstacle, Prey и Predator). Заканчивает работу, когда количество Prey и Predator становится равным 0.
Cell (ячейка)
Абстрактный базовый класс.
Хранит указатель на Ocean, в котором находится, а также координаты своего местоположения в Ocean.
Имеет виртуальную функцию exec() с пустым телом, обеспечивающую выполнение одного хода.
Obstacle (препятствие)
Разновидность Cell. Не может двигаться.
Prey (добыча)
Разновидность Cell. Может двигаться. Перемещается с равной вероятностью на любую свободную ячейку. Может размножаться. Размножается, если ее время размножения достигло нуля и она переместилась. Потомство создается в том месте, из которого она переместилась. При создании и размножении ее счетчик timeToReproduce устанавливается в диапазоне от MIN_PREY_TIME_TO_REPRODUCE до MAX_PREY_TIME_TO_REPRODUCE случайным образом.
Predator (хищник)
Разновидность Prey. Если видит Prey в пределах своего хода, то ест ее. Не ест других Predator. В противном случае ведет себя так же, как и Prey. При создании и размножении ее счетчик timeToReproduce устанавливается в диапазоне от MIN_PREDATOR_TIME_TO_REPRODUCE до MAX_PREDATOR_TIME_TO_REPRODUCE случайным образом.
Ест Prey. Умирает от голода, если его timeToFeed достигло нуля. При создании и после еды устанавливает счетчик timeToFeed в диапазоне от MIN_TIME_TO_FEED до MAX_TIME_TO_FEED случайным образом.
Указание. Для предотвращения повторного хода объекта в течение одного цикла exec() введите в него переменную СчетчикХодов и сравнивайте ее со счетчиком ходов Ocean.
2) Дерево разбора выражений
Реализовать синтаксический разбор выражения, содержащего операции +, – (унарные и бинарные), *, /, стандартные математические функции, скобки и переменные. Результатом разбора должно стать дерево разбора выражения, каждый узел которого должен уметь вычислять свое поддерево с помощью виртуальной функции calculate(). Предусмотреть следующие разновидности узлов: BinaryNode, UnaryNode, VarNode, FunctionNode, RealNode. Предусмотреть также класс таблицы используемых переменных вместе с их значениями.
Указание. Для ввода значений переменных рекомендуется допустить следующий синтаксис для выражений:
{x=5;y=3} –(sin(x)+y)*3–x=
Здесь в фигурных скобках инициализируются все переменные.
Рекомендуется также организовать работу с программой в интерактивном режиме, позволяющем вычислять значения нескольких выражений в одном сеансе.
3) Библиотека графических объектов с возможностью полиморфного ввода-вывода
Реализовать библиотеку графических объектов, содержащую классы Shape (абстрактный), Point, Line (отрезок), Rectangle, Square, Circle, Ellipse, Polyline, Polygon (замкнутая Polyline), Figure (контейнер других фигур). При включении в Figure все потомки Shape имеют координаты относительно Figure. Сама Figure также является наследником Shape и таким образом может содержать другие Figure.
Обеспечить возможность сохранения в файл/восстановления из файла (полиморфный ввод-вывод). При сохранении в файл сохранять также имя (или уникальный идентификатор) класса, при восстановлении из файла вначале считывать этот идентификатор, а затем создавать объект соответствующего класса. Для этого создать ассоциативный массив пар (идентификатор класса; указатель на функцию, создающую пустой экземпляр этого класса). Каждый класс, желающий считывать свои объекты из файла, необходимо зарегистрировать перед началом работы программы. При встрече идентификатора некоторого класса необходимо обеспечить его поиск в ассоциативном массиве и вызов соответствующей функции.
Указание. Для ассоциативного массива легче всего воспользоваться шаблонным классом map<T> стандартной библиотеки.
4) Библиотека графических объектов с возможностью рисования
Реализовать библиотеку графических объектов, содержащую классы Shape (абстрактный), Point, Line (отрезок), Rectangle, Square, Circle, Polyline, Polygon (замкнутая Polyline), Triangle, Figure (контейнер других фигур). При включении в Figure все потомки Shape имеют координаты относительно Figure. Сама Figure также является наследником Shape и таким образом может содержать другие Figure. Каждый объект может себя рисовать, выполнять параллельный перенос, а также поворот относительно некоторой точки, передаваемой в качестве параметра (по умолчанию вращение должно происходить относительно опорной точки объекта). Опорная точка должна храниться в базовом классе Shape. Ее выбор для объекта не всегда тривиален. К примеру, для прямоугольника в качестве опорной точки можно выбрать одну из вершин либо же центр симметрии (последнее решение принято в векторных графических редакторах).
Указание. Для хранения списков объектов воспользуйтесь шаблонным классом list<Shape*> стандартной библиотеки.
5) Администратор сообщений
Реализовать систему объектов, поддерживающих сообщения друг от друга и обрабатывающих их.
Сообщение характеризуется уникальным идентификатором (тип сообщения) и параметрами. Простые параметры (int, double, char, char*) передаются через структуру с вариантной частью (union {int i; float f; double d; …}). Параметры большого размера передаются через указатель void*. Сообщение должно хранить идентификатор типа параметра (для стандартных параметров) и длину массива параметров (при передаче его через void*).
Каждый такой объект должен быть порожден от класса MessBase, инкапсулирующего прием/передачу сообщений. Вначале каждый объект типа MessBase регистрирует, сообщения каких типов он хочет принимать. Данная информация регистрируется в специальном объекте класса Adm (администратор), который запоминает все зарегистрированные сообщения в виде (ассоциативного) массива пар (Идентификатор сообщения, Список рассылки (список указателей на объекты, которым рассылать данное сообщение). Если некоторый класс MessBase отправляет сообщение (SendMessage), он вызывает соответствующую функцию-член администратора, которая рассылает это сообщение по соответствующему списку рассылки
Каждый объект типа MessBase имеет также виртуальную функцию
MessProc(MessBase* Sender, MessBase* Receiver, int MessID, Variant params);
где Sender – источник сообщения, Receiver – получатель, MessID – идентификатор сообщения, params – его параметры. Эта функция содержит “большую” инструкцию switch (MessID) на все типы обрабатываемых сообщений и является аналогом WndProc в Windows. Вначале она чисто виртуальная. Потомки MessBase должны ее переопределить, наполнив конкретными реакциями на сообщения.
Администратор также имеет специальное хранилище для передачи больших объектов.
Необязательная часть. Предусмотрите отправку сообщения с уведомлением, в котором возвращался бы указатель на получателя. Предусмотрите также возможность отправки обратного сообщения Senderу от Receiverа непосредственно, минуя администратор. Можно ли в этом случае передавать параметры большого размера?
6) Полиморфная графическая система
Реализовать иерархию графических классов, объекты которых хранятся в специальном контейнере – модели. Реализовать контейнер графических объектов. Реализовать также класс Graph, хранящий графические примитивы для отображения на экране. Создать два его подкласса, по-разному отображающие объекты на экране. Каждый графический объект хранит указатель на текущую графическую систему, в которой он будет нарисован по умолчанию. Каждый графический объект имеет также функцию Draw(Graph*) с указанием графической системы, на которой будет происходить рисование.
Выдать контейнер графических фигур на две графические системы.
7) Пересечения
Реализовать иерархию классов, содержащую подклассы класса Shape, а также функцию, проверяющую все фигуры на пересечения. Создать библиотеку из нескольких графических фигур. В отдельном файле предусмотреть создание новой фигуры, ее регистрацию для правильной работы функции пересечения.