-
Notifications
You must be signed in to change notification settings - Fork 18
/
09-BatchCommands.fsx
151 lines (119 loc) · 3.84 KB
/
09-BatchCommands.fsx
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(* ======================================
09-BatchCommands.fsx
Part of "Thirteen ways of looking at a turtle"
Related blog post: http://fsharpforfunandprofit.com/posts/13-ways-of-looking-at-a-turtle/
======================================
Way #9: Batch oriented -- Using a list of commands
In this design, the client creates a list of `Command`s that will be intepreted later.
These commands are then run in sequence using the Turtle library functions.
This approach means that there is no state that needs to be persisted between calls by the client.
====================================== *)
#load "Common.fsx"
#load "FPTurtleLib.fsx"
open Common
// ======================================
// TurtleCommmandHandler
// ======================================
module TurtleCommmandHandler =
open FPTurtleLib
/// Function to log a message
let log message =
printfn "%s" message
// logged versions
let move = Turtle.move log
let turn = Turtle.turn log
let penDown = Turtle.penDown log
let penUp = Turtle.penUp log
let setColor = Turtle.setColor log
type TurtleCommand =
| Move of Distance
| Turn of Angle
| PenUp
| PenDown
| SetColor of PenColor
// --------------------------------------
// The Command Handler
// --------------------------------------
/// Apply a command to the turtle state and return the new state
let applyCommand state command =
match command with
| Move distance ->
move distance state
| Turn angle ->
turn angle state
| PenUp ->
penUp state
| PenDown ->
penDown state
| SetColor color ->
setColor color state
/// Run list of commands in one go
let run aListOfCommands =
aListOfCommands
|> List.fold applyCommand Turtle.initialTurtleState
// ======================================
// TurtleCommmandHandler
// ======================================
module TurtleCommmandClient =
open TurtleCommmandHandler
let drawTriangle() =
// create the list of commands
let commands = [
Move 100.0
Turn 120.0<Degrees>
Move 100.0
Turn 120.0<Degrees>
Move 100.0
Turn 120.0<Degrees>
]
// run them
run commands
let drawThreeLines() =
// create the list of commands
let commands = [
// draw black line
PenDown
SetColor Black
Move 100.0
// move without drawing
PenUp
Turn 90.0<Degrees>
Move 100.0
Turn 90.0<Degrees>
// draw red line
PenDown
SetColor Red
Move 100.0
// move without drawing
PenUp
Turn 90.0<Degrees>
Move 100.0
Turn 90.0<Degrees>
// back home at (0,0) with angle 0
// draw diagonal blue line
PenDown
SetColor Blue
Turn 45.0<Degrees>
Move 100.0
]
// run the commands
run commands
let drawPolygon n =
let angle = 180.0 - (360.0/float n)
let angleDegrees = angle * 1.0<Degrees>
// define a function that draws one side
let drawOneSide sideNumber = [
Move 100.0
Turn angleDegrees
]
// repeat for all sides
let commands =
[1..n] |> List.collect drawOneSide
// run the commands
run commands
// ======================================
// TurtleCommmandClient Tests
// ======================================
TurtleCommmandClient.drawTriangle()
TurtleCommmandClient.drawThreeLines() // Doesn't go back home
TurtleCommmandClient.drawPolygon 4