gpt4 book ai didi

haskell - 如何在 Haskell 中建模 2D 世界

转载 作者:行者123 更新时间:2023-12-03 14:11:30 28 4
gpt4 key购买 nike

我在做游戏。游戏由一个无限平面组成。单位必须在一个离散的正方形上,因此可以使用简单的 Location { x :: Int, y :: Int } 来定位它们。

可能有很多种Unit s。有些可能是生物,有些只是物体,例如一 block 石头或木头(想想那里的 2d minecraft)。许多将是空的(只是草或其他)。

你会如何在 Haskell 中建模呢?我已经考虑过执行以下操作,但是 Object vs Creature 呢?他们可能有不同的领域?在 Unit 上将它们全部标准化?

data Unit = Unit { x :: Int, y :: Int, type :: String, ... many shared properties... }

我也考虑过有一个位置类型
data Location = Location { x :: Int, y :: Int, unit :: Unit } 
-- or this
data Location = Location { x :: Int, y :: Int }
data Unit = Unit { unitFields... , location :: Location }

你有什么想法?在 OO 语言中,我可能会有 LocationUnit相互继承,并使特定类型的 Unit 相互继承。

另一个考虑因素是这将通过网络发送大量这些对象,因此我需要将它们序列化为 JSON 以在客户端使用,并且不想编写大量的解析样板。

最佳答案

Location只是一个简单的二维Point类型。

我建议不要绑定(bind) Unit s 到他们所在的位置;只需使用 Map Location Unit处理网格上位置之间的 map 以及那里存在什么(如果有的话)。

至于具体类型Unit去吧,我至少会建议将公共(public)字段分解为数据类型:

data UnitInfo = UnitInfo { ... }

data BlockType = Grass | Wood | ...

data Unit
= NPC UnitInfo AgentID
| Player UnitInfo PlayerID
| Block UnitInfo BlockType

或类似的。

通常,将常见的事物分解到它们自己的数据类型中,并尽可能保持数据简单和“隔离”(即将诸如“这个单元在什么位置?”之类的东西移动到将两者关联起来的单独结构中,以便单独的数据-类型尽可能“永恒”、可重用和抽象)。

拥有 String对于 Unit 的“类型”是 Haskell 中一个强大的反模式;它通常表明您正在尝试使用数据类型实现动态类型或 OOP 结构,这是不合适的。

您的 JSON 要求使事情变得复杂,但是 this FAQ entry展示了一个很好的例子,说明如何在没有 String 的情况下在 Haskell 中惯用地实现这种通用性。打字或花哨的类型类黑客,使用函数和数据类型作为抽象的主要单位。当然,前者会给你带来麻烦;很难将函数序列化为 JSON。但是,您可以维护来自 ADT 的 map ,该 map 表示生物或方 block 的“类型”等,以及它的实际实现:
-- records containing functions to describe arbitrary behaviour; see FAQ entry
data BlockOps = BlockOps { ... }
data CreatureOps = CreatureOps { ... }
data Block = Block { ... }
data Creature = Creature { ... }
data Unit = BlockUnit Block | CreatureUnit Creature
newtype GameField = GameField (Map Point Unit)

-- these types are sent over the network, and mapped *back* to the "rich" but
-- non-transferable structures describing their behaviour; of course, this means
-- that BlockOps and CreatureOps must contain a BlockType/CreatureType to map
-- them back to this representation
data BlockType = Grass | Wood | ...
data CreatureType = ...
blockTypes :: Map BlockType BlockOps
creatureTypes :: Map CreatureType CreatureOps

这让您拥有典型 OOP 结构的所有可扩展性和不重复自己的性质,同时保持功能简单并允许简单的网络传输游戏状态。

通常,您应该避免考虑继承和其他 OOP 概念;相反,尝试从功能和更简单结构的组合来考虑动态行为。函数是函数式编程中最强大的工具,因此得名,它可以表示任何复杂的行为模式。最好不要让网络播放等要求影响您的基本设计;就像上面的例子一样,几乎总是可以将这些东西放在为表现力和简单性而构建的设计之上,而不是像通信格式这样的限制。

关于haskell - 如何在 Haskell 中建模 2D 世界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8904086/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com