@@ -11,75 +11,181 @@ const move = ({
1111 y : 0 ,
1212 d : 90 // Default to facing east
1313 } ,
14- command
14+ waypoint = {
15+ x : 10 ,
16+ y : 1
17+ } ,
18+ command,
19+ mode = 'normal'
1520} ) => {
1621 // Movement subfunctions
1722 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+ }
3672 }
3773 } ,
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+ } )
65152 }
66153 }
67154 }
68155
69156 console . debug ( 'Received' , command , position )
70157 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+ }
73170}
74171
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
83189}
84190
85191module . exports = {
0 commit comments