From 0dc6aab59dea8aed3e35b706e071ed4f3a6755c3 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Mon, 30 Jun 2014 22:37:37 +0100 Subject: [PATCH] Minor changes --- project.clj | 2 +- src/mw_engine/core.clj | 64 ++++++----------------------------------- src/mw_engine/utils.clj | 8 +++++- src/mw_engine/world.clj | 15 ++++++++-- 4 files changed, 30 insertions(+), 59 deletions(-) diff --git a/project.clj b/project.clj index 8018d17..e318ccf 100644 --- a/project.clj +++ b/project.clj @@ -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"} diff --git a/src/mw_engine/core.clj b/src/mw_engine/core.clj index d5eec14..bd2399c 100644 --- a/src/mw_engine/core.clj +++ b/src/mw_engine/core.clj @@ -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)) \ No newline at end of file diff --git a/src/mw_engine/utils.clj b/src/mw_engine/utils.clj index 056330f..4616050 100644 --- a/src/mw_engine/utils.clj +++ b/src/mw_engine/utils.clj @@ -2,4 +2,10 @@ (defn member? "True if elt is a member of col." - [elt col] (some #(= elt %) col)) \ No newline at end of file + [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)) \ No newline at end of file diff --git a/src/mw_engine/world.clj b/src/mw_engine/world.clj index 16c1916..4f5347a 100644 --- a/src/mw_engine/world.clj +++ b/src/mw_engine/world.clj @@ -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"