342 lines
21 KiB
HTML
342 lines
21 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/world.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns ^{:doc "Functions to create and to print two dimensional cellular automata.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003 Nothing in this namespace should determine what states are possible within
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 the automaton, except for the initial state, :new.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
005
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006 A cell is a map containing at least values for the keys `:x`, `:y`, and `:state`.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
007
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008 A world is a two dimensional matrix (sequence of sequences) of cells, such
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 that every cell's `:x` and `:y` properties reflect its place in the matrix."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
010 :author "Simon Brooke"}
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
011 mw-engine.world
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
012 (:require [clojure.string :as string]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
013 [mw-engine.utils :refer [population]]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
014
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
017 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
018 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
019 ;;;; This program is free software; you can redistribute it and/or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
020 ;;;; modify it under the terms of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
021 ;;;; as published by the Free Software Foundation; either version 2
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
022 ;;;; of the License, or (at your option) any later version.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
023 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
024 ;;;; This program is distributed in the hope that it will be useful,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
025 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
026 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 ;;;; GNU General Public License for more details.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
028 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
029 ;;;; You should have received a copy of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 ;;;; along with this program; if not, write to the Free Software
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
031 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
032 ;;;; USA.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
033 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 ;;;; Copyright (C) 2014 Simon Brooke
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
035 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
037
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
038 (defn cell?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
039 "Return `true` if `obj` is a cell, as understood by MicroWorld, else `false`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
040 [obj]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 16 forms covered">
|
|
041 (and (map? obj) ;; it's a map...
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
042 ;; TODO: it's worth checking (and this does not) that cells have the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
043 ;; right co-ordinates!
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
044 (pos-int? (:x obj)) ;; with an x co-ordinate...
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
045 (pos-int? (:y obj)) ;; and a y co-ordinate...
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
046 (keyword? (:state obj)))) ;; and a state which is a keyword.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
047
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
048 (defn world?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
049 "Return `true` if `obj` is a world, as understood by MicroWorld, else `false`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
050 [obj]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 16 forms covered">
|
|
051 (and (coll? obj) ;; it's a collection...
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
052 (every? coll? obj) ;; of collections...
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 9 forms covered">
|
|
053 (= 1 (count (set (map count obj)))) ;; all of which are the same length...
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
054 (every? cell? (flatten obj)))) ;; and every element of each of those is a cell.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
055
|
|
</span><br/>
|
|
<span class="covered" title="30 out of 30 forms covered">
|
|
056 (defmacro make-cell
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
057 "Create a minimal default cell at x, y
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
058
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
059 * `x` the x coordinate at which this cell is created;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
060 * `y` the y coordinate at which this cell is created."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
061 [x y]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
062 `{:x ~x :y ~y :state :new})
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
063
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
064 (defn make-world
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
065 "Make a world width cells from east to west, and height cells from north to
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
066 south.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
067
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
068 * `width` a natural number representing the width of the matrix to be created;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
069 * `height` a natural number representing the height of the matrix to be created."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
070 [width height]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
071 (apply vector
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
072 (map (fn [h]
|
|
</span><br/>
|
|
<span class="covered" title="16 out of 16 forms covered">
|
|
073 (apply vector (map #(make-cell % h) (range width))))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
074 (range height))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
075
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
076 (defn truncate-state
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
077 "Truncate the print name of the state of this cell to at most limit characters."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
078 [cell limit]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
079 (let [s (:state cell)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
080 (try
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 15 forms covered">
|
|
081 (cond (> (count (str s)) limit) (subs (name s) 0 limit)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
082 :else s)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
083 (catch Exception any
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
084 (throw (ex-info (.getMessage any)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
085 {:cell cell
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
086 :limit limit
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
087 :exception-class (.getClass any)}))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
088
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
089 (defn format-cell
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
090 "Return a formatted string summarising the current state of this cell."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
091 [cell]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
092 (format "%10s"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
093 (truncate-state cell 10)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
094
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
095 (defn- format-world-row
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
096 "Format one row in the state of a world for printing."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
097 [row]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
098 (string/join (map format-cell row)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
099
|
|
</span><br/>
|
|
<span class="partial" title="1 out of 2 forms covered">
|
|
100 (defn print-world
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
101 "Print the current state of this world, and return nil.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
102
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
103 * `world` a world as defined above."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
104 [world]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
105 (println)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
106 (dorun
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
107 (map
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
108 #(println
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
109 (format-world-row %))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
110 world))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
111 nil)
|
|
</span><br/>
|
|
</body>
|
|
</html>
|