Minor changes
This commit is contained in:
parent
977947d4b0
commit
0dc6aab59d
|
@ -1,5 +1,5 @@
|
|||
(defproject mw-engine "0.1.0-SNAPSHOT"
|
||||
:description "FIXME: write description"
|
||||
:description "Cellular automaton world builder."
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns mw-engine.core
|
||||
(:use mw-engine.world
|
||||
(:require mw-engine.world
|
||||
mw-engine.natural-rules
|
||||
mw-engine.utils))
|
||||
|
||||
;; every rule is a function of two arguments, a cell and a world. If the rule
|
||||
|
@ -8,60 +9,6 @@
|
|||
;;
|
||||
;; Rules are applied in turn until one matches.
|
||||
|
||||
|
||||
(def treeline 10)
|
||||
|
||||
(def natural-rules
|
||||
(list
|
||||
;; Randomly, birds plant tree seeds into pasture.
|
||||
(fn [cell world] (cond (and (= (:state cell) :pasture)(< (rand 10) 1))(merge cell {:state :scrub})))
|
||||
;; Scrub below the treeline grows gradually into forest
|
||||
(fn [cell world]
|
||||
(cond (and
|
||||
(= (:state cell) :scrub)
|
||||
(< (:altitude cell) treeline))
|
||||
(merge cell {:state :scrub2})))
|
||||
(fn [cell world] (cond (= (:state cell) :scrub2) (merge cell {:state :forest})))
|
||||
;; Forest on fertile land at low altitude grows to climax
|
||||
(fn [cell world]
|
||||
(cond
|
||||
(and
|
||||
(= (:state cell) :forest)
|
||||
(> (:fertility cell) 10))
|
||||
(merge cell {:state :climax})))
|
||||
;; Climax forest occasionally catches fire (e.g. lightning strikes)
|
||||
(fn [cell world] (cond (and (= (:state cell) :climax)(< (rand 10) 1)) (merge cell {:state :fire})))
|
||||
;; Climax forest neighbouring fires is likely to catch fire
|
||||
(fn [cell world]
|
||||
(cond
|
||||
(and (= (:state cell) :climax)
|
||||
(< (rand 3) 1)
|
||||
(not (empty? (get-neighbours-with-state world (:x cell) (:y cell) 1 :fire))))
|
||||
(merge cell {:state :fire})))
|
||||
;; After fire we get waste
|
||||
(fn [cell world] (cond (= (:state cell) :fire) (merge cell {:state :waste})))
|
||||
;; And after waste we get pioneer species; if there's a woodland seed
|
||||
;; source, it's going to be scrub, otherwise grassland.
|
||||
(fn [cell world]
|
||||
(cond
|
||||
(and (= (:state cell) :waste)
|
||||
(not
|
||||
(empty?
|
||||
(flatten
|
||||
(list
|
||||
(get-neighbours-with-state world (:x cell) (:y cell) 1 :scrub2)
|
||||
(get-neighbours-with-state world (:x cell) (:y cell) 1 :forest)
|
||||
(get-neighbours-with-state world (:x cell) (:y cell) 1 :climax))))))
|
||||
(merge cell {:state :scrub})))
|
||||
(fn [cell world]
|
||||
(cond (= (:state cell) :waste)
|
||||
(merge cell {:state :pasture})))
|
||||
;; Forest increases soil fertility
|
||||
(fn [cell world]
|
||||
(cond (member? (:state cell) '(:forest :climax))
|
||||
(merge cell {:fertility (+ (:fertility cell) 1)})))
|
||||
))
|
||||
|
||||
(defn transform-cell
|
||||
"Derive a cell from this cell of this world by applying these rules."
|
||||
[cell world rules]
|
||||
|
@ -96,3 +43,10 @@
|
|||
[world rules generations]
|
||||
(let [state (list world rules)]
|
||||
(take generations (iterate transform-world-state state))))
|
||||
|
||||
(defn animate-world
|
||||
[world rules generations]
|
||||
(let [state (list world rules)]
|
||||
(dorun
|
||||
(take generations (iterate transform-world-state state)))
|
||||
nil))
|
|
@ -3,3 +3,9 @@
|
|||
(defn member?
|
||||
"True if elt is a member of col."
|
||||
[elt col] (some #(= elt %) col))
|
||||
|
||||
(defn population [cell species]
|
||||
"Return the population of this species in this cell.
|
||||
Species is assumed to be a keyword whose value in a cell should be an
|
||||
integer."
|
||||
(or (get cell species) 0))
|
|
@ -1,4 +1,5 @@
|
|||
(ns mw-engine.world
|
||||
(:use mw-engine.utils)
|
||||
(:require [clojure.math.combinatorics :as combo]))
|
||||
|
||||
(defn make-cell
|
||||
|
@ -39,12 +40,19 @@
|
|||
(nth (nth world y) x)))
|
||||
|
||||
(defn get-neighbours
|
||||
([world x y depth]
|
||||
"Get the neighbours to distance depth of the cell at x, y in this world."
|
||||
[world x y depth]
|
||||
(map #(get-cell world (first %) (first (rest %)))
|
||||
(combo/cartesian-product
|
||||
(range (- x depth) (+ x depth))
|
||||
(range (- y depth) (+ y depth)))))
|
||||
([world cell depth]
|
||||
"Get the neighbours to distance depth of this cell in this world."
|
||||
(get-neighbours world (:x cell) (:y cell) depth))
|
||||
([world cell]
|
||||
"Get the immediate neighbours of this cell in this world"
|
||||
(get-neighbours world cell 1)))
|
||||
|
||||
|
||||
(defn get-neighbours-with-state
|
||||
"Get the neighbours to distance depth of the cell at x, y in this world which
|
||||
|
@ -63,7 +71,10 @@
|
|||
"Format one row in the state of a world for printing"
|
||||
[row]
|
||||
(apply str
|
||||
(map #(format "%10s" (truncate-state % 10)) row)))
|
||||
(map #(format "%10s(%d/%d)"
|
||||
(truncate-state % 10)
|
||||
(population % :deer)
|
||||
(population % :wolves)) row)))
|
||||
|
||||
(defn print-world
|
||||
"Print the current state of this world, and return nil"
|
||||
|
|
Loading…
Reference in a new issue