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 并将其在内存中表示为一棵树,然后在树上执行查找。
什么关于变体,那么你应该用变体类型表示以下数据:
- 移动方向:
type dir = N | NE | E ...
- 动词
type verb = Go | Take of item | Drop of item
此外,为 room
和 items
创建一个抽象数据类型是个好主意,这将保证它们确实存在于 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
...
我正在尝试制作一个简单的天真的文字冒险游戏(基础 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 并将其在内存中表示为一棵树,然后在树上执行查找。
什么关于变体,那么你应该用变体类型表示以下数据:
- 移动方向:
type dir = N | NE | E ...
- 动词
type verb = Go | Take of item | Drop of item
此外,为 room
和 items
创建一个抽象数据类型是个好主意,这将保证它们确实存在于 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
...