diff --git a/src/mw_engine/core.clj b/src/mw_engine/core.clj index 771f355..b066fb3 100644 --- a/src/mw_engine/core.clj +++ b/src/mw_engine/core.clj @@ -2,7 +2,8 @@ (ns mw-engine.core (:use mw-engine.utils) - (:require [mw-engine.world :as world]) + (:require [clojure.core.reducers :as r] + [mw-engine.world :as world]) (:gen-class)) ;; Every rule is a function of two arguments, a cell and a world. If the rule @@ -79,16 +80,34 @@ these `:rules`. As a side effect, print the world." [state] (let [world (transform-world (:world state) (:rules state))] - (world/print-world world) + ;;(world/print-world world) {:world world :rules (:rules state)})) + (defn run-world "Run this world with these rules for this number of generations. * `world` a world as discussed above; * `init-rules` a sequence of rules as defined above, to be run once to initialise the world; - * `rules` a sequence of rules as definied above, to be run iteratively for each generation; - * `generations` an (integer) number of generations." - [world init-rules rules generations] + * `rules` a sequence of rules as defined above, to be run iteratively for each generation; + * `generations` an (integer) number of generations. + + Return the final generation of the world." + [world init-rules rules generations] (let [state {:world (transform-world world init-rules) :rules rules}] - (take generations (iterate transform-world-state state)))) + (:world + (last + (do-all + (take generations + (iterate transform-world-state state))))))) + +(defn run-world2 + "Doesn't work yet" + [world init-rules rules generations] + (with-local-vars [r (ref (transform-world world init-rules))] + (dotimes [g generations] + (dosync + (ref-set r (transform-world (deref r) rules)))) + (deref r))) + + diff --git a/src/mw_engine/utils.clj b/src/mw_engine/utils.clj index 3b73c3d..8c6fee5 100644 --- a/src/mw_engine/utils.clj +++ b/src/mw_engine/utils.clj @@ -1,7 +1,9 @@ ;; Utility functions needed by MicroWorld and, specifically, in the interpretation of MicroWorld rule. (ns mw-engine.utils - (:require [clojure.math.combinatorics :as combo])) + (:require + [clojure.core.reducers :as r] + [clojure.math.combinatorics :as combo])) (defn abs "Surprisingly, Clojure doesn't seem to have an abs function, or else I've @@ -34,11 +36,13 @@ ([world function] (map-world world function nil)) ([world function additional-args] - (apply vector ;; vectors are more efficient for scanning, which we do a lot. - (for [row world] - (apply vector - (map #(apply function (cons world (cons % additional-args))) - row)))))) + (into [] ;; vectors are more efficient for scanning, which we do a lot. + (r/map (fn [row] + (into [] (r/map + #(apply function + (cons world (cons % additional-args))) + row))) + world)))) (defn get-cell "Return the cell a x, y in this world, if any.