如何在文本中表示和跟踪可变状态
这个问题是关于如何设计一个应用程序和布局数据,以在冒险游戏中表示可变状态,其中存在玩家可以进入的位置以及可以在这些位置或者在他们选择之后在玩家库存中的物品他们了。
newtype ItemName     = ItemName Text
newtype LocationName = LocationName Text
newtype Description  = Description Text
new type ItemWeight  = ItemWeight Int
data Location = Location LocationName Description [Item]
data Item     = Item ItemName [ItemName] Description ItemWeight
data Player   = Player PlayerPosition [Item]
data PlayerPosition = ...
  因为这是可变的,并且其他所有内容都是不可变的,所以每个Location都有一个Item列表可能没有意义。  对于Player 
在这样的游戏中,核心逻辑属于一个被称为的功能。
playMove :: Move -> GameState -> ([MoveResult], GameState)
  Move和MoveResult函数在哪里 
data Move                              data MoveResult
  = MoveTo Direction                     = EnteredLocation Location
  | PickUpItem ItemName                  | NoLocationAt Direction
  | UseItemWithItem ItemName ItemName    | PickedUpItem Item
  | Examine ItemName                     | UsedItemWithItem Item
  | Quit                                 | CantUseItems Item Item
                                         | NoSuchItem Item
                                         | Description Item
                                         | InventoryFull ItemWeight Item
                                         | GameWon
                                         | ...
  Move用户输入解析为Move值并输出MoveResult ,这是发生在IO monad中的事情。  方向只是North | South | East | West一个总和类型 North | South | East | West 
  其中大部分无疑会涉及一个捕获的GameState 
我的问题是
GameState数据结构是什么?  这样的结构应该包含玩家的位置和库存内容,以及在世界上可以找到的物品。  它应该像API一样提供API moveTo :: GameState -> Direction -> ([MoveResult], GameState) ,其中MoveResult是EnteredLocation或NoLocationAt 。  这又需要一个像locationAt :: Location -> Direction -> Maybe Location这样的函数 pickUp :: GameState -> ItemName -> ([MoveResult], GameState) ,其中MoveResult是PickedUpItem或NoSuchItem 。  在这种情况下,如何将ItemName与Item匹配 useItemWithItem :: GameState -> (ItemName, ItemName) -> ([MoveResult], GameState) ,其中MoveResult是PickedUpItem如果有新项目结果),否则为CantUserItems 。  这又需要像combineItems :: Item -> Item -> Maybe Item这样的函数来查看是否可以组合项目。 PlayerPosition Location类型还是引入一些LocationId来表示PlayerPosition和潜在的项目位置 Location到目的地Location经由Direction边缘,什么是最好的数据结构来使用。  我在想(Location, Direction)到Location的Data.Map 。   我知道拉链,以及playMove适合State monad的事实。  我的问题是如何构建GameState来捕获这个问题的可变和不可变的部分。 
编辑:答案
我确实从Reddit上的这个富有成效的讨论中找到了答案。 如果其他人发现这个问题,那么在讨论中/ u / achadoseperdidos指出我的问题的答案由Learn PureScript by Example的第11章提供,它实际上描述了如何使用RWS monad写一个冒险游戏 - 我正在寻找答案。
在这种规模下,您无需担心规模或效率。 只需使用如下记录:
import qualified Data.Map as M
data Location = Location
  { locationname :: String
  , description :: String
  } deriving Ord
data GameStep = GameStep
  { itemsWorld :: M.Map Location [Item]
  , inventory :: [Item]
  , position :: Location
  }
                        链接地址: http://www.djcxy.com/p/58769.html
                        上一篇: How to represent and track mutable state in a text
下一篇: STM with fclabels
