Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@laurentpetit
Created November 8, 2012 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save laurentpetit/4038525 to your computer and use it in GitHub Desktop.
Save laurentpetit/4038525 to your computer and use it in GitHub Desktop.
Memento du déroulé Agile Grenoble 2012
(ns agile.life
(:use [clojure.pprint :only [pprint]]))
;; cell representation
(pprint [2 2])
;; game state representation
#{[2 2] [3 2]}
;; game initial state ("blinker")
(def init #{[2 2] [3 2] [4 2]})
; translation for left neighbour
[-1 0]
; left neighbour
[(+ 3 -1) (+ 2 0)]
(defn add [[x y] [dx dy]]
[(+ x dx) (+ y dy)])
(add [3 2] [-1 0])
;; relative positions of neighbors
(def directions #{[-1 1] [ 0 1] [ 1 1]
[-1 0] [ 1 0]
[-1 -1] [ 0 -1] [ 1 -1]})
(map (fn [direction] (add [3 2] direction)) directions)
;; compute neighbors of a cell
(defn neighbours [cell]
(map
(fn [direction] (add cell direction))
directions))
(neighbours [3 2])
(map neighbours init)
(pprint (map neighbours init))
(mapcat neighbours init)
(pprint (mapcat neighbours init))
(pprint (set (mapcat neighbours init)))
(frequencies (mapcat neighbours init))
(pprint (frequencies (mapcat neighbours init)))
;;
(defn live? [alive? n-live-neighbours]
(or (= n-live-neighbours 3)
(and (= n-live-neighbours 2) alive?)))
(live? false 3)
(live? false 2)
(live? true 3)
(live? true 2)
(live? true 0)
;; is a cell alive?
(contains? init [2 2])
(get init [2 2])
(init [2 2])
(init [0 0])
;; putting it all together
(for [[cell n] (frequencies (mapcat neighbours init))
:when (live? (init cell) n)]
cell)
(set (for [[cell n] (frequencies (mapcat neighbours init))
:when (live? (init cell) n)]
cell))
(defn step [cells]
(set (for [[cell n] (frequencies (mapcat neighbours cells))
:when (live? (cells cell) n)]
cell)))
init
(step init)
(step (step init))
(pprint (take 5 (iterate step init)))
(def glider #{[2 2] [3 3] [4 1] [4 2] [4 3]})
(pprint (take 5 (iterate step glider)))
;; Pour ajouter un visualiseur Swing
;;
;; 1. coller ce texte à la fin de votre namespace mixit.life
;; 2. evaluer
;; 3. demarrer un visualiseur swing :
;; (swing-board board 7 5)
;; 4. attention, la fenetre swing est peut etre cachee derriere votre fenetre Eclipse
;; 5. lancer l'animation en calculant 10 générations à partir de l'état init :
;; (play init 20)
(defn str-board
"Represente les cells dans une chaîne
de caractères de largeur w et de hauteur
h."
[cells w h]
(apply str (for [y (range h)
x (range (inc w))]
(cond
(= x w) \newline
(cells [x y]) \O
:else \.))))
(defn pb
"Fonction utilitaire pour afficher
les cellules vivantes pour la plage
7 5"
[cells]
(print (str-board cells 7 5)))
(def poll-period 40)
(def continue? true)
(defn swing-board
"Affiche la plage [w h] de cellules vivantes dans un
TextArea Swing, en allant toutes les poll-period millisecondes
recuperer la valeur de r et en l'affichant."
[r w h]
(let [t (doto (javax.swing.JTextArea. "" h w)
(.setFont (java.awt.Font/decode "Monospaced 48")))
j (doto (javax.swing.JFrame. "Jeu de la vie")
(.add t)
.pack
.show)]
(future (while continue?
(Thread/sleep poll-period)
(.setText t (str-board @r w h))))))
(def board "atom dans lequel on stocke la valeur courante a afficher"
(atom #{}))
(def sleep "Temps d'attente(ms) avant de calculer l'etat suivant du jeu"
200)
(defn play
"En partant d'un etat initial init du jeu, calcule times etats
suivants, et met a jour la variable board a intervalles sleep."
[init times]
(future
(reset! board init)
(dotimes [_ times]
(Thread/sleep sleep)
(swap! board step))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment