Я создаю простую реализацию MiniMax на функциональном языке программирования Elixir. Поскольку существует множество игр с совершенным знанием (крестики-нолики, connect-four, шашки, шахматы и т. Д.), Эта реализация может стать основой для создания игровых ИИ для любой из этих игр.
Однако одна проблема, с которой я сталкиваюсь, заключается в том, как правильно сохранить состояние игры на функциональном языке. Эти игры в основном имеют дело с двумерными игровыми полями, где часто выполняются следующие операции:
- Прочитайте содержимое определенного места на доске
- Обновить содержимое определенного места на доске (при возврате новой возможности перемещения)
- Рассматривая содержимое одного или нескольких местоположений, которые связаны с текущим местоположением (то есть следующее или предыдущее горизонтальное, вертикальное или диагональное местоположение)
- Учитывая содержимое нескольких подключенных мест в любом направлении.
- Учитывая содержимое целых файлов, рангов и диагоналей.
- Поворот или зеркальное отображение доски (для проверки симметрий, которые дают тот же результат, что и что-то уже рассчитанное).
Большинство функциональных языков используют связанные списки и кортежи в качестве базовых строительных блоков многоэлементных структур данных. Тем не менее, они выглядят очень плохо для работы:
- Связанные списки имеют O (n) (линейное) время поиска. Кроме того, поскольку мы не можем «сканировать и обновлять доску» за один проход по доске, использование списков представляется очень непрактичным.
- Кортежи имеют O (1) (постоянное) время поиска. Однако представление доски в виде кортежа фиксированного размера очень затрудняет итерации по рядам, файлам, диагоналям или другим видам последовательных квадратов. Кроме того, и Elixir, и Haskell (это два известных мне функциональных языка) не имеют синтаксиса для чтения n- го элемента кортежа. Это сделало бы невозможным написание динамического решения, которое работало бы для плат произвольного размера.
Elixir имеет встроенную структуру данных Map (и Haskell Data.Map
), которая позволяет O (log n) (логарифмический) доступ к элементам. Прямо сейчас я использую карту с x, y
кортежами, которые представляют позицию в качестве ключей.
Это «работает», но неправильно использовать карты таким образом, хотя я не знаю точно, почему. Я ищу лучший способ хранения двумерной игровой доски на функциональном языке программирования.