Created
August 26, 2016 14:03
-
-
Save daviwil/3419811b3bfed172b7888efe2a0e1436 to your computer and use it in GitHub Desktop.
Source code from Episode 003 of the_dev_aspect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// --------- Model --------- | |
// | |
type Details = | |
{ Name: string | |
Description: string } | |
type Item = | |
{ Details: Details } | |
type RoomId = | |
| RoomId of string | |
type Exit = | |
| PassableExit of string * destination: RoomId | |
| LockedExit of string * key: Item * next: Exit | |
| NoExit of string option | |
type Exits = | |
{ North: Exit | |
South: Exit | |
East: Exit | |
West: Exit } | |
type Room = | |
{ Id: RoomId | |
Details: Details | |
Items: Item list | |
Exits: Exits } | |
type Player = | |
{ Details: Details | |
Location: RoomId | |
Inventory: Item list } | |
type World = | |
{ Rooms: Map<RoomId, Room> | |
Player: Player } | |
// --------- Initial World --------- | |
let key: Item = | |
{ Details = | |
{ Name = "A shiny key" | |
Description = "This key looks like it could open a nearby door."} } | |
let allRooms = [ | |
{ Id = RoomId "center" | |
Details = | |
{ Name = "A central room" | |
Description = "You are standing in a central room with exits in all directions. A single brazier lights the room."} | |
Items = [] | |
Exits = | |
{ North = PassableExit ("You see a darkened passageway to the north.", RoomId "north1") | |
South = PassableExit ("You see door to the south. A waft of cold air hits your face.", RoomId "south1") | |
East = LockedExit ("You see a locked door to the east.", key, PassableExit ("You see an open door to the east.", RoomId "east1")) | |
West = PassableExit ("You see an interesting room to the west.", RoomId "west1") }} | |
{ Id = RoomId "north1" | |
Details = | |
{ Name = "A dark room" | |
Description = "You are standing in a very dark room. You hear the faint sound of rats scurrying along the floor."} | |
Items = [] | |
Exits = | |
{ North = NoExit None | |
South = PassableExit ("You see an dimly lit room to the south.", RoomId "center") | |
East = NoExit None | |
West = NoExit None }} | |
{ Id = RoomId "south1" | |
Details = | |
{ Name = "A cold room" | |
Description = "You are standing in a room that feels very cold. Your breath instantly turns into a white puff."} | |
Items = [] | |
Exits = | |
{ North = PassableExit ("You see an exit to the north. That room looks much warmer.", RoomId "center") | |
South = NoExit None | |
East = NoExit None | |
West = NoExit None }} | |
{ Id = RoomId "west1" | |
Details = | |
{ Name = "A cozy room" | |
Description = "This room seems very cozy, as if someone had made a home here. Various personal belongings are strewn about."} | |
Items = [ key ] | |
Exits = | |
{ North = NoExit None | |
South = NoExit None | |
East = PassableExit ("You see a doorway back to the lit room.", RoomId "center") | |
West = NoExit None }} | |
{ Id = RoomId "east1" | |
Details = | |
{ Name = "An open meadow" | |
Description = "You are in an open meadow. The sun is bright and it takes some time for your eyes to adjust."} | |
Items = [] | |
Exits = | |
{ North = NoExit None | |
South = NoExit None | |
East = NoExit None | |
West = PassableExit ("You see stone doorway to the west. Why would you want to go back there?", RoomId "center") }} | |
] | |
let player = | |
{ Details = { Name = "Luke"; Description = "Just your average adventurer."} | |
Inventory = [] | |
Location = RoomId "center" } | |
let gameWorld = | |
{ Rooms = | |
allRooms | |
|> Seq.map (fun room -> (room.Id, room)) | |
|> Map.ofSeq | |
Player = player} | |
// | |
// --------- Logic --------- | |
// | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// --------- Model --------- | |
// | |
type Details = | |
{ Name: string | |
Description: string } | |
type Item = | |
{ Details: Details } | |
type RoomId = | |
| RoomId of string | |
type Exit = | |
| PassableExit of string * destination: RoomId | |
| LockedExit of string * key: Item * next: Exit | |
| NoExit of string option | |
type Exits = | |
{ North: Exit | |
South: Exit | |
East: Exit | |
West: Exit } | |
type Room = | |
{ Id: RoomId | |
Details: Details | |
Items: Item list | |
Exits: Exits } | |
type Player = | |
{ Details: Details | |
Location: RoomId | |
Inventory: Item list } | |
type World = | |
{ Rooms: Map<RoomId, Room> | |
Player: Player } | |
// --------- Initial World --------- | |
let key: Item = | |
{ Details = | |
{ Name = "A shiny key" | |
Description = "This key looks like it could open a nearby door."} } | |
let allRooms = [ | |
{ Id = RoomId "center" | |
Details = | |
{ Name = "A central room" | |
Description = "You are standing in a central room with exits in all directions. A single brazier lights the room."} | |
Items = [] | |
Exits = | |
{ North = PassableExit ("You see a darkened passageway to the north.", RoomId "north1") | |
South = PassableExit ("You see door to the south. A waft of cold air hits your face.", RoomId "south1") | |
East = LockedExit ("You see a locked door to the east.", key, PassableExit ("You see an open door to the east.", RoomId "east1")) | |
West = PassableExit ("You see an interesting room to the west.", RoomId "west1") }} | |
{ Id = RoomId "north1" | |
Details = | |
{ Name = "A dark room" | |
Description = "You are standing in a very dark room. You hear the faint sound of rats scurrying along the floor."} | |
Items = [] | |
Exits = | |
{ North = NoExit None | |
South = PassableExit ("You see an dimly lit room to the south.", RoomId "center") | |
East = NoExit None | |
West = NoExit None }} | |
{ Id = RoomId "south1" | |
Details = | |
{ Name = "A cold room" | |
Description = "You are standing in a room that feels very cold. Your breath instantly turns into a white puff."} | |
Items = [] | |
Exits = | |
{ North = PassableExit ("You see an exit to the north. That room looks much warmer.", RoomId "center") | |
South = NoExit None | |
East = NoExit None | |
West = NoExit None }} | |
{ Id = RoomId "west1" | |
Details = | |
{ Name = "A cozy room" | |
Description = "This room seems very cozy, as if someone had made a home here. Various personal belongings are strewn about."} | |
Items = [ key ] | |
Exits = | |
{ North = NoExit None | |
South = NoExit None | |
East = PassableExit ("You see a doorway back to the lit room.", RoomId "center") | |
West = NoExit None }} | |
{ Id = RoomId "east1" | |
Details = | |
{ Name = "An open meadow" | |
Description = "You are in an open meadow. The sun is bright and it takes some time for your eyes to adjust."} | |
Items = [] | |
Exits = | |
{ North = NoExit None | |
South = NoExit None | |
East = NoExit None | |
West = PassableExit ("You see stone doorway to the west. Why would you want to go back there?", RoomId "center") }} | |
] | |
let player = | |
{ Details = { Name = "Luke"; Description = "Just your average adventurer."} | |
Inventory = [] | |
Location = RoomId "center" } | |
let gameWorld = | |
{ Rooms = | |
allRooms | |
|> Seq.map (fun room -> (room.Id, room)) | |
|> Map.ofSeq | |
Player = player} | |
// | |
// --------- Logic --------- | |
// | |
type Result<'TSuccess, 'TFailure> = | |
| Success of 'TSuccess | |
| Failure of 'TFailure | |
let bind processFunc lastResult = | |
match lastResult with | |
| Success s -> processFunc s | |
| Failure f -> Failure f | |
let (>>=) x f = | |
bind f x | |
let switch processFunc input = | |
Success (processFunc input) | |
let getRoom world roomId = | |
match world.Rooms.TryFind roomId with | |
| Some room -> Success room | |
| None -> Failure "Room does not exist!" | |
let describeDetails details = | |
sprintf "\n\n%s\n\n%s\n\n" details.Name details.Description | |
let extractDetailsFromRoom (room: Room) = | |
room.Details | |
let describeCurrentRoom world = | |
world.Player.Location | |
|> getRoom world | |
|> (bind (switch extractDetailsFromRoom) >> bind (switch describeDetails)) | |
let north ({ North = northExit }: Exits) = northExit | |
let south ({ South = southExit }: Exits) = southExit | |
let east ({ East = eastExit }: Exits) = eastExit | |
let west ({ West = westExit }: Exits) = westExit | |
let getCurrentRoom world = | |
world.Player.Location | |
|> getRoom world | |
let setCurrentRoom world room = | |
{ world with | |
Player = { world.Player with Location = room.Id} } | |
let getExit direction exits = | |
match (direction exits) with | |
| PassableExit (_, roomId) -> Success roomId | |
| LockedExit (_, _, _) -> Failure "There is a locked door in that direction." | |
| NoExit (_) -> Failure "There is no room in that direction." | |
let move direction world = | |
world | |
|> getCurrentRoom | |
>>= switch (fun room -> room.Exits) | |
>>= getExit direction | |
>>= getRoom world | |
>>= switch (setCurrentRoom world) | |
let displayResult result = | |
match result with | |
| Success s -> printf "%s" s | |
| Failure f -> printf "%s" f | |
gameWorld | |
|> move south | |
|> bind (move north) | |
|> bind (move east) | |
|> bind describeCurrentRoom | |
|> displayResult |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment