Проект “Симуляция” #
Суть проекта - пошаговая симуляция 2D мира, населённого травоядными и хищниками. Кроме существ, мир содержит ресурсы (траву), которыми питаются травоядные, и статичные объекты, с которыми нельзя взаимодействовать - они просто занимают место.
2D мир представляет из себя матрицу NxM, каждое существо или объект занимают клетку целиком, нахождение в клетке нескольких объектов/существ - недопустимо.
Идея взята отсюда и упрощена.
Комментарии по проекту - https://www.youtube.com/watch?v=3Vrwx4iryhw.
Что нужно знать #
- Java - коллекции, ООП
Мотивация проекта #
Основная цель - демонстрация принципов дизайна архитектуры приложения с помощью ООП. Описанная ниже структура классов не является всеобъемлющей, предполагается что студент будет ей следовать, взяв за основу.
Дизайн классов #
Entity
#
Корневой абстрактный класс для всех существ и объектов существующих в симуляции.
Grass
, Rock
, Tree
#
Rock
, Tree
- статичные объекты. Grass
- ресурс для травоядных.
Creature
#
Абстрактный класс, наследуется от Entity
. Существо, имеет скорость (сколько клеток может пройти за 1 ход), количество HP. Имеет метод makeMove()
- сделать ход.
Herbivore
#
Травоядное, наследуется от Creature
. Стремятся найти ресурс (траву), может потратить свой ход на движение в сторону травы, либо на её поглощение.
Predator
#
Хищник, наследуется от Creature
. В дополнение к полям класса Creature
, имеет силу атаки. На что может потратить ход хищник:
- Переместиться (чтобы приблизиться к жертве - травоядному)
- Атаковать травоядное. При этом количество HP травоядного уменьшается на силу атаки хищника. Если значение HP жертвы опускается до 0, травоядное исчезает
Map
#
Карта, содержит в себе коллекцию для хранения существ и их расположения. Советую не спешить использовать двумерный массив или список списков, а подумать какие ещё коллекции могут подойти.
Simulation
#
Главный класс приложения, включает в себя:
- Карту
- Счётчик ходов
- Рендерер поля
- Actions - список действий, исполняемых перед стартом симуляции или на каждом ходу (детали ниже)
Методы:
nextTurn()
- просимулировать и отрендерить один ходstartSimulation()
- запустить бесконечный цикл симуляции и рендерингаpauseSimulation()
- приостановить бесконечный цикл симуляции и рендеринга
Actions
#
Action
- действие, совершаемое над миром. Например - сходить всеми существами. Это действие итерировало бы существ и вызывало каждому makeMove()
. Каждое действие описывается отдельным классом и совершает операции над картой. Симуляция содержит 2 массива действий:
initActions
- действия, совершаемые перед стартом симуляции. Пример - расставить объекты и существ на картеturnActions
- действия, совершаемые каждый ход. Примеры - передвижение существ, добавить травы или травоядных, если их осталось слишком мало
Поиск пути #
Советую писать алгоритм поиска пути полностью с нуля, используя в качестве источника описание алгоритма на википедии. Проще всего начать с алгоритма поиска в ширину. Он относительно простой в реализации, но может работать медленно на больших полях, для которых лучше подойдет алгоритм A*.
Рендерер #
Рендерер ответственен за визуализацию состояния поля, его отрисовку. По желанию студента интерфейс приложения может быть консольным, либо графическим.
Конечная цель #
Реализовать симуляцию и подобрать различные значения так, чтобы взаимодействия внутри мира получились максимально интересными:
- Размер поля
- Диапазоны HP и скорости существ
- Диапазон атаки хищников
Опциональные идеи для усложнения проекта:
- Механика размножения существ
- Механика голода, когда от отсутствия пищи у них начинает уменьшаться HP
Ресурсы для работы над ошибками #
- Эталонная реализация проекта похожего уровня сложности, написанного на серии стримов
- Реализации проекта другими студентами и мои ревью этих реализаций
- Чеклист для самопроверки с типовыми ошибками (в конце страницы)
- Готовый проект можете отправить мне на ревью -
https://t.me/zhukovsd
- [Обновление от 7 сентября 2023] - целевое количество видео и текстовых ревью проекта “Симуляция” накоплено, новые реализации к ревью не принимаются. В любом случае призываю отправлять законченные проекты в чат, добавляю их в список. Подробности - https://t.me/zhukovsd_it_mentor/57
Чеклист для самопроверки #
❗️Спойлеры: советую не читать этот список до того момента, пока не допишете первую самостоятельную работающую версию проекта❗️
Проблемы и ошибки в коде:
- Интеграция библиотеки графического интерфейса ценой чистоты и понятности кода. Достаточно консольного интерфейса
- Дублирование кода между классами Herbivore и Predator
- Класс Map
- Неоптимальный выбор коллекции для хранения состояния ячеек
- Не использование generics, параллельные коллекции для разных типов существ (для каждого типа своя коллекция)
- Заполнение карты “пустотами”
- Недостаточная энкапсуляция - “протекающее” наружу внутреннее устройство класса Map (например, прямой доступ к коллекции ячеек) вместо набора методов с говорящими названиями (
AddEntity
,RemoveEntity
, и так далее) - Пример чистой энкапсуляции
- Иерархия классов
Action
’s- Дублирование кода
- Пример чистой реализации
- Неоднозначное именование полей, переменных, методов. Несовпадение имён смысловой нагрузке
- Поиск пути
- Реализация алгоритма поиска пути внутри классов существ. Следует вынести это в отдельный класс
- Дублирование кода для поиска пути хищниками и травоядными
Мелочи:
- Неиспользование
.gitignore
, из-за чего в репозиторий попадают лишние файлы и папки (например,target
,out
) - Неаккуратное форматирование кода
- Неиспользование пакетов для структурирования классов, все классы в корне проекта