My monster! It lives!

This commit is contained in:
Simon Brooke 2014-07-14 18:34:38 +01:00
parent e5b74a4a68
commit e1ed824aff
2 changed files with 41 additions and 111 deletions

View file

@ -13,8 +13,8 @@ is returned and there's no helpful error message.
The generated function is a function of two arguments The generated function is a function of two arguments
_ __cell__ a cell in a world as defined in mw-engine.world, q.v.; + __cell__ a cell in a world as defined in mw-engine.world, q.v.;
_ __world__ the world of which that cell forms part. + __world__ the world of which that cell forms part.
It returns a new cell, based on the cell passed. It returns a new cell, based on the cell passed.
@ -25,13 +25,22 @@ modified.
### <a name="grammar"></a>Grammar ### <a name="grammar"></a>Grammar
#### Comments
+ Any line which starts with the hash character (#) is ignored;
+ Any line which starts with a semi-colon (;) is ignored.
#### Rules
A rule comprises: A rule comprises:
+ if _conditions_ then _actions_ + if _conditions_ then _actions_
Each rule must be on a single line. There should be nothing else on that line.
#### Conditions #### Conditions
where _conditions_ is: In rules, _conditions_ is one of:
+ _condition_ + _condition_
+ _condition_ and _conditions_ + _condition_ and _conditions_
@ -54,12 +63,21 @@ A _condition_ is one of:
+ _property_ is more than _numeric-value_ + _property_ is more than _numeric-value_
+ _property_ is less than _numeric-value_ + _property_ is less than _numeric-value_
+ _number_ neighbours have _property_ equal to _value_ + _number_ neighbours have _property_ equal to _value_
+ _number_ neighbours have _property_ more than _numeric-value_
+ _number_ neighbours have _property_ less than _numeric-value_
+ more than _number_ neighbours have _property_ equal to _value_ + more than _number_ neighbours have _property_ equal to _value_
+ fewer than _number_ neighbours have _property_ equal to _value_ + fewer than _number_ neighbours have _property_ equal to _value_
+ some neighbours have _property_ equal to _value_
+ more than _number_ neighbours have _property_ more than _numeric-value_
+ fewer than _number_ neighbours have _property_ more than _numeric-value_
+ some neighbours have _property_ more than _numeric-value_
+ more than _number_ neighbours have _property_ less than _numeric-value_
+ fewer than _number_ neighbours have _property_ less than _numeric-value_
+ some neighbours have _property_ less than _numeric-value_
#### Actions #### Actions
Where _actions_ is: In these rules, _actions_ is one of:
+ _action_ + _action_
+ _action_ and _actions_ + _action_ and _actions_
@ -67,17 +85,18 @@ Where _actions_ is:
and _action_ is: and _action_ is:
+ _property_ should be _value_ + _property_ should be _value_
+ _number_ chance in _number_ _property_ should be _value_
#### Properties #### Properties
In the above, _property_ is the name of any property of a cell. Any alpha-numeric In the above, _property_ is the name of any property of a cell. Any alpha-numeric
string of characters can form the name of a property. Actions should NOT refer string of characters can form the name of a property. Actions should __NOT__ refer
to the reserved properties __x__ and __y__. to the reserved properties __x__ and __y__.
#### Values in Conditions #### Values in Conditions
Values in conditions and actions are considered slightly differently. In a Values in conditions and actions are considered slightly differently. In a
condition, a value is one of condition, a value is one of:
+ _symbolic-value_ + _symbolic-value_
+ _numeric-value_ + _numeric-value_
@ -116,14 +135,11 @@ and _operator_ is one of the simple arithmetic operators '+', '-', '*' and '/'.
### Shorthand ### Shorthand
Note that '...members are...' is equivalent to '...members have state equal to...', Note that '...neighbours are...' is equivalent to '...neighbours have state equal to...',
and 'some neighbours...' is equivalent to 'more than 0 neighbours...' and 'some neighbours...' is equivalent to 'more than 0 neighbours...'
## License ## License
Copyright © 2014 Simon Brooke Copyright © 2014 Simon Brooke
Distributed under the terms of the [GNU General Public License v2][1] Distributed under the terms of the [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
[1]: http://www.gnu.org/licenses/gpl-2.0.html

View file

@ -1,182 +1,96 @@
## Vegetation rules ## Vegetation rules
;; rules which populate the world with plants ;; rules which populate the world with plants
;; Occasionally, passing birds plant tree seeds into grassland ;; Occasionally, passing birds plant tree seeds into grassland
;; (fn [cell world] (cond (and (= (:state cell) :grassland)(< (rand 10) 1))(merge cell {:state :heath})))
if state is grassland then 1 chance in 10 state should be heath if state is grassland then 1 chance in 10 state should be heath
;; heath below the treeline grows gradually into forest, providing browsing pressure is not to high ;; heath below the treeline grows gradually into forest, providing browsing pressure is not to high
;; (fn [cell world]
;; (cond (and
;; (= (:state cell) :heath)
;; ;; browsing limit really ought to vary with soil fertility, but...
;; (< (+ (get-int cell :deer)(get-int cell :sheep)) 6)
;; (< (get-int cell :altitude) treeline))
;; (merge cell {:state :scrub})))
if state is heath and deer are fewer than 6 and altitude is less than 150 then state should be scrub if state is heath and deer are fewer than 6 and altitude is less than 150 then state should be scrub
;; (fn [cell world] (cond (= (:state cell) :scrub) (merge cell {:state :forest})))
if state is scrub then 1 chance in 5 state should be forest if state is scrub then 1 chance in 5 state should be forest
;; Forest on fertile land grows to climax ;; Forest on fertile land grows to climax
;; (fn [cell world]
;; (cond
;; (and
;; (= (:state cell) :forest)
;; (> (get-int cell :fertility) 10))
;; (merge cell {:state :climax})))
if state is forest and fertility is more than 5 then state should be climax if state is forest and fertility is more than 5 then state should be climax
;; Climax forest occasionally catches fire (e.g. lightning strikes) ;; Climax forest occasionally catches fire (e.g. lightning strikes)
;; (fn [cell world] (cond (and (= (:state cell) :climax)(< (rand lightning-probability) 1)) (merge cell {:state :fire})))
if state is climax then 1 chance in 500 state should be fire if state is climax then 1 chance in 500 state should be fire
;; Climax forest neighbouring fires is likely to catch 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})))
if state is climax and some neighbours are fire then 1 chance in 3 state should be fire if state is climax and some neighbours are fire then 1 chance in 3 state should be fire
;; After fire we get waste ;; After fire we get waste
;; (fn [cell world] (cond (= (:state cell) :fire) (merge cell {:state :waste})))
if state is fire then state should be waste if state is fire then state should be waste
;; And after waste we get pioneer species; if there's a woodland seed ;; And after waste we get pioneer species; if there's a woodland seed
;; source, it's going to be heath, otherwise grassland. ;; source, it's going to be heath, otherwise grassland.
;; (fn [cell world]
;; (cond
;; (and (= (:state cell) :waste)
;; (not
;; (empty?
;; (flatten
;; (list
;; (get-neighbours-with-state world (:x cell) (:y cell) 1 :scrub)
;; (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 :heath})))
if state is waste and some neighbours are scrub then state should be heath if state is waste and some neighbours are scrub then state should be heath
if state is waste and some neighbours are forest then state should be heath 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 and some neighbours are climax then state should be heath
;; (fn [cell world]
;; (cond (= (:state cell) :waste)
;; (merge cell {:state :grassland})))
if state is waste then state should be grassland if state is waste then state should be grassland
;; Forest increases soil fertility ;; Forest increases soil fertility
;; (fn [cell world]
;; (cond (member? (:state cell) '(:forest :climax))
;; (merge cell {:fertility (+ (get-int cell :fertility) 1)})))
if state is in forest or climax then fertility should be fertility - 1 if state is in forest or climax then fertility should be fertility - 1
## Herbivore rules ## Herbivore rules
;; rules describing the impact of herbivores on the environment ;; rules describing the impact of herbivores on the environment
;; if there are too many deer for the fertility of the area to sustain, ;; if there are too many deer for the fertility of the area to sustain,
;; some die or move on. ;; some die or move on.
;; (fn [cell world]
;; (cond (> (get-int cell :deer) (get-int cell :fertility))
;; (merge cell {:deer (get-int cell :fertility)})))
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. ;; deer arrive occasionally at the edge of the map.
;; (fn [cell world]
;; (cond (and (< (count (get-neighbours world cell)) 8)
;; (< (rand 50) 1)
;; (> (get-int cell :fertility) 0)
;; (= (get-int cell :deer) 0))
;; (merge cell {:deer 2})))
if x is 0 or y is 0 and deer are 0 then 1 chance in 5 deer should be 2 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. ;; deer gradually spread through the world by breeding or migrating.
;; (fn [cell world]
;; (let [n (apply + (map #(get-int % :deer) (get-neighbours world cell)))]
;; (cond (and
;; (> (get-int cell :fertility) 0)
;; (= (get-int cell :deer) 0)
;; (>= n 2))
;; (merge cell {:deer (int (/ n 2))}))))
if fertility is more than 10 and deer is 0 and some neighbours have deer more than 2 then deer should be 2 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. ;; deer breed.
;; (fn [cell world]
;; (cond
;; (>= (get-int cell :deer) 2)
;; (merge cell {:deer (int (* (:deer cell) 2))})))))
if deer are more than 1 then deer should be deer * 2 if deer are more than 1 then deer should be deer * 2
## Predator rules ## Predator rules
;; rules describing the impact of predator behaviour on the environment ;; rules describing the impact of predator behaviour on the environment
;; wolves eat deer
;; (fn [cell world]
;; (cond
;; (>= (get-int cell :wolves) 1)
;; (merge cell {:deer (max 0 (- (get-int cell :deer) (get-int cell :wolves)))})))
if deer are more than wolves then deer should be deer - wolves if deer are more than wolves then deer should be deer - wolves
;; ;; not more than eight wolves in a pack, for now (hack because wolves are not dying)
;; (fn [cell world]
;; (cond (> (get-int cell :wolves) 8) (merge cell {:wolves 8})))
;; if there are not enough deer to sustain the population of wolves, ;; if there are not enough deer to sustain the population of wolves,
;; some wolves die or move on. (doesn't seem to be working?) ;; some wolves die or move on.
;; (fn [cell world]
;; (cond (> (get-int cell :wolves) (get-int cell :deer))
;; (merge cell {:wolves 0})))
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
;; wolves arrive occasionally at the edge of the map. ;; wolves arrive occasionally at the edge of the map.
;; (fn [cell world]
;; (cond (and (< (count (get-neighbours world cell)) 8)
;; (< (rand 50) 1)
;; (not (= (:state cell) :water))
;; (= (get-int cell :wolves) 0))
;; (merge cell {:wolves 2})))
if x is 0 or y is 0 and wolves are 0 then 1 chance in 5 wolves should be 2 if x is 0 or y is 0 and wolves are 0 then 1 chance in 50 wolves should be 2
;; wolves gradually spread through the world by breeding or migrating. ;; wolves gradually spread through the world by breeding or migrating.
;; (fn [cell world]
;; (let [n (apply + (map #(get-int % :wolves) (get-neighbours world cell)))]
;; (cond (and
;; (not (= (:state cell) :water))
;; (= (get-int cell :wolves) 0)
;; (>= n 2))
;; (merge cell {:wolves 2}))))
if state is not water and wolves is 0 and some neighbours have wolves more than 2 then 1 chance in 5 wolves should be 2 if state is not water and wolves is 0 and some neighbours have wolves more than 2 then 1 chance in 5 wolves should be 2
;; wolves breed. ;; wolves breed.
;; (fn [cell world]
;; (cond
;; (>= (get-int cell :wolves) 2)
;; (merge cell {:wolves (int (* (:wolves cell) 2))})))
;; ))
if wolves are more than 1 then wolves should be wolves * 2 if wolves are more than 1 then wolves should be wolves * 2
## Initialisation rules ## Initialisation rules
;; Rules which deal with state 'new' will waste less time if they're near the ;; Rules which deal with state 'new' will waste less time if they're near the
;; end of the file ;; end of the file
;; below the waterline we have water.
if state is new and altitude is less than 10 then state should be water if state is new and altitude is less than 10 then state should be water
;; above the snowline we have snow.
if state is new and altitude is more than 200 then state should be snow if state is new and altitude is more than 200 then state should be snow
;; another comment
;; otherwise, we have grassland.
if state is new then state should be grassland if state is new then state should be grassland