Rule language now working cleanly with no errors showing. Very occasional
null pointer exception during parsing, not yet diagnosed.
This commit is contained in:
parent
a61ace1694
commit
91310af2d8
|
@ -19,8 +19,6 @@ if state is forest and fertility is more than 5 then state should be climax
|
|||
if state is climax then 1 chance in 500 state should be fire
|
||||
|
||||
;; Climax forest neighbouring fires is likely to catch fire
|
||||
;; TODO: this rule, and specifically the 'some neighbours' clause, seems to give
|
||||
;; rise to the 'Keyword cannot be cast to Number' bug.
|
||||
if state is climax and some neighbours are fire then 1 chance in 3 state should be fire
|
||||
|
||||
;; After fire we get waste
|
||||
|
@ -35,24 +33,19 @@ if state is waste and some neighbours are forest then state should be heath
|
|||
if state is waste and some neighbours are climax then state should be heath
|
||||
if state is waste then state should be grassland
|
||||
|
||||
;; Forest increases soil fertility. TODO: this rule compiles to what looks like
|
||||
;; the right code but it never fires.
|
||||
if state is in forest or climax then fertility should be fertility + 1
|
||||
|
||||
## Herbivore rules
|
||||
|
||||
;; rules describing the impact of herbivores on the environment
|
||||
|
||||
;; if there are too many deer for the fertility of the area to sustain,
|
||||
;; some die or move on.
|
||||
if deer are more than fertility then deer should be fertility / 2
|
||||
;; if deer are more than fertility then deer should be fertility / 2
|
||||
|
||||
;; deer arrive occasionally at the edge of the map.
|
||||
|
||||
if x is 0 or y is 0 and deer are 0 then 1 chance in 50 deer should be 2
|
||||
|
||||
;; deer gradually spread through the world by breeding or migrating.
|
||||
|
||||
if fertility is more than 10 and deer is 0 and some neighbours have deer more than 2 then deer should be 2
|
||||
|
||||
;; deer breed.
|
||||
|
@ -68,7 +61,7 @@ if deer are more than wolves then deer should be deer - wolves
|
|||
;; if there are not enough deer to sustain the population of wolves,
|
||||
;; some wolves die or move on.
|
||||
|
||||
if wolves are more than deer then deer should be 0 and wolves should be deer
|
||||
if wolves are more than deer then deer should be 0 and wolves should be deer + 0
|
||||
|
||||
;; wolves arrive occasionally at the edge of the map.
|
||||
|
||||
|
@ -82,6 +75,12 @@ if state is not water and wolves is 0 and some neighbours have wolves more than
|
|||
|
||||
if wolves are more than 1 then wolves should be wolves * 2
|
||||
|
||||
## Potential blockers
|
||||
|
||||
;; Forest increases soil fertility.
|
||||
if state is in forest or climax then fertility should be fertility + 1
|
||||
|
||||
|
||||
## Initialisation rules
|
||||
|
||||
;; Rules which deal with state 'new' will waste less time if they're near the
|
||||
|
|
|
@ -30,22 +30,10 @@
|
|||
"Compile each non-comment line of this `string` into an executable anonymous
|
||||
function, and return the sequence of such functions."
|
||||
[string]
|
||||
(map #(compile-rule % true) (remove comment? (split string #"\n"))))
|
||||
(map #(compile-rule % true) (remove comment? (trim (split string #"\n")))))
|
||||
|
||||
(defn compile-file
|
||||
"Compile each non-comment line of the file indicated by this `filename` into
|
||||
an executable anonymous function, and return the sequence of such functions."
|
||||
[filename]
|
||||
(compile-string (slurp filename)))
|
||||
|
||||
|
||||
|
||||
|
||||
;; (let [lines
|
||||
;; (doall (with-open [rdr (reader filename)] (line-seq rdr)))]
|
||||
;; (map parse-line lines)))
|
||||
|
||||
;;(defn parse-string
|
||||
;; "Parse rules from successive lines in this `string`"
|
||||
;; [string]
|
||||
;; (parse-from-reader (BufferedReader. (StringReader. string))))
|
|
@ -118,7 +118,7 @@
|
|||
([tokens expect-int]
|
||||
(or
|
||||
(parse-disjunct-value tokens expect-int)
|
||||
(parse-simple-value tokens)))
|
||||
(parse-simple-value tokens expect-int)))
|
||||
([tokens]
|
||||
(parse-value tokens false)))
|
||||
|
||||
|
|
|
@ -107,6 +107,14 @@
|
|||
(is (nil? (apply afn (list {:altitude 200} nil)))
|
||||
"Rule does not fire when condition is not met")))
|
||||
|
||||
(testing "Property is more than property"
|
||||
(let [afn (compile-rule "if wolves are more than deer then deer should be 0")]
|
||||
(is (= (apply afn (list {:deer 2 :wolves 3} nil))
|
||||
{:deer 0 :wolves 3})
|
||||
"Rule fires when condition is met")
|
||||
(is (nil? (apply afn (list {:deer 3 :wolves 2} nil)))
|
||||
"Rule does not fire when condition is not met")))
|
||||
|
||||
(testing "Property is less than numeric-value"
|
||||
(let [afn (compile-rule "if altitude is less than 10 then state should be water")]
|
||||
(is (= (apply afn (list {:altitude 9} nil))
|
||||
|
@ -115,6 +123,14 @@
|
|||
(is (nil? (apply afn (list {:altitude 10} nil)))
|
||||
"Rule does not fire when condition is not met")))
|
||||
|
||||
(testing "Property is less than property"
|
||||
(let [afn (compile-rule "if wolves are less than deer then deer should be deer - wolves")]
|
||||
(is (= (apply afn (list {:deer 3 :wolves 2} nil))
|
||||
{:deer 1 :wolves 2})
|
||||
"Rule fires when condition is met")
|
||||
(is (nil? (apply afn (list {:deer 2 :wolves 3} nil)))
|
||||
"Rule does not fire when condition is not met")))
|
||||
|
||||
(testing "Number neighbours have property equal to value"
|
||||
(let [afn (compile-rule "if 3 neighbours have state equal to new then state should be water")
|
||||
world (make-world 3 3)]
|
||||
|
@ -396,7 +412,4 @@
|
|||
(is (= (:state (apply afn (list {:x 2 :y 2} world))) :beach)
|
||||
"Rule fires when condition is met (strip of altitude 11 down right hand side)")
|
||||
(is (nil? (apply afn (list {:x 0 :y 1} world)))
|
||||
"Middle cell of the strip has only two high neighbours, so rule should not fire.")))
|
||||
|
||||
|
||||
)
|
||||
"Middle cell of the strip has only two high neighbours, so rule should not fire."))))
|
||||
|
|
Loading…
Reference in a new issue