RoT*_*oRa 5 functional-programming scala
我试图理解在功能上使用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))
Run Code Online (Sandbox Code Playgroud)
我不喜欢的是使用索引循环(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))
Run Code Online (Sandbox Code Playgroud)
然而,这要求数据结构是可排序的,在我的"真实"应用程序中,它很可能不是一个List[Int],而是一个元组或一个案例类.我想我需要的是一个distinct方法,它采用定义相等的函数.我该如何实现?
如果你的部分是相同的,我认为你的数据结构是错误的。您需要一个 Map[Int,Int],其中键告诉您方块的索引,值告诉您有多少块(没有默认的计数集,否则这会更容易)。然后
def moves(start: Map[Int,Int]) = start.keySet.map(k => {
val n = start(k)
val pickup = (if (n == 1) (start - k) else start + (k -> (n-1)))
pickup + ((k+1) -> (start.getOrElse(k+1, 0) + 1))
})
Run Code Online (Sandbox Code Playgroud)
这解决了您的玩具示例中的所有问题(但可能不是您真正的问题)。它组成得很好:
scala> val firstmoves = moves(Map(0->3))
firstmoves: scala.collection.Set[scala.collection.immutable.Map[Int,Int]] =
Set(Map((0,2), (1,1)))
scala> val secondmoves = firstmoves.flatMap(moves)
secondmoves: scala.collection.Set[scala.collection.immutable.Map[Int,Int]] =
Set(Map((0,1), (1,2)), Map((0,2), (2,1)))
scala> val thirdmoves = secondmoves.flatMap(moves)
thirdmoves: scala.collection.Set[scala.collection.immutable.Map[Int,Int]] =
Set(Map((1,3)), Map((0,1), (1,1), (2,1)), Map((0,2), (3,1)))
Run Code Online (Sandbox Code Playgroud)