commit dc9088ffa50882ed4974ff0fb9fbc2875cc7b1f1
parent 8b638fcc187f9d3bf9d026ea9f339b6a62bbf3a1
Author: Daniel Barlow <dan@telent.net>
Date: Mon, 23 Jan 2023 22:17:58 +0000
implement collision detection
Diffstat:
| M | rover.fnl | | | 56 | ++++++++++++++++++++++++++++++++++---------------------- |
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/rover.fnl b/rover.fnl
@@ -1,21 +1,23 @@
(local { : view } (require :fennel))
-(local { : merge } (require :lume))
+(local { : merge : any } (require :lume))
(fn wrap-longitude [x]
(if (<= x -180) (wrap-longitude (+ x 360))
(< 180 x) (wrap-longitude (- x 360))
x))
-(fn drive [{: x : y : direction} distance]
- (let [distance
- (if (. {:w true :e true} direction)
- (/ distance (math.cos (/ (* math.pi y) 180)))
- distance)]
- (match direction
- :n {:y (+ y distance)}
- :s {:y (- y distance)}
- :w {:x (wrap-longitude (- x distance))}
- :e {:x (wrap-longitude (+ x distance))})))
+(fn drive [{: x : y : direction : stopped &as r} distance]
+ (if stopped
+ r
+ (let [distance
+ (if (. {:w true :e true} direction)
+ (/ distance (math.cos (/ (* math.pi y) 180)))
+ distance)]
+ (match direction
+ :n {:y (+ y distance)}
+ :s {:y (- y distance)}
+ :w {:x (wrap-longitude (- x distance))}
+ :e {:x (wrap-longitude (+ x distance))}))))
(fn turn-left [{: x : y : direction}]
(if (= y 90)
@@ -41,14 +43,22 @@
}
(. direction))}))
+(fn at-obstacle? [{: x : y : obstacles}]
+ (any obstacles
+ (fn [[ox oy]] (and (= ox x) (= oy y)))))
+
(fn command [rover string]
- (merge rover
- (match string
- :f (drive rover 1)
- :b (drive rover -1)
- :r (turn-right rover)
- :l (turn-left rover)
- _ (assert false (. "unrecognised command " string)))))
+ (let [next-move
+ (merge rover
+ (match string
+ :f (drive rover 1)
+ :b (drive rover -1)
+ :r (turn-right rover)
+ :l (turn-left rover)
+ _ (assert false (. "unrecognised command " string))))]
+ (if (at-obstacle? next-move)
+ (merge rover {:stopped true})
+ next-move)))
(fn fudge-for-pole [{: y &as r}]
(if (= y 90)
@@ -62,10 +72,11 @@
_ c (ipairs cmds)]
(merge rover (fudge-for-pole (command rover c)))))
-(fn rover [x y direction]
+(fn rover [x y direction ?obstacles]
{: x
: y
: direction
+ :obstacles (or ?obstacles [])
})
;;;; TESTS
@@ -179,9 +190,10 @@
(execute (rover 0 89 :n) [:f :r])
{:x 90 :y 90 :direction :s})
-(expect "Near the North Pole, I can travel 90 degree in three steps"
- (execute (rover 0 89 :n) [:f :r :f])
- {:x 90 :y 89 :direction :s})
+(expect "It does not move past obstacles"
+ (let [obstacles [[5 5] [7 5]]]
+ (execute (rover 5 3 :n obstacles) [:f :f :f :f :f :f]))
+ {:x 5 :y 4 :direction :n :stopped true})
;; "TODO: deal with the south pole special casing"