From dc9088ffa50882ed4974ff0fb9fbc2875cc7b1f1 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Mon, 23 Jan 2023 22:17:58 +0000 Subject: [PATCH] implement collision detection --- rover.fnl | 56 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/rover.fnl b/rover.fnl index 822cc4c..9225d7e 100644 --- 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"