使用(功能)Scala对二十一点表进行建模

时间:2016-03-20 16:29:58

标签: scala functional-programming

我想将二十一点游戏作为训练我的scala技能的一种方式,我想以功能的方式这样做,只使用val属性。

我有一张桌子,里面有一只鞋子,里面装有一张卡片。 一旦我处理了一张卡片,我就不得不重建一张没有卡片的新卡片列表,因为它不是可变的,但是我必须用新的卡片列表重建一双新的鞋子,因为鞋子不是可变的。但后来我必须用新鞋重建桌子,因为桌子本身不可变,等等...... 我觉得我做错了。什么是桌子本身是游戏场地的一部分,它本身就是赌场的一部分等等。每次发牌,或者下注或者球员加入或离开时,我真的需要重建一切吗?

有人能给我一些关于设计这个的最佳方法的见解吗?

也许我应该将游戏状态存储在数据库而不是对象中?

2 个答案:

答案 0 :(得分:2)

我有3条建议,

第一个是阅读书籍“Functional Programming in Scala”,它有一章涵盖了功能状态,这对于看这个是非常宝贵的。

第二个是查看State Monad,它是一个包含来自S =>的函数的monad。 (A,S)基本上是一个以当前状态作为输入,产生结果和新状态作为输出的函数。

最后一个是查看功能镜头,有几个实现,但它们允许您为深度嵌套的属性创建具有更改值的不可变结构的副本。我个人使用lens implementation in Shapeless

最后一点,通常构建功能程序,以便在最外层处理可变性和副作用,例如IO,数据库交互等。您在数据库中存储状态的想法从根本上意味着您是使用可变状态。

答案 1 :(得分:0)

在Clojure(或其他任何(半)函数语言中)我通常会使用一个原子解决这个问题,这个原子是一个可变的存储位置,它本身拥有代表整个游戏状态的不可变数据结构。游戏状态通常使用具有各种条目的不可变哈希图来建模。在Scala中,可能是一个案例类。在功能程序中进行变异没有任何问题,只要它在一个地方被隔离并且使用将前一个映射到下一个状态的函数以原子方式完成更新。您可以在许多React实现中找到相同的想法,例如Redux,它将整个UI表示为一个数据结构。我不知道Scala是否有类似Clojure原子的东西,如果这被认为是惯用的话。 您可以使用递归代替可变引用。每次玩家玩游戏时,您都会进入新游戏状态的新递归。