Mercurial > rlm
diff src/rlm/light_bot.clj @ 0:78a630e650d2
initial import
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 18 Oct 2011 00:57:08 -0700 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/rlm/light_bot.clj Tue Oct 18 00:57:08 2011 -0700 1.3 @@ -0,0 +1,175 @@ 1.4 +(ns rlm.light-bot 1.5 + (:refer-clojure :only []) 1.6 + (:require rlm.ns-rlm mobius.base)) 1.7 +(rlm.ns-rlm/ns-clone mobius.base) 1.8 +;(use 'clojure.contrib.combinatorics) 1.9 +(use 'sunil.curry) 1.10 + 1.11 + 1.12 +{:loc '[x y] 1.13 + :rot '[c]} 1.14 + 1.15 +(defrecord tile [height lit?]) 1.16 + 1.17 + 1.18 + 1.19 + 1.20 + 1.21 +;;; Robot Actions 1.22 +(def cycle-right 1.23 + {:N :E 1.24 + :E :S 1.25 + :S :W 1.26 + :W :N}) 1.27 +(def cycle-left 1.28 + {:N :W 1.29 + :W :S 1.30 + :S :E 1.31 + :E :N}) 1.32 + 1.33 +(defn turn-left [game] 1.34 + (update-in game [:pos :rot] cycle-left)) 1.35 + 1.36 +(defn turn-right [game] 1.37 + (update-in game [:pos :rot] cycle-right)) 1.38 + 1.39 +(def light* {nil nil 1.40 + true false 1.41 + false true}) 1.42 + 1.43 +(defn light [{:keys [map pos] :as game}] 1.44 + (update-in game [:map (:loc pos) :lit?] light*)) 1.45 + 1.46 +(def move 1.47 + {:N [0,1] 1.48 + :E [1,0] 1.49 + :S [0,-1] 1.50 + :W [-1,0]}) 1.51 + 1.52 +(defn-decorated 1.53 + advance 1.54 + [(curry 2)] 1.55 + [action {:keys [pos] :as game}] 1.56 + (let [proposed (vec (map + (move (:rot pos)) (:loc pos)))] 1.57 + (if (get (:map game) proposed false) 1.58 + (assoc-in game [:pos :loc] (action proposed game)) 1.59 + game))) 1.60 + 1.61 +(defn jump-gaurd [proposed {:keys [pos] :as game}] 1.62 + (if (= (.height ((:map game) proposed)) (inc (.height ((:map game) (:loc pos))))) 1.63 + proposed 1.64 + (:loc pos))) 1.65 +(def jump (advance jump-gaurd)) 1.66 + 1.67 +(defn forward-gaurd [proposed {:keys [map pos] :as game}] 1.68 + (if (= (.height ((:map game) proposed)) (.height ((:map game) (:loc pos)))) 1.69 + proposed 1.70 + (:loc pos))) 1.71 +(def forward (advance forward-gaurd));;heehee :) 1.72 + 1.73 + 1.74 +(declare commands) 1.75 + 1.76 +(defn expand [game moves] 1.77 + (reduce (fn [game move] ((commands move) game)) game moves)) 1.78 + 1.79 +(defn function-1 [{{f1 :f1} :stragety :as game}] 1.80 + (expand game f1)) 1.81 + 1.82 +(defn function-2 [{{f2 :f2} :stragety :as game}] 1.83 + (expand game f2)) 1.84 + 1.85 + 1.86 + 1.87 +(defn all-lit? [game] 1.88 + (not (some false? (map #(.lit? %) (vals (:map game)))))) 1.89 + 1.90 + 1.91 +(defn solves? [game] 1.92 + (all-lit? (expand game (:main (:stragety game))))) 1.93 + 1.94 + 1.95 + 1.96 +(def commands 1.97 + {:jump jump 1.98 + :light light 1.99 + :turn-left turn-left 1.100 + :turn-right turn-right 1.101 + :function-1 function-1 1.102 + :function-2 function-2 1.103 + :forward forward}) 1.104 + 1.105 + 1.106 +;;; End game implementation 1.107 + 1.108 + 1.109 + 1.110 + 1.111 +;;; Find linear solutions 1.112 + 1.113 +(def naturals (iterate inc 1)) 1.114 + 1.115 +(defvar linear-commands 1.116 + (remove #(or (= % :function-2) (= % :function-1)) (keys commands)) 1.117 + "all the commands ignoring function calls. Branching factor 5.") 1.118 + 1.119 +(decorate selections (curry 2)) 1.120 +(defn breadth-first 1.121 + "iterate through the search space in breadth-first-order" 1.122 + [coll] 1.123 + (mapcat (selections coll) naturals)) 1.124 + 1.125 +(defn solutions 1.126 + "find solutions via breadth first search and returns as a lazy seq" 1.127 + [{level-map :map init-pos :pos :as level}] 1.128 + (filter #(solves? (assoc-in level [:stragety :main] %)) (breadth-first linear-commands))) 1.129 + 1.130 +;;(decorate selections [(curry 2) memoize]) 1.131 + 1.132 + 1.133 + 1.134 + 1.135 + 1.136 + 1.137 + 1.138 + 1.139 + 1.140 + 1.141 + 1.142 +;;; 1.143 + 1.144 + 1.145 + 1.146 + 1.147 + 1.148 + 1.149 + 1.150 + 1.151 + 1.152 + 1.153 +;;;Level One 1.154 +(defn level-one-gen [[x y]] 1.155 + (cond (= x 0) (tile. 2 nil) 1.156 + (= x 7) (tile. 2 nil) 1.157 + (= [x y] [3 4]) (tile. 0 false) 1.158 + true (tile. 0 nil))) 1.159 + 1.160 +(def level-one-map 1.161 + (let [domain (selections (range 8) 2)] 1.162 + (zipmap (map vec domain) (map level-one-gen domain)))) 1.163 + 1.164 +(def level-one-solution 1.165 + {:main [:forward :forward :light] 1.166 + :f1 [] 1.167 + :f2 []}) 1.168 + 1.169 +(def level-one-init-pos {:loc [3 2] :rot :N}) 1.170 +(def game-1 1.171 + {:map level-one-map 1.172 + :stragety level-one-solution 1.173 + :pos level-one-init-pos}) 1.174 + 1.175 +(def level-1 {:map level-one-map 1.176 + :pos level-one-init-pos}) 1.177 + 1.178 +