@@ -11,75 +11,181 @@ const move = ({
11
11
y : 0 ,
12
12
d : 90 // Default to facing east
13
13
} ,
14
- command
14
+ waypoint = {
15
+ x : 10 ,
16
+ y : 1
17
+ } ,
18
+ command,
19
+ mode = 'normal'
15
20
} ) => {
16
21
// Movement subfunctions
17
22
const mv = {
18
- N : ( u ) => { // North
19
- position . y += u
20
- } ,
21
- S : ( u ) => { // South
22
- position . y -= u
23
- } ,
24
- E : ( u ) => { // East
25
- position . x += u
26
- } ,
27
- W : ( u ) => { // West
28
- position . x -= u
29
- } ,
30
- L : ( u ) => { // Turn Left
31
- position . d -= u
32
- position . d = position . d % 360
33
- // prevent negative angles
34
- if ( position . d < 0 ) {
35
- position . d += 360
23
+ normal : {
24
+ N : ( u ) => { // North
25
+ position . y += u
26
+ } ,
27
+ S : ( u ) => { // South
28
+ position . y -= u
29
+ } ,
30
+ E : ( u ) => { // East
31
+ position . x += u
32
+ } ,
33
+ W : ( u ) => { // West
34
+ position . x -= u
35
+ } ,
36
+ L : ( u ) => { // Turn Left
37
+ position . d -= u
38
+ position . d = position . d % 360
39
+ // prevent negative angles
40
+ if ( position . d < 0 ) {
41
+ position . d += 360
42
+ }
43
+ } ,
44
+ R : ( u ) => { // Turn Right
45
+ position . d += u
46
+ position . d = position . d % 360
47
+ // prevent negative angles
48
+ if ( position . d < 0 ) {
49
+ position . d += 360
50
+ }
51
+ } ,
52
+ F : ( u ) => { // Forward
53
+ // TODO: replace with vector positioning of arbitrary angles
54
+ switch ( position . d ) {
55
+ case 0 :
56
+ mv [ mode ] . N ( u )
57
+ break
58
+ case 90 :
59
+ mv [ mode ] . E ( u )
60
+ break
61
+ case 180 :
62
+ mv [ mode ] . S ( u )
63
+ break
64
+ case 270 :
65
+ mv [ mode ] . W ( u )
66
+ break
67
+ default :
68
+ console . debug ( 'Position' , position )
69
+ console . debug ( 'Forward' , u )
70
+ throw new Error ( 'Non-cardinal compass direction' )
71
+ }
36
72
}
37
73
} ,
38
- R : ( u ) => { // Turn Right
39
- position . d += u
40
- position . d = position . d % 360
41
- // prevent negative angles
42
- if ( position . d < 0 ) {
43
- position . d += 360
44
- }
45
- } ,
46
- F : ( u ) => { // Forward
47
- // TODO: replace with vector positioning of arbitrary angles
48
- switch ( position . d ) {
49
- case 0 :
50
- mv . N ( u )
51
- break
52
- case 90 :
53
- mv . E ( u )
54
- break
55
- case 180 :
56
- mv . S ( u )
57
- break
58
- case 270 :
59
- mv . W ( u )
60
- break
61
- default :
62
- console . debug ( 'Position' , position )
63
- console . debug ( 'Forward' , u )
64
- throw new Error ( 'Non-cardinal compass direction' )
74
+ waypoint : {
75
+ N : ( u ) => { // Waypoint North
76
+ waypoint . y += u
77
+ } ,
78
+ S : ( u ) => { // Waypoint South
79
+ waypoint . y -= u
80
+ } ,
81
+ E : ( u ) => { // Waypoint East
82
+ waypoint . x += u
83
+ } ,
84
+ W : ( u ) => { // Waypoint West
85
+ waypoint . x -= u
86
+ } ,
87
+ L : ( u ) => { // Waypoint Turn Left
88
+ // Luckily we can be lazy and not involve trig since all the rotations
89
+ // are multiples of 90 degrees
90
+
91
+ // Rotate around an origin since it's easier
92
+ let oldWaypoint = {
93
+ x : waypoint . x - position . x ,
94
+ y : waypoint . y - position . y
95
+ }
96
+ let tmpWaypoint = { }
97
+ // Figure out the number of quarter-turns
98
+ const qtr = u / 90
99
+ // Rotate each quarter turn
100
+ for ( let r = 1 ; r <= qtr ; r ++ ) {
101
+ tmpWaypoint = {
102
+ x : oldWaypoint . y * - 1 ,
103
+ y : oldWaypoint . x
104
+ }
105
+ // Prep for next rotation
106
+ oldWaypoint = JSON . parse ( JSON . stringify ( tmpWaypoint ) )
107
+ }
108
+ // Update the waypoint with the new position
109
+ Object . assign ( waypoint , {
110
+ x : position . x + tmpWaypoint . x ,
111
+ y : position . y + tmpWaypoint . y
112
+ } )
113
+ } ,
114
+ R : ( u ) => { // Waypoint Turn Right
115
+ // Rotate around an origin since it's easier
116
+ let oldWaypoint = {
117
+ x : waypoint . x - position . x ,
118
+ y : waypoint . y - position . y
119
+ }
120
+ let tmpWaypoint = { }
121
+ // Figure out the number of quarter-turns
122
+ const qtr = u / 90
123
+ // Rotate each quarter turn
124
+ for ( let r = 1 ; r <= qtr ; r ++ ) {
125
+ tmpWaypoint = {
126
+ x : oldWaypoint . y ,
127
+ y : oldWaypoint . x * - 1
128
+ }
129
+ // Prep for next rotation
130
+ oldWaypoint = JSON . parse ( JSON . stringify ( tmpWaypoint ) )
131
+ }
132
+ // Update the waypoint with the new position
133
+ Object . assign ( waypoint , {
134
+ x : position . x + tmpWaypoint . x ,
135
+ y : position . y + tmpWaypoint . y
136
+ } )
137
+ } ,
138
+ F : ( u ) => { // Forward
139
+ const distance = {
140
+ x : waypoint . x - position . x ,
141
+ y : waypoint . y - position . y
142
+ }
143
+
144
+ Object . assign ( position , {
145
+ x : position . x + ( distance . x * u ) ,
146
+ y : position . y + ( distance . y * u )
147
+ } )
148
+ Object . assign ( waypoint , {
149
+ x : waypoint . x + ( distance . x * u ) ,
150
+ y : waypoint . y + ( distance . y * u )
151
+ } )
65
152
}
66
153
}
67
154
}
68
155
69
156
console . debug ( 'Received' , command , position )
70
157
const operation = parseCommand ( command )
71
- mv [ operation . cmd ] ( operation . unit )
72
- return position
158
+ mv [ mode ] [ operation . cmd ] ( operation . unit )
159
+
160
+ if ( mode === 'normal' ) {
161
+ return position
162
+ }
163
+ console . debug ( '-------------------' )
164
+ console . debug ( 'position:' , position )
165
+ console . debug ( 'waypoint:' , waypoint )
166
+ return {
167
+ position,
168
+ waypoint
169
+ }
73
170
}
74
171
75
- const route = ( { instructions } ) => {
76
- return instructions . reduce (
77
- ( position , command ) => {
78
- console . debug ( 'Routing position' , position )
79
- console . debug ( 'Routing command' , command )
80
- return move ( { position, command } )
81
- } , { x : 0 , y : 0 , d : 90 }
82
- )
172
+ const route = ( { instructions, mode } ) => {
173
+ let position = { x : 0 , y : 0 , d : 90 }
174
+ let waypoint = { x : 10 , y : 1 }
175
+ instructions . forEach ( ( command ) => {
176
+ console . debug ( 'Routing position' , position )
177
+ console . debug ( 'Routing command' , command )
178
+ console . debug ( 'Routing method' , mode )
179
+ if ( mode === 'waypoint' ) {
180
+ const tmp = move ( { position, waypoint, command, mode } )
181
+ position = tmp . position
182
+ waypoint = tmp . waypoint
183
+ } else {
184
+ position = move ( { position, command, mode } )
185
+ }
186
+ } )
187
+
188
+ return position
83
189
}
84
190
85
191
module . exports = {
0 commit comments