Я пытаюсь понять, как писать стратегические игры с использованием Scala функционально, но, к сожалению, я застрял в самой сути.(Это не домашняя работа, а мои попытки освоить что-то новое, а именно «чистое» функциональное программирование.)
Давайте возьмем следующую простую «игру»: (единственный) игрок имеет x одинаковые кусочки на бесконечном ряду квадратов.Части начинаются с квадрата 0, и каждый ход он может продвигать одну фигуру вперед на одну клетку.
В качестве структуры данных я буду использовать List[Int]
, где каждый элемент - это позиция (квадрат) одной фигуры.
Для генерации возможных ходов я придумал:
def moves(start: List[Int]) =
(0 until start.length).map({i => start.updated(i, start(i) + 1)});
val m1 = moves(List(0,0,0))
// m1 then contains Vector(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))
val m2 = moves(List(1,2,3))
// m1 then contains Vector(List(2, 2, 3), List(1, 3, 3), List(1, 2, 4))
Что мне не нравится, так это использование цикла индекса (0 until start.length)
.Это не кажется мне очень «функциональным».Это правильный способ сделать это или есть лучший способ?
Теперь в моем примере игры все фигуры идентичны, поэтому в случае m1
все три возможных хода также идентичны и могут /должны быть сведены в одно движение.Я изменил moves
, чтобы отсортировать каждый элемент перемещения, чтобы я мог получить список отдельных элементов:
def moves(start: List[Int]) =
(0 until start.length).map({i => start.updated(i, start(i) + 1).sorted}).distinct;
val m1 = moves(List(0,0,0))
// m1 then contains Vector(List(0, 0, 1))
val m2 = moves(List(1,2,3))
// m1 then contains Vector(List(2, 2, 3), List(1, 3, 3), List(1, 2, 4))
Однако для этого требуется, чтобы структура данных была сортируемой, и в моем "реальном" приложении это наиболеескорее всего, не List[Int]
, а класс Tuple или case.Думаю, мне понадобится метод distinct
, который принимает функцию, определяющую равенство.Как бы я это реализовал?