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 cells 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))))))