implement collision detection

main
Daniel Barlow 2023-01-23 22:17:58 +00:00
parent 8b638fcc18
commit dc9088ffa5
1 changed files with 34 additions and 22 deletions

View File

@ -1,21 +1,23 @@
(local { : view } (require :fennel)) (local { : view } (require :fennel))
(local { : merge } (require :lume)) (local { : merge : any } (require :lume))
(fn wrap-longitude [x] (fn wrap-longitude [x]
(if (<= x -180) (wrap-longitude (+ x 360)) (if (<= x -180) (wrap-longitude (+ x 360))
(< 180 x) (wrap-longitude (- x 360)) (< 180 x) (wrap-longitude (- x 360))
x)) x))
(fn drive [{: x : y : direction} distance] (fn drive [{: x : y : direction : stopped &as r} distance]
(let [distance (if stopped
(if (. {:w true :e true} direction) r
(/ distance (math.cos (/ (* math.pi y) 180))) (let [distance
distance)] (if (. {:w true :e true} direction)
(match direction (/ distance (math.cos (/ (* math.pi y) 180)))
:n {:y (+ y distance)} distance)]
:s {:y (- y distance)} (match direction
:w {:x (wrap-longitude (- x distance))} :n {:y (+ y distance)}
:e {:x (wrap-longitude (+ x distance))}))) :s {:y (- y distance)}
:w {:x (wrap-longitude (- x distance))}
:e {:x (wrap-longitude (+ x distance))}))))
(fn turn-left [{: x : y : direction}] (fn turn-left [{: x : y : direction}]
(if (= y 90) (if (= y 90)
@ -41,14 +43,22 @@
} }
(. direction))})) (. direction))}))
(fn at-obstacle? [{: x : y : obstacles}]
(any obstacles
(fn [[ox oy]] (and (= ox x) (= oy y)))))
(fn command [rover string] (fn command [rover string]
(merge rover (let [next-move
(match string (merge rover
:f (drive rover 1) (match string
:b (drive rover -1) :f (drive rover 1)
:r (turn-right rover) :b (drive rover -1)
:l (turn-left rover) :r (turn-right rover)
_ (assert false (. "unrecognised command " string))))) :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}] (fn fudge-for-pole [{: y &as r}]
(if (= y 90) (if (= y 90)
@ -62,10 +72,11 @@
_ c (ipairs cmds)] _ c (ipairs cmds)]
(merge rover (fudge-for-pole (command rover c))))) (merge rover (fudge-for-pole (command rover c)))))
(fn rover [x y direction] (fn rover [x y direction ?obstacles]
{: x {: x
: y : y
: direction : direction
:obstacles (or ?obstacles [])
}) })
;;;; TESTS ;;;; TESTS
@ -179,9 +190,10 @@
(execute (rover 0 89 :n) [:f :r]) (execute (rover 0 89 :n) [:f :r])
{:x 90 :y 90 :direction :s}) {:x 90 :y 90 :direction :s})
(expect "Near the North Pole, I can travel 90 degree in three steps" (expect "It does not move past obstacles"
(execute (rover 0 89 :n) [:f :r :f]) (let [obstacles [[5 5] [7 5]]]
{:x 90 :y 89 :direction :s}) (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" ;; "TODO: deal with the south pole special casing"