齐天大圣
齐天大圣

Reputation: 1189

OCaml: design datatypes for a text adventure game

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?

Upvotes: 2

Views: 490

Answers (1)

ivg
ivg

Reputation: 35260

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:

  1. movement directions: type dir = N | NE | E ...
  2. verbs 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
...

Upvotes: 4

Related Questions