-
Notifications
You must be signed in to change notification settings - Fork 0
/
Input.fs
91 lines (79 loc) · 2.96 KB
/
Input.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
module Input
open System
open Compass
open Command
type IncompleteCommand =
| Open
| Close
| MindSwap
type CommandInput =
| IncompleteCommand of IncompleteCommand
| Command of Command
type private Character = char
type private Special = ConsoleKey * int
type private KeyboardInput =
| Character of Character
| Special of Special
let private keyboardInput (info: ConsoleKeyInfo) =
match info.KeyChar, info.Key with
| c, _ when Char.IsLetterOrDigit c || Char.IsSymbol c || Char.IsPunctuation c -> Character c
| _, key -> Special (key, int info.Modifiers)
let private tryLookup table key =
table
|> Map.tryFind key
let private tryLookupWithDefault table defaultValue key =
tryLookup table key
|> Option.defaultValue defaultValue
let private newCommandTable = Map [
Character 'o' , IncompleteCommand Open
Character 'c' , IncompleteCommand Close
Character 'm' , IncompleteCommand MindSwap
Character '.' , Command Wait
Character '?' , Command Help
Character 'q' , Command Quit
Character 's' , Command SaveGameCommand
Character 't' , Command ToggleTilesetCommand
Special (ConsoleKey.LeftArrow, 0) , Command (Move West)
Special (ConsoleKey.RightArrow, 0), Command (Move East)
Special (ConsoleKey.UpArrow, 0) , Command (Move North)
Special (ConsoleKey.DownArrow, 0) , Command (Move South)
]
let private getNewCommand() =
Console.ReadKey(true)
|> keyboardInput
|> tryLookup newCommandTable
let private directionCommandTable = Map [
Special (ConsoleKey.LeftArrow , 0), Some West
Special (ConsoleKey.RightArrow, 0), Some East
Special (ConsoleKey.UpArrow , 0), Some North
Special (ConsoleKey.DownArrow , 0), Some South
Special (ConsoleKey.Escape , 0), None
]
let rec private getDirectionOrCancel() =
Console.ReadKey(true)
|> keyboardInput
|> tryLookup directionCommandTable
|> function
| Some maybeDirection -> maybeDirection
| None -> getDirectionOrCancel()
let private completeDirectionalCommand command =
match getDirectionOrCancel() with
| Some direction -> command direction
| None -> Cancel
let rec getCommand messageWriter =
let command = getNewCommand()
match command with
| Some (Command c) ->
c
| Some (IncompleteCommand Open) ->
messageWriter "Open in which direction?"
completeDirectionalCommand OpenTo
| Some (IncompleteCommand Close) ->
messageWriter "Close in which direction?"
completeDirectionalCommand CloseTo
| Some (IncompleteCommand MindSwap) ->
messageWriter "Mind swap in which direction?"
completeDirectionalCommand MindSwapTo
| None ->
messageWriter "Unknown command, type ? for help."
getCommand messageWriter