Added a new file drainage.clj which attempts to model rivers; moved

some functions from heightmap into utils; added a -archive option to
buildall as first step towards auto-building a Debian package for
Raspberry Pi.
This commit is contained in:
simon 2014-07-31 23:43:02 +01:00
parent b3b7f8a475
commit 1300e8d103
4 changed files with 140 additions and 52 deletions

View file

@ -8,12 +8,15 @@
# Simon Broooke <simon@jasmine.org.uk> # Simon Broooke <simon@jasmine.org.uk>
# Variable and glag initialisation
archive=FALSE
email=`grep ${USER} /etc/passwd | awk -F\: '{print $5}' | awk -F\, '{print $4}'` email=`grep ${USER} /etc/passwd | awk -F\: '{print $5}' | awk -F\, '{print $4}'`
fullname=`grep ${USER} /etc/passwd | awk -F\: '{print $5}' | awk -F\, '{print $1}'` fullname=`grep ${USER} /etc/passwd | awk -F\: '{print $5}' | awk -F\, '{print $1}'`
webappsdir="/var/lib/tomcat7/webapps" old="unset"
release="" release=""
trial="FALSE"
tmp=buildall.tmp.$$ tmp=buildall.tmp.$$
trial="FALSE"
webappsdir="/var/lib/tomcat7/webapps"
# Builds the build signature properties in the manifest map file # Builds the build signature properties in the manifest map file
# expected arguments: old version tag, version tag, full name of user, # expected arguments: old version tag, version tag, full name of user,
@ -69,6 +72,7 @@ if [ $# -lt 1 ]
then then
cat <<-EOF 1>&2 cat <<-EOF 1>&2
Usage: Usage:
-archive Create a tar archive of the current state of the source.
-build Build all components and commit to master. -build Build all components and commit to master.
-email [ADDRESS] Your email address, to be recorded in the build signature. -email [ADDRESS] Your email address, to be recorded in the build signature.
-fullname [NAME] Your full name, to be recorded in the build signature. -fullname [NAME] Your full name, to be recorded in the build signature.
@ -82,6 +86,8 @@ fi
while (( "$#" )) while (( "$#" ))
do do
case $1 in case $1 in
-a|-archive)
archive="TRUE";;
-b|-build) -b|-build)
# 'build' is the expected normal case. # 'build' is the expected normal case.
trial="FALSE"; trial="FALSE";
@ -256,3 +262,26 @@ do
done done
if [ "${archive}" ]
then
for dir in mw-*
do
pushd ${dir}
version=`cat project.clj | grep 'defproject mw' | sed 's/.*defproject mw-[a-z]* "\([A-Za-z0-9_.-]*\)".*/\1/'`
lein clean
popd
done
tmp=microworld-${version}
mkdir ${tmp}
pushd ${tmp}
for dir in ../mw-*
do
cp -r $dir .
done
popd
tar czvf ${tmp}.orig.tar.gz ${tmp}
rm -rf ${tmp}
fi

View file

@ -0,0 +1,42 @@
;; Experimental, probably of no interest to anyone else; attempt to compute drainage on a world,
;; assumed to have altitudes already set from a heighmap.
(ns mw-engine.drainage
(:use mw-engine.utils
mw-engine.world))
(defn rain-world
"Simulate rainfall on this `world`. TODO: Doesn't really work just now - should
rain more on west-facing slopes, and less to the east of high ground"
[world]
(map-world world (fn [world cell] (merge cell {:rainfall 1}))))
(defn flow-contributors
"Return a list of the cells in this `world` which are higher than this
`cell` and for which this cell is the lowest neighbour"
[world cell]
(remove nil?
(map
(fn [n]
(cond (= cell (get-least-cell (get-neighbours world n) :altitude)) n))
(get-neighbours-with-property-value world (:x cell) (:y cell) 1
:altitude
(or (:altitude cell) 0) >))))
(defn flow
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
to this one but having a value of its flow property set from that computation.
Flow comes from a higher cell to a lower only if the lower is the lowest neighbour of the higher."
[world cell]
(merge cell
{:flow (+ (:rainfall cell)
(apply +
(map (fn [neighbour] (:flow (flow world neighbour)))
(flow-contributors world cell))))}))
(defn flow-world
"Return a world like this `world`, but with cells tagged with the amount of
water flowing through them."
[world]
(map-world (rain-world world) flow))

View file

@ -6,21 +6,12 @@
(ns mw-engine.heightmap (ns mw-engine.heightmap
(:import [java.awt.image BufferedImage]) (:import [java.awt.image BufferedImage])
(:use mw-engine.utils (:use mw-engine.utils
mw-engine.world) mw-engine.world
mw-engine.drainage)
(:require [fivetonine.collage.util :as collage :only [load-image]] (:require [fivetonine.collage.util :as collage :only [load-image]]
[mikera.image.core :as imagez :only [filter-image get-pixels]] [mikera.image.core :as imagez :only [filter-image get-pixels]]
[mikera.image.filters :as filters])) [mikera.image.filters :as filters]))
(defn- abs
"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,
and negative integers onto natural numbers. Also maps negative real numbers
onto positive real numbers.
* `n` a number, on the set of real numbers."
[n]
(cond (< n 0) (- 0 n) true n))
(defn tag-gradient (defn tag-gradient
"Set the `gradient` property of this `cell` of this `world` to the difference in "Set the `gradient` property of this `cell` of this `world` to the difference in
altitude between its highest and lowest neghbours." altitude between its highest and lowest neghbours."

View file

@ -3,6 +3,16 @@
(ns mw-engine.utils (ns mw-engine.utils
(:require [clojure.math.combinatorics :as combo])) (:require [clojure.math.combinatorics :as combo]))
(defn abs
"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,
and negative integers onto natural numbers. Also maps negative real numbers
onto positive real numbers.
* `n` a number, on the set of real numbers."
[n]
(cond (< n 0) (- 0 n) true n))
(defn member? (defn member?
"True if elt is a member of col." "True if elt is a member of col."
[elt col] (some #(= elt %) col)) [elt col] (some #(= elt %) col))
@ -138,6 +148,22 @@
([world cell state] ([world cell state]
(get-neighbours-with-state world cell 1 state))) (get-neighbours-with-state world cell 1 state)))
(defn get-least-cell
"Return the cell from among these `cells` which has the lowest numeric value
for this `property`; if the property is absent or not a number, use this
`default`"
([cells property default]
(cond
(empty? cells) nil
true (let [downstream (get-least-cell (rest cells) property default)]
(cond (<
(or (property (first cells)) default)
(or (property downstream) default)) (first cells)
true downstream))))
([cells property]
(get-least-cell cells property (. Integer MAX_VALUE))))
(defn- set-cell-property (defn- set-cell-property
"If this `cell`s x and y properties are equal to these `x` and `y` values, "If this `cell`s x and y properties are equal to these `x` and `y` values,
return a cell like this cell but with the value of this `property` set to return a cell like this cell but with the value of this `property` set to