OCaml:为文本冒险游戏设计数据类型

OCaml: design datatypes for a text adventure game

我正在尝试制作一个简单的天真的文字冒险游戏(基础 this page)来学习 OCaml。

该游戏是关于制作游戏引擎的,因此有关房间、物品等的所有信息都存储在 json 文件中。

示例 json 文件如下所示:

{
  "rooms":
  [
    {
      "id": "room1",
      "description": "This is Room 1.  There is an exit to the north.\nYou should drop the white hat here.",
      "items": ["black hat"],
      "points": 10,
      "exits": [
        {
          "direction": "north",
          "room": "room2"
        }
      ],
      "treasure": ["white hat"]
    },
    {
      "id": "room2",
      "description": "This is Room 2.  There is an exit to the south.\nYou should drop the black hat here.",
      "items": [],
      "points": 10,
      "exits": [
        {
          "direction": "south",
          "room": "room1"
        }
      ],
      "treasure": ["black hat"]
    }
  ],
  "start_room": "room1",
  "items":
  [
    {
      "id": "black hat",
      "description": "A black fedora",
      "points": 100
    },
    {
      "id": "white hat",
      "description": "A white panama",
      "points": 100
    }
  ],
  "start_items": ["white hat"]
}

我快完成游戏了,但是在项目描述页面上,它说其中两个目标是

  • Design user-defined data types, especially records and variants.
  • Write code that uses pattern matching and higher-order functions on lists and on trees.

然而,我制作的唯一用户自定义数据类型是一个记录类型,用于捕获游戏的当前状态,我没有使用树和变体:

type state = {
  current_inventory : string list ;
  current_room      : string ;
  current_score     : int ;
  current_turn      : int ;
}

然后只需解析用户输入并使用模式匹配来处理不同的情况。

我一直在想如何在游戏中使用 variant(或多态变体)tree

谁能提供一些建议吗?

json本质上是一棵树。当然,您可以在没有内存表示的情况下解析 json,并在通过 json 数据下降时执行副作用计算,以用您读取的数据填充哈希表.这是一个有效的选项,但看起来本课程的作者希望您首先阅读整个 json 并将其在内存中表示为一棵树,然后在树上执行查找。

什么关于变体,那么你应该用变体类型表示以下数据:

  1. 移动方向:type dir = N | NE | E ...
  2. 动词type verb = Go | Take of item | Drop of item

此外,为 roomitems 创建一个抽象数据类型是个好主意,这将保证它们确实存在于 json 数据库中.您正在使用 string 来代表他们。但是这种类型包括所有值,包括那些不代表有效标识符的值,以及那些没有出现在游戏描述文件中的值。库存物品也值得拥有自己的类型。

一般在类型系统丰富的语言中,尽量用类型系统来表达。

只是为了减少理论性,如果我是你,那么我的游戏中将有以下类型(作为第一个近似值):

type game
type room
type item
type verb 
type dir
type treasure
type state

(** a static representation of a game (using a tree inside) *)
module Game : sig 
  type t = game
  val from_json : string -> t option
  val start : t -> room
  val room_exits : t -> room -> (dir * room) list
end

module Room : sig
  type t = room
  val description : t -> string
  val items : t -> item list
  val points : t -> int
  val treasure : t -> treasure list
end
...