Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns codelesson.week3-1
- (:require [clojure.string])
- (:gen-class))
- (defn merge-with-padding [x y]
- " merge arrays x & y and padding the shorter of the two with nils "
- (let [cx (count x) cy (count y)]
- (if (not= cx cy)
- (if (< cx cy)
- (map #(vector %1 %2) (concat x (take (- cy cx) (repeat nil) )) y)
- (map #(vector %1 %2) x (concat y (take (- cx cy) (repeat nil) ))))
- (map #(vector %1 %2) x y))))
- (defn char-to-i [c]
- " cheezy character to int coverter "
- (- (int c) 48))
- (defn coord [thegrid x y]
- (let [gridy (dec (count thegrid))]
- ((thegrid (- gridy y)) x)))
- (defn get-rover-coords [rover-num]
- (println "Enter rover" rover-num " initial coords")
- (let [in (read-line)
- v (filter #(not= \space %) (vec in))] ; [\1 \2 \N]
- {:name (keyword (str rover-num)) :position [(char-to-i (first v)) (char-to-i (second v))] :facing (last v)}))
- (defn get-grid-size []
- (println "Enter the grid dimensions")
- (let [in (read-line)]
- [ (char-to-i (first in)) (char-to-i (last in)) ]))
- (defn get-rover-mvmt [rover-num]
- (println "Enter movement instructions for rover" rover-num)
- (read-line))
- (defn set-coord [thegrid rover contents]
- "returns grid with rover at it's :position"
- (let [gridy (dec (count thegrid)) x (first (:position rover)) y (last (:position rover))]
- (assoc-in thegrid [(- gridy y) x] contents)))
- ;(assoc-in thegrid (:position rover) rover))
- (defn create-grid [x y rover1 rover2]
- (let [row (vec (repeat (inc y) {}))
- grid (vec (repeat (inc x) row))
- grid (set-coord grid rover1 rover1)
- grid (set-coord grid rover2 rover2)]
- grid))
- (def turn-left {\E \N \N \W \W \S \S \E})
- (def turn-right {\E \S \S \W \W \N \N \E})
- (def turn {\L turn-left \R turn-right})
- (defn forward [x y facing rovername]
- "returns new {:position [x y] :facing facing} after moving forward 1-coordinate"
- (condp = facing
- \N {:position [x (inc y)] :facing facing :name rovername}
- \S {:position [x (dec y)] :facing facing :name rovername}
- \E {:position [(inc x) y] :facing facing :name rovername}
- \W {:position [(dec x) y] :facing facing :name rovername}
- nil))
- (defn rover-moved [rover move]
- " returns a new rover map after the move"
- (let [x (first (:position rover)) y (last (:position rover)) facing (:facing rover) rovername (:name rover)]
- (cond
- (or (= move \L) (= move \R)) {:position [x y] :facing ((turn move) facing) :name rovername}
- (= move \M) (forward x y facing rovername)
- (nil? move) rover
- :default (throw (do (println "Shouldn't hit this in rover-moved!"))))))
- (defn not-in-bounds? [rover grid]
- (let [x (first (:position rover)) y (last (:position rover))
- size-x (count grid) size-y (count (get grid 0))]
- (if (and (< x size-x) (< y size-y) (>= x 0) (>= y 0))
- false
- true)))
- (defn check-moves [r1new r2new grid]
- (cond
- (not-in-bounds? r1new @grid) [false "Rover 1 out of bounds!"]
- (not-in-bounds? r2new @grid) [false "Rover 2 out of bounds!"]
- (= (:position r1new) (:position r2new)) [false "Crash!!!!!!"]
- :default [true true]))
- (defn update-grid [grid r1 r1new r2 r2new]
- (dosync
- (send grid set-coord r1 {})
- (send grid set-coord r1new r1new)
- (send grid set-coord r2 {})
- (send grid set-coord r2new r2new)
- [r1new r2new]))
- (defn parse-move [state move grid]
- " returns [{rover1map} {rover2map} [grid]]"
- (let [r1move (first move)
- r2move (last move)
- r1 (first state)
- r2 (second state)
- r1new (rover-moved r1 r1move)
- r2new (rover-moved r2 r2move)
- validmove (check-moves r1new r2new grid)]
- (if (first validmove)
- (update-grid grid r1 r1new r2 r2new)
- validmove)))
- (defn showgrid [grid]
- (await grid)
- (doseq [row @grid]
- (prn row)))
- (defn spit-state [state grid]
- (let [rover1 (first state) rover2 (second state)]
- (println (first (:position rover1)) (last (:position rover1)) (:facing rover1))
- (println (first (:position rover2)) (last (:position rover2)) (:facing rover2))
- (showgrid grid)))
- (defn spit-error [grid error]
- (showgrid grid)
- (println error))
- (defn rove [grid-x grid-y rover1-initial-pos rover1-moves rover2-initial-pos rover2-moves]
- (let [ grid (agent (create-grid grid-x grid-y rover1-initial-pos rover2-initial-pos))]
- (loop [rover-state [rover1-initial-pos rover2-initial-pos ]
- current-move (first (merge-with-padding rover1-moves rover2-moves))
- moves (rest (merge-with-padding rover1-moves rover2-moves))]
- (if (and (not-empty current-move) (first rover-state))
- (recur (parse-move rover-state current-move grid) (first moves) (rest moves))
- (if (false? (first rover-state))
- (spit-error grid (last rover-state))
- (spit-state rover-state grid))))))
- (defn -main[] ; works with 'lein trampoline run'
- (let [grid-dims (get-grid-size)
- rover1-pos (get-rover-coords 1)
- rover1-mvmt (get-rover-mvmt 1)
- rover2-pos (get-rover-coords 2)
- rover2-mvmt (get-rover-mvmt 2)]
- (rove (first grid-dims) (last grid-dims) rover1-pos rover1-mvmt rover2-pos rover2-mvmt)))
- (rove 5 5 {:name :rover1 :position [1 2] :facing \N} "LMLMLMLMM" {:name :rover2 :position [3 3] :facing \E} "MMRMMRMRRM")
- (rove 3 3 {:name :rover1 :position [1 2] :facing \N} "LMLMLMLMM" {:name :rover2 :position [3 3] :facing \E} "MMRMMRMRRM") ; contrive out of bounds
- (rove 3 3 {:name :rover1 :position [2 0] :facing \N} "MMMMMMM" {:name :rover2 :position [0 2] :facing \E} "MMMMRRRM") ; contrive a crash!
Add Comment
Please, Sign In to add comment