Dememoised get-neighbours, as the optimisation only works in deep
recursion which I'm no longer doing.
This commit is contained in:
parent
5f73b18d12
commit
3c26408a9f
|
@ -1,4 +1,4 @@
|
||||||
;; Utility functions needed by MicroWorld and, specifically, in the
|
;; Utility functions needed by MicroWorld and, specifically, in the
|
||||||
;; interpretation of MicroWorld rule.
|
;; interpretation of MicroWorld rule.
|
||||||
|
|
||||||
(ns mw-engine.utils
|
(ns mw-engine.utils
|
||||||
|
@ -21,17 +21,17 @@
|
||||||
[elt col] (some #(= elt %) col))
|
[elt col] (some #(= elt %) col))
|
||||||
|
|
||||||
(defn get-int-or-zero
|
(defn get-int-or-zero
|
||||||
"Return the value of this `property` from this `map` if it is a integer;
|
"Return the value of this `property` from this `map` if it is a integer;
|
||||||
otherwise return zero."
|
otherwise return zero."
|
||||||
[map property]
|
[map property]
|
||||||
(let [value (map property)]
|
(let [value (map property)]
|
||||||
(if (integer? value) value 0)))
|
(if (integer? value) value 0)))
|
||||||
|
|
||||||
(defn init-generation
|
(defn init-generation
|
||||||
"Return a cell like this `cell`, but having a value for :generation, zero if
|
"Return a cell like this `cell`, but having a value for :generation, zero if
|
||||||
the cell passed had no integer value for generation, otherwise the value
|
the cell passed had no integer value for generation, otherwise the value
|
||||||
taken from the cell passed. The `world` argument is present only for
|
taken from the cell passed. The `world` argument is present only for
|
||||||
consistency with the rule engine and is ignored."
|
consistency with the rule engine and is ignored."
|
||||||
[world cell]
|
[world cell]
|
||||||
(merge cell {:generation (get-int-or-zero cell :generation)}))
|
(merge cell {:generation (get-int-or-zero cell :generation)}))
|
||||||
|
|
||||||
|
@ -124,7 +124,10 @@
|
||||||
(get-int cell species))
|
(get-int cell species))
|
||||||
|
|
||||||
(def memo-get-neighbours
|
(def memo-get-neighbours
|
||||||
"Memoised core primitive for `get-neighbours` for efficiency."
|
"Memoised get neighbours is more efficient when running deeply recursive
|
||||||
|
algorithms on the same world. But it's less efficient when running the
|
||||||
|
engine in its normal iterative style, because then we will rarely call
|
||||||
|
get naighbours on the same cell of the same world twice."
|
||||||
(memoize
|
(memoize
|
||||||
(fn [world x y depth]
|
(fn [world x y depth]
|
||||||
(remove nil?
|
(remove nil?
|
||||||
|
@ -135,28 +138,36 @@
|
||||||
(range (- y depth) (+ y depth 1)))))))))
|
(range (- y depth) (+ y depth 1)))))))))
|
||||||
|
|
||||||
(defn get-neighbours
|
(defn get-neighbours
|
||||||
"Get the neighbours to distance depth of the cell at x, y in this world.
|
"Get the neighbours to distance depth of a cell in this world.
|
||||||
|
|
||||||
|
Several overloads:
|
||||||
|
* `world` a world, as described in world.clj;
|
||||||
|
* `cell` a cell within that world
|
||||||
|
Gets immediate neighbours of the specified cell.
|
||||||
|
|
||||||
|
* `world` a world, as described in world.clj;
|
||||||
|
* `cell` a cell within that world
|
||||||
|
* `depth` an integer representing the depth to search from the
|
||||||
|
`cell`
|
||||||
|
Gets neighbours within the specified distance of the cell.
|
||||||
|
|
||||||
* `world` a world, as described in world.clj;
|
* `world` a world, as described in world.clj;
|
||||||
* `x` an integer representing an x coordinate in that world;
|
* `x` an integer representing an x coordinate in that world;
|
||||||
* `y` an integer representing an y coordinate in that world;
|
* `y` an integer representing an y coordinate in that world;
|
||||||
* `depth` an integer representing the distance from [x,y] that
|
* `depth` an integer representing the distance from [x,y] that
|
||||||
should be searched."
|
should be searched
|
||||||
|
Gets the neighbours within the specified distance of the cell at
|
||||||
|
coordinates [x,y] in this world."
|
||||||
([world x y depth]
|
([world x y depth]
|
||||||
(memo-get-neighbours world x y depth))
|
(remove nil?
|
||||||
|
(map #(get-cell world (first %) (first (rest %)))
|
||||||
|
(remove #(= % (list x y))
|
||||||
|
(combo/cartesian-product
|
||||||
|
(range (- x depth) (+ x depth 1))
|
||||||
|
(range (- y depth) (+ y depth 1)))))))
|
||||||
([world cell depth]
|
([world cell depth]
|
||||||
"Get the neighbours to distance depth of this cell in this world.
|
|
||||||
|
|
||||||
* `world` a world, as described in world.clj;
|
|
||||||
* `cell` a cell within that world;
|
|
||||||
* `depth` an integer representing the distance from [x,y] that
|
|
||||||
should be searched."
|
|
||||||
(memo-get-neighbours world (:x cell) (:y cell) depth))
|
(memo-get-neighbours world (:x cell) (:y cell) depth))
|
||||||
([world cell]
|
([world cell]
|
||||||
"Get the immediate neighbours of this cell in this world
|
|
||||||
|
|
||||||
* `world` a world, as described in world.clj;
|
|
||||||
* `cell` a cell within that world."
|
|
||||||
(get-neighbours world cell 1)))
|
(get-neighbours world cell 1)))
|
||||||
|
|
||||||
(defn get-neighbours-with-property-value
|
(defn get-neighbours-with-property-value
|
||||||
|
@ -166,10 +177,10 @@
|
||||||
* `world` a world, as described in `world.clj`;
|
* `world` a world, as described in `world.clj`;
|
||||||
* `cell` a cell within that world;
|
* `cell` a cell within that world;
|
||||||
* `depth` an integer representing the distance from [x,y] that
|
* `depth` an integer representing the distance from [x,y] that
|
||||||
should be searched;
|
should be searched (optional);
|
||||||
* `property` a keyword representing a property of the neighbours;
|
* `property` a keyword representing a property of the neighbours;
|
||||||
* `value` a value of that property (or, possibly, the name of another);
|
* `value` a value of that property (or, possibly, the name of another);
|
||||||
* `op` a comparator function to use in place of `=`.
|
* `op` a comparator function to use in place of `=` (optional).
|
||||||
|
|
||||||
It gets messy."
|
It gets messy."
|
||||||
([world x y depth property value op]
|
([world x y depth property value op]
|
||||||
|
@ -253,7 +264,7 @@
|
||||||
[world cell]
|
[world cell]
|
||||||
(if (in-bounds world (:x cell) (:y cell))
|
(if (in-bounds world (:x cell) (:y cell))
|
||||||
(map-world world
|
(map-world world
|
||||||
#(if
|
#(if
|
||||||
(and
|
(and
|
||||||
(= (:x cell)(:x %2))
|
(= (:x cell)(:x %2))
|
||||||
(= (:y cell)(:y %2)))
|
(= (:y cell)(:y %2)))
|
||||||
|
|
Loading…
Reference in a new issue