I am trying to make a simple naive text adventure game (base one this page) to learn OCaml.
The game is about making an game engine, so all the information about rooms, items ect, is store in a json file.
Sample json file would be like this:
{
"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"]
}
I've almost done the game, but on the project description page, it says two of the objectives are
- Design user-defined data types, especially records and variants.
- Write code that uses pattern matching and higher-order functions on lists and on trees.
However, the only user-defined datatype I made is a record type used to capture the current state of the game, I did not use tree and variant :
type state = {
current_inventory : string list ;
current_room : string ;
current_score : int ;
current_turn : int ;
}
then just parse user input and use pattern matching to handle different situations.
I'm been trying to figure out how should I use variant (or polymorphic variant) and tree in my game.
Can anyone please provide some suggestions?
The json
is inherently a tree. You may, of course just parse the json without having an in-memory representation and perform side-effectful computations as you descent though the json data to fill in hash tables with the data that you've read. This is a valid option, but it looks like that authors of the course expect, that you first read the entire json and represent it in memory as a tree, and then perform lookups on the tree.
What concerning variants, then you should represent with a variant type the following data:
type dir = N | NE | E ...
type verb = Go | Take of item | Drop of item
Also, it would be a good idea to create an abstract data types for room
and items
, that will guarantee that they are is actually present in the json
data bases. You're using string
to represent them. But this type includes all values, including those, that doesn't represent a valid identifiers, as well as those, that doesn't occur in the game description file. Inventory items are also deserve to get their own type.
In general in languages with rich type system, you should try to express as much as possible with the type system.
Just to be less theoretical, if I were you, then I will have the following types in my game (as a first approximation):
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
...