Desdoc_prototype - Xrite/roguelike-haskell GitHub Wiki
Design document
После первой домашки на реализацию.
Общие сведения
Игра с консольной графикой в жанре roguelike, следующая канонам классических игр, но не реализующая большую часть интересных деталей.
Эта версия представляет собой всего лишь один уровень с возможностью перемещаться по нему.
Требования к первой версии
- Возможность генерации уровня или загрузка его с диска
- Возможность перемещаться персонажем по карте
- Консольная графика
Логическая структура
(Смотреть лучше справа-налево)
В языке с неизменяемыми переменными каждый вызов рандома создает новую копию генератора случайных чисел. Следить за ними становится чрезвычайно неприятно, поэтому сделана монада RandomMonad, прячущая состояние генератора в себя. Это тайпкласс, но написана реализация из (RandomGen g, MonadState g m) => RandomMonad g m.
С использованием этой монады написан генератор уровней по алгоритмы с binary space tree (см. статью).
Юнит -- общий интерфейс для всех игровых персонажей. Любое воздействие на юнита производится через специальынй DSL эффектов (Effect).
Каждый тип юнитов волен сам определять, как он поддается воздействию различных эффектов, что позволяет реализовывать любые механики (например сопротивление магическому урону). Воздействие на карту тоже будет производиться с помощью тех же эффектов, но пока это не реализовано.
Сейчас есть два типа юнитов -- игрок и моб. Моб это просто минимальная реализация тайпкласса, а игрок еще хранит информацию про стой опыт и уровни (ну и мб что-то еще что нужно будет исключительно игровым персонажам).
В хаскеле беда с полиморфизмом, поэтому чтобы иметь возможность класть разные типы юнитов в одну коллекцию через экзестенциальные типы сделан AnyUnit. Вообще это считается антипаттерн, но а как иначе?
Для хранения информации об игре есть Environment. Для его модификации в соответствие с игровыми правилами есть набор функция в модуле Move. В частности есть функция, которая по действию Action и идентификатору моба исполняет это действие, или говорит что оно невозможно (например пойти в стену -- это же не должно занимать хода если игрок случайно ошибся кнопкой).
Еще есть UI и сохранение уровней, но в этом я не силен, так что TODO