92c64081b5f8

Animals and water and more!
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 12 Dec 2015 17:54:05 +0000
parents dee99c486fc1
children bf284ae6d81f
branches/tags (none)
files src/silt/core.clj

Changes

--- a/src/silt/core.clj	Sat Dec 12 15:44:46 2015 +0000
+++ b/src/silt/core.clj	Sat Dec 12 17:54:05 2015 +0000
@@ -6,25 +6,40 @@
 
 
 ; Data ------------------------------------------------------------------------
-(def fps 20)
+(def fps 10)
 (def world-width 600)
 (def world-height 400)
 
+(def pond-count 100)
+(def pond-size 3)
+
 (def screen (s/get-screen :swing))
 (defonce running (atom true))
 (def window-loc (ref [0 0]))
 (defonce last-timestamp (atom 0))
 
 (defonce terrain (ref []))
-(def terrain-rate 1)
+(def terrain-rate 2)
 (def terrain-objects
-  [{:name :rock :glyph "*"}
-   {:name :shrub :glyph "%"}])
+  {{:name :rock :glyph "*"} 20
+   {:name :shrub :glyph "%" :styles {:fg :green}
+    :energy 0.1} 80})
+
+(def landmarks
+  (ref #{{:name :monolith :glyph "#" :loc [0 0] :styles {:fg :black :bg :yellow}}
+         {:name :colossus :glyph "@" :loc [200 100] :styles {:fg :black :bg :red}}}))
+
 
-(def landmarks (ref
-                 #{{:name :monolith :glyph "#" :loc [0 0] :styles {:fg :black :bg :yellow}}
-                   {:name :colossus :glyph "@" :loc [200 100] :styles {:fg :black :bg :red}}
-                   }))
+(def world-temp (ref 0))
+(def mutation-chance 1)
+
+(def eve
+  {:glyph "@"
+   :styles {:fg :white}
+   :temp 0
+   :insulation 0
+   :age 0
+   :energy 100.0})
 
 
 ; Utils -----------------------------------------------------------------------
@@ -34,23 +49,10 @@
        ~@body
        (recur))))
 
-
-; World Generation ------------------------------------------------------------
-(defn generate-terrain []
-  (for [x (range world-width)
-        y (range world-height)
-        :when (rr/rand-bool terrain-rate)]
-    (assoc (rr/rand-nth terrain-objects)
-           :loc [x y])))
+(defn random-coord []
+  [(rr/rand-int 0 world-width)
+   (rr/rand-int 0 world-height)])
 
-(defn reset-terrain! []
-  (let [new-terrain (generate-terrain)]
-    (dosync
-      (ref-set terrain new-terrain))
-    nil))
-
-
-; Drawing ---------------------------------------------------------------------
 (defn normalize-coord [v limit]
   (cond
     (< v 0) (normalize-coord (+ limit v) limit)
@@ -61,17 +63,84 @@
   [(normalize-coord wx world-width)
    (normalize-coord wy world-height)])
 
+(defmacro maybe [chance value & body]
+  `(fn [~value]
+     (if (rr/rand-bool ~chance)
+       (do ~@body)
+       ~value)))
+
+
+; World Generation ------------------------------------------------------------
+(defn generate-terrain []
+  (for [x (range world-width)
+        y (range world-height)
+        :when (rr/rand-bool terrain-rate)]
+    (assoc (rr/rand-nth-weighted terrain-objects)
+           :loc [x y])))
+
+(defn generate-pond [[ox oy]]
+  (for [_ (range 200)
+            :let [x (rr/rand-gaussian-int ox (* pond-size 1.5))
+                  y (rr/rand-gaussian-int oy pond-size)]]
+    {:name :water
+     :glyph "≈"
+     :energy 0.1
+     :loc (normalize-world-coords [x y])
+     :styles {:fg :black :bg :blue}}))
+
+(defn generate-water []
+  (->> (for [_ (range pond-count)]
+         (generate-pond (random-coord)))
+    (into #{})
+    (apply concat)))
+
+(defn dedupe-terrain [terrain]
+  (->> (for [{:keys [loc] :as t} terrain]
+         [loc t])
+    (into {})
+    vals))
+
+(defn reset-terrain! []
+  (let [new-terrain (-> (generate-terrain)
+                      (into (generate-water))
+                      dedupe-terrain)]
+    (dosync
+      (ref-set terrain new-terrain))
+    nil))
+
+
+; Animals ---------------------------------------------------------------------
+(defn can-reproduce [animal]
+  (> (:energy animal) 50))
+
+(defn clone [animal]
+  (-> animal
+    (assoc :age 0)
+    (assoc :energy 50)
+    (update-in [:insulation]
+               (maybe mutation-chance v
+                      (+ v (rand-nth [-1 1]))))
+    (update-in [:styles :fg]
+               (maybe mutation-chance v
+                      (rr/rand-nth [:white :blue :green :yellow :red])))))
+
+(defn reproduce [animal]
+  [(update-in animal [:energy] #(- % 40))
+   (clone animal)])
+
+
+; Drawing ---------------------------------------------------------------------
 (defn calc-screen-coords [[wx wy]]
   (let [[ox oy] @window-loc]
     (normalize-world-coords [(- wx ox) (- wy oy)])))
 
 (defn draw-terrain! [screen]
   (let [[swidth sheight] (s/get-size screen)]
-    (doseq [{:keys [loc glyph]} @terrain
+    (doseq [{:keys [loc glyph styles]} @terrain
             :let [[sx sy] (calc-screen-coords loc)]
             :when (and (< -1 sx swidth)
                        (< -1 sy sheight))]
-      (s/put-string screen sx sy glyph))))
+      (s/put-string screen sx sy glyph styles))))
 
 (defn draw-landmarks! [screen]
   (let [[swidth sheight] (s/get-size screen)]
@@ -81,32 +150,41 @@
                        (< -1 sy sheight))]
       (s/put-string screen sx sy glyph styles))))
 
+(defn from-right [screen n]
+  (- (nth (s/get-size screen) 0) n))
+
 (defn draw-screen! [screen]
-  (s/clear screen)
-  (draw-terrain! screen)
-  (draw-landmarks! screen)
-  (s/put-string screen (- (nth (s/get-size screen) 0) 7) 0 " SILT ")
-  (s/move-cursor screen (- (nth (s/get-size screen) 0) 6) 0)
-  (s/redraw screen))
+  (letfn [(put-right [s y]
+            (s/put-string screen (from-right screen (.length s)) y s))]
+    (s/clear screen)
+    (draw-terrain! screen)
+    (draw-landmarks! screen)
+    (put-right " SILT  " 0)
+    (put-right (str @world-temp "° ") 1)
+    (s/move-cursor screen (from-right screen 1) 0)
+    (s/redraw screen)))
 
 
 ; Input -----------------------------------------------------------------------
-(defn move-window! [key]
-  (dosync
-    (commute window-loc
-             #(let [[x y] %1]
-                (case %2
-                  :up [x (dec y)]
-                  :down [x (inc y)]
-                  :left [(dec x) y]
-                  :right [(inc x) y]))
-             key)))
+(defn move-window!
+  ([key] (move-window! key 1))
+  ([key scale]
+   (dosync
+     (commute window-loc
+              #(let [[x y] %1]
+                 (case %2
+                   (:up \k) [x (- y scale)]
+                   (:down \j) [x (+ y scale)]
+                   (:left \h) [(- x scale) y]
+                   (:right \l) [(+ x scale) y]))
+              key))))
 
 (defn handle-input! [screen]
   (while-let [key (s/get-key screen)]
     (case key
       :escape (reset! running false)
-      (:up :down :left :right) (move-window! key)
+      (:up :down :left :right) (move-window! key 10)
+      (\h \j \k \l) (move-window! key)
       nil)))
 
 
@@ -139,6 +217,7 @@
 (comment
   (reset! running false)
   (reset! running true)
+  (dosync (ref-set world-temp 0))
 
   (reset-terrain!)