From 98e43dbe8f5567a44719b6997fee041d67cb7250 Mon Sep 17 00:00:00 2001
From: Simon Brooke
MicroWorld is a rule driven cellular automaton. What does that mean? Well, it's
a two dimensional world made up of squares called **cells**. The world develops
in steps, and at each step, each cell is modified by applying the rules.
diff --git a/resources/public/css/standard.css b/resources/public/css/standard.css
index 1a8c13d..db66b45 100644
--- a/resources/public/css/standard.css
+++ b/resources/public/css/standard.css
@@ -72,9 +72,10 @@ li.nav-item a:active { background: gray; color: white; }
}
.widget {
- margin: 0;
- padding: 0.25em 1em;
- border: thin solid white;
+ background-color: silver;
+ border: thin solid white;
+ margin-top: 0;
+ margin-bottom: 0;
}
.world {
@@ -86,8 +87,6 @@ div.error {
}
form {
- width: 100%;
- background-color: silver;
border: thin solid silver;
}
@@ -100,7 +99,7 @@ h1, h2, h3, h4, h5 {
color: white;
}
-p, pre, ul, ol, dl, menu, h1, h2, h3, h4, h5 {
+div.content, form, p, pre, ul, ol, dl, menu, h1, h2, h3, h4, h5 {
padding: 0.25em 10%;
}
@@ -118,15 +117,8 @@ input.required:after {
}
label {
- min-width: 35%;
-}
-
-label, input {
- padding: 0.25em 1em;
- margin: 0 0.5em;
-}
-
-label {
+ width: 30em;
+ min-width: 20em;
border-right: thin solid gray;
}
@@ -138,9 +130,19 @@ menu li::before {
content: "|| ";
}
-div.world table, div.world tr td {
+div.world table, div.world table tr td {
padding: 0;
margin: 0;
+ border-collapse: collapse;
border: none;
}
+table.music-ruled tr:nth-child(odd) {
+ background-color: silver;
+}
+
+th, td {
+ text-align: left;
+ padding: 0 0.25em;
+}
+
diff --git a/resources/public/docs/mw-engine/uberdoc.html b/resources/public/docs/mw-engine/uberdoc.html
index 08d1adb..a604419 100644
--- a/resources/public/docs/mw-engine/uberdoc.html
+++ b/resources/public/docs/mw-engine/uberdoc.html
@@ -3441,7 +3441,30 @@ important.
Functions to create and to print two dimensional cellular automata. Nothing in this + (get-neighbours-with-state world cell 1 state)))
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
+ this value
. Otherwise, just return this cell
.
(defn- set-cell-property + [cell x y property value] + (cond + (and (= x (:x cell)) (= y (:y cell))) + (merge cell {property value}) + true + cell))
Return a world like this world
but with the value of exactly one property
+ of one cell
changed to this value
(defn set-property + ([world cell property value] + (set-property world (:x cell) (:y cell) property value)) + ([world x y property value] + (apply + vector ;; we want a vector of vectors, not a list of lists, for efficiency + (map + (fn [row] + (apply + vector + (map #(set-cell-property % x y property value) + row))) + world))))
Functions to create and to print two dimensional cellular automata. Nothing in this file should determine what states are possible within the automaton, except for the initial state, :new.
diff --git a/resources/public/docs/mw-ui/uberdoc.html b/resources/public/docs/mw-ui/uberdoc.html index 4057037..71f8ea5 100644 --- a/resources/public/docs/mw-ui/uberdoc.html +++ b/resources/public/docs/mw-ui/uberdoc.html @@ -3126,6 +3126,7 @@ net.brehaut.ClojureTools = (function (SH) { [mw-engine.natural-rules :as rules] [mw-parser.bulk :as compiler] [hiccup.core :refer [html]] + [noir.io :as io] [noir.session :as session]))(defn format-css-class [statekey] "Format this statekey, assumed to be a keyword indicating a state in the @@ -3141,7 +3142,7 @@ net.brehaut.ClojureTools = (function (SH) { [cell] (let [state (:state cell)] [:td {:class (format-css-class state) :title (format-mouseover cell)} - [:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))} + [:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))} [:img {:alt (:state cell) :src (format-image-path state)}]]]))
Render this world row as a Hiccup table row.
(defn render-world-row [row] @@ -3151,11 +3152,13 @@ net.brehaut.ClojureTools = (function (SH) { (let [world (or (session/get :world) (engine/transform-world (heightmap/apply-heightmap - "resources/public/img/heightmaps/small_hill.png" + (io/get-resource "/img/heightmaps/small_hill.png") ;; "resources/public/img/heightmaps/great_britain_and_ireland_small.png") rules/init-rules)) rules (or (session/get :rules) - (do (session/put! :rules (compiler/compile-file "resources/rulesets/basic.txt")) + (do (session/put! :rules + (compiler/compile-file + (io/get-resource "/rulesets/basic.txt"))) (session/get :rules))) generation (+ (or (session/get :generation) 0) 1) w2 (engine/transform-world world rules) @@ -3166,22 +3169,17 @@ net.brehaut.ClojureTools = (function (SH) { (apply vector (cons :table (map render-world-row w2))) - [:p (str "Generation " generation)]]))
Render the world implied by the session as a complete HTML page.
-(defn render-world - [] - (html - [:html - [:head - [:title "MicroWorld demo"] - [:link {:media "only screen and (max-device-width: 480px)" :href "css/phone.css" :type "text/css" :rel "stylesheet"}] - [:link {:media "only screen and (min-device-width: 481px) and (max-device-width: 1024px)" :href "css/tablet.css" :type "text/css" :rel "stylesheet"}] - [:link {:media "screen and (min-device-width: 1025px)" :href "css/standard.css" :type "text/css" :rel "stylesheet"}] - [:link {:media "print" :href "css/print.css" :type "text/css" :rel "stylesheet"}] - [:link {:href "css/states.css" :type "text/css" :rel "stylesheet"}] - [:meta {:http-equiv "refresh" :content "5"}]] - [:body - (render-world-table) - ]]))
(defn render-inspector + [cell table] + [:table {:class "music-ruled"} + [:tr + [:td {:colspan 2 :style "text-align: center;"} + [:img {:src (str "img/tiles/" (name (:state cell)) ".png") + :width 64 + :height 64}]]] + [:tr [:th "Key"][:th "Value"]] + (map #(vector :tr (vector :th %)(vector :td (cell %))) (keys cell))])
(ns mw-ui.repl (:use mw-ui.handler ring.server.standalone @@ -3214,16 +3212,40 @@ net.brehaut.ClojureTools = (function (SH) {
(ns mw-ui.routes.home (:use clojure.walk compojure.core + [mw-engine.utils :as engine-utils] [mw-ui.routes.rules :as rules] [mw-ui.routes.params :as params]) (:require [hiccup.core :refer [html]] [mw-ui.layout :as layout] [mw-ui.util :as util] [mw-ui.render-world :as world] - [noir.session :as session]))
(defn home-page [] (layout/render "trusted-content.html" {:title "Welcome to MicroWorld" :content (util/md->html "/md/mw-ui.md")}))
(defn inspect-page [request] + (let [params (keywordize-keys (:params request)) + xs (:x params) + ys (:y params) + x (if (not (empty? xs)) (read-string xs) 0) + y (if (not (empty? ys)) (read-string ys) 0) + world (session/get :world) + cell (engine-utils/get-cell world x y) + state (:state params)] + (cond state + (do + (session/put! :world (engine-utils/set-property world cell :state (keyword state))) + (response/redirect "world")) + true + (layout/render "inspector.html" + {:title (format "Inspect cell at %d, %d" x y) + :content (html (world/render-inspector cell world)) + :cell cell + :x (:x cell) + :y (:y cell) + :states (util/list-resources + "/img/tiles" #"([0-9a-z-_]+).png")}))))
(defn world-page [] (layout/render "trusted-content.html" {:title "Watch your world grow" @@ -3250,8 +3272,8 @@ net.brehaut.ClojureTools = (function (SH) {
(defn docs-page [] (layout/render "docs.html" {:title "Documentation" :parser (util/md->html "/md/mw-parser.md" ) - :states (util/list-resources "resources/public/img/tiles" #"([0-9a-z-_]+).png") - :lessons (util/list-resources "resources/public/md/lesson-plans" #"([0-9a-z-_]+).md") + :states (util/list-resources "/img/tiles" #"([0-9a-z-_]+).png") + :lessons (util/list-resources "/md/lesson-plans" #"([0-9a-z-_]+).md") :components ["mw-engine" "mw-parser" "mw-ui"]}))
(defroutes home-routes (GET "/" [] (home-page)) @@ -3262,9 +3284,12 @@ net.brehaut.ClojureTools = (function (SH) { (GET "/md" request (md-page request)) (POST "/params" request (params/params-page request)) (GET "/rules" request (rules/rules-page request)) - (POST "/rules" request (rules/rules-page request)))
(ns mw-ui.routes.params (:use clojure.walk + clojure.java.io compojure.core) (:require [hiccup.core :refer [html]] [mw-engine.heightmap :as heightmap] @@ -3272,12 +3297,13 @@ net.brehaut.ClojureTools = (function (SH) { [mw-ui.layout :as layout] [mw-ui.util :as util] [mw-ui.render-world :as world] + [noir.io :as io] [noir.session :as session]))
(defn- send-params [] {:title "Choose your world" - :heightmaps (util/list-resources "resources/public/img/heightmaps" #"([0-9a-z-_]+).png") + :heightmaps (util/list-resources "/img/heightmaps" #"([0-9a-z-_]+).png") :pause (or (session/get :pause) 5) - :rulesets (util/list-resources "resources/rulesets" #"([0-9a-z-_]+).txt") + :rulesets (util/list-resources "/rulesets" #"([0-9a-z-_]+).txt") })
Handler for params request. If no request
passed, show empty params form.
If request
is passed, put parameters from request into session and show
the world page.
(defn process-rules-request [request] @@ -3337,7 +3364,7 @@ net.brehaut.ClojureTools = (function (SH) { " rules") }) true {:rule-text (or (session/get :rule-text) - (slurp "resources/rulesets/basic.txt")) + (io/slurp-resource "/rulesets/basic.txt")) :message "No rules found in request; loading defaults"}) (catch Exception e {:rule-text src @@ -3362,6 +3389,7 @@ net.brehaut.ClojureTools = (function (SH) { (rules-page nil)))
(ns mw-ui.util (:require [noir.io :as io] + [noir.session :as session] [markdown.core :as md]))
reads a markdown file from public/md and returns an HTML string
(defn md->html [filename] @@ -3370,8 +3398,11 @@ net.brehaut.ClojureTools = (function (SH) { (md/md-to-html-string)))
(defn list-resources [directory pattern] "List resource files matching `pattern` in `directory`." - (sort - (filter #(not (nil? %)) + (let + [path (str (io/resource-path) directory)] + (session/put! :list-resources-path path) + (sort + (filter #(not (nil? %)) (map #(first (rest (re-matches pattern (.getName %)))) - (file-seq (clojure.java.io/file directory))))))