Mainly documentation tidy-up, a little code tidy-up.

This commit is contained in:
Simon Brooke 2014-07-08 19:15:07 +01:00
parent 1c0f6079d9
commit 57a86ca6c3
3 changed files with 31 additions and 41 deletions

View file

@ -9,6 +9,10 @@
;; fires, it returns a new cell, which should have the same values for :x and ;; fires, it returns a new cell, which should have the same values for :x and
;; :y as the old cell. Anything else can be modified. ;; :y as the old cell. Anything else can be modified.
;; ;;
;; While any function of two arguments can be used as a rule, a special high
;; level rule language is provided by the `mw-parser` package, which compiles
;; rules expressed in a subset of English rules into suitable functions.
;;
;; A cell is a map containing at least values for the keys :x, :y, and :state; ;; A cell is a map containing at least values for the keys :x, :y, and :state;
;; a transformation should not alter the values of :x or :y, and should not ;; a transformation should not alter the values of :x or :y, and should not
;; return a cell without a keyword as the value of :state. Anything else is ;; return a cell without a keyword as the value of :state. Anything else is
@ -18,7 +22,9 @@
;; that every cell's :x and :y properties reflect its place in the matrix. ;; that every cell's :x and :y properties reflect its place in the matrix.
;; See `world.clj`. ;; See `world.clj`.
;; ;;
;; Rules are applied in turn until one matches. ;; Each time the world is transformed (see `transform-world`, for each cell,
;; rules are applied in turn until one matches. Once one rule has matched no
;; further rules can be applied.
(defn- transform-cell (defn- transform-cell
"Derive a cell from this cell of this world by applying these rules." "Derive a cell from this cell of this world by applying these rules."
@ -60,17 +66,3 @@
[world init-rules rules generations] [world init-rules rules generations]
(let [state {:world (transform-world world init-rules) :rules rules}] (let [state {:world (transform-world world init-rules) :rules rules}]
(take generations (iterate transform-world-state state)))) (take generations (iterate transform-world-state state))))
;; (defn animate-world
;; "Run this world with these rules for this number of generations, and return nil
;; to avoid cluttering the screen. Principally for debugging.
;; * `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]
;; (let [state (list (transform-world world init-rules) rules)]
;; (dorun
;; (take generations (iterate transform-world-state state)))
;; state))

View file

@ -17,7 +17,7 @@
"Surprisingly, Clojure doesn't seem to have an abs function, or else I've "Surprisingly, Clojure doesn't seem to have an abs function, or else I've
missed it. So here's one of my own. Maps natural numbers onto themselves, missed it. So here's one of my own. Maps natural numbers onto themselves,
and negative integers onto natural numbers. Also maps negative real numbers and negative integers onto natural numbers. Also maps negative real numbers
onto positive real numbers, but I don't care so much about them. onto positive real numbers.
* `n` a number, on the set of real numbers." * `n` a number, on the set of real numbers."
[n] [n]
@ -25,8 +25,7 @@
(defn transform-altitude (defn transform-altitude
"Set the altitude of this cell from the corresponding pixel of this heightmap. "Set the altitude of this cell from the corresponding pixel of this heightmap.
If the heightmap you supply is smaller than the world, this will break and If the heightmap you supply is smaller than the world, this will break.
it's ALL YOUR FAULT.
* `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map; * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map;
* `heightmap` an (ideally) greyscale image, whose x and y dimensions should * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
@ -45,15 +44,14 @@
(defn- apply-heightmap-row (defn- apply-heightmap-row
"Set the altitude of each cell in this sequence from the corresponding pixel "Set the altitude of each cell in this sequence from the corresponding pixel
of this heightmap. of this heightmap.
If the heightmap you supply is smaller than the world, this will break and If the heightmap you supply is smaller than the world, this will break.
it's ALL YOUR FAULT.
* `row` a row in a world, as discussed in world.clj, q.v. Alternatively, a * `row` a row in a world, as discussed in world.clj, q.v. Alternatively, a
sequence of maps; sequence of maps;
* `heightmap` an (ideally) greyscale image, whose x and y dimensions should * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
exceed those of the world of which the `cell` forms part." exceed those of the world of which the `cell` forms part."
[row heightmap] [row heightmap]
(apply vector (map #(transform-altitude %1 heightmap) row))) (apply vector (map #(transform-altitude % heightmap) row)))
(defn apply-heightmap (defn apply-heightmap
"Apply the image file loaded from this path to this world, and return a world whose "Apply the image file loaded from this path to this world, and return a world whose
@ -65,4 +63,4 @@
[world imagepath] [world imagepath]
;; bizarrely, the collage load-util is working for me, but the imagez version isn't. ;; bizarrely, the collage load-util is working for me, but the imagez version isn't.
(let [heightmap (filter-image (grayscale)(load-image imagepath))] (let [heightmap (filter-image (grayscale)(load-image imagepath))]
(apply vector (map #(apply-heightmap-row %1 heightmap) world)))) (apply vector (map #(apply-heightmap-row % heightmap) world))))

View file

@ -51,7 +51,6 @@
(defn get-neighbours (defn get-neighbours
([world x y depth]
"Get the neighbours to distance depth of the cell at x, y in this world. "Get the neighbours to distance depth of the cell at x, y in this world.
* `world` a world, as described in world.clj; * `world` a world, as described in world.clj;
@ -59,26 +58,27 @@
* `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."
(remove nil? ([world x y depth]
(map #(get-cell world (first %) (first (rest %))) (remove nil?
(remove #(= % (list x y)) (map #(get-cell world (first %) (first (rest %)))
(combo/cartesian-product (remove #(= % (list x y))
(range (- x depth) (+ x depth 1)) (combo/cartesian-product
(range (- y depth) (+ y depth 1))))))) (range (- x depth) (+ x depth 1))
([world cell depth] (range (- y depth) (+ y depth 1)))))))
"Get the neighbours to distance depth of this cell in this world. ([world cell depth]
"Get the neighbours to distance depth of this cell in this world.
* `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."
(get-neighbours world (:x cell) (:y cell) depth)) (get-neighbours world (:x cell) (:y cell) depth))
([world cell] ([world cell]
"Get the immediate neighbours of this cell in this world "Get the immediate neighbours of this cell in this world
* `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."
(get-neighbours world cell 1))) (get-neighbours world cell 1)))
(defn get-neighbours-with-property-value (defn get-neighbours-with-property-value
"Get the neighbours to distance depth of the cell at x, y in this world which "Get the neighbours to distance depth of the cell at x, y in this world which