Permalink
Browse files

convert README to Markdown; update endline characters

  • Loading branch information...
1 parent 0594c49 commit 5fe97b6aade2bb047b7a51429c0c11637e5e9480 @bitsai committed Oct 7, 2011
Showing with 183 additions and 185 deletions.
  1. +0 −11 README
  2. +9 −0 README.md
  3. +87 −87 engine.clj
  4. +75 −75 gui.clj
  5. +5 −5 light_cycle.clj
  6. +7 −7 win_fns.clj
View
@@ -1,11 +0,0 @@
-A simple Tron light cycle game in Clojure, inspired by the Snake example in Programming Clojure and Google's Tron AI Challenge:
-http://pragprog.com/titles/shcloj/programming-clojure
-http://csclub.uwaterloo.ca/contest/
-
-Current gameplay is Free-For-All between 2 humans and 2 bots:
-- Player 1 controls the yellow light cycle using WASD.
-- Player 2 controls the blue light cycle using the arrow keys.
-- Right now, the bots are not very smart. They simply choose a random open adjacent square, with a bias for going straight if possible.
-
-To start the game, assuming . is on the class path, just run light_cycle.clj:
-clj light_cycle.clj
View
@@ -0,0 +1,9 @@
+A simple Tron light cycle game in Clojure, inspired by the Snake example in [Programming Clojure](http://pragprog.com/titles/shcloj/programming-clojure) and [Google's Tron AI Challenge](http://csclub.uwaterloo.ca/contest/).
+
+Current gameplay is Free-For-All between 2 humans and 2 bots:
+* Player 1 controls the yellow light cycle using WASD.
+* Player 2 controls the blue light cycle using the arrow keys.
+* Right now, the bots are not very smart. They simply choose a random open adjacent square, with a bias for going straight if possible.
+
+To start the game, run light_cycle.clj:
+ clj light_cycle.clj
View
@@ -1,87 +1,87 @@
-(ns engine
- (:import (java.awt Color)))
-
-(def width 75)
-(def height 50)
-(def point-size 10)
-(def turn-millis 75)
-
-(def black (Color. 0 0 0))
-(def blue (Color. 0 0 255))
-(def red (Color. 255 0 0))
-(def yellow (Color. 255 255 0))
-(def white (Color. 255 255 255))
-
-(defn add-points [& pts]
- (vec (apply map + pts)))
-
-(defn create-cycle [name pt dir color move-fn]
- {:name name
- :trail [pt]
- :dir dir
- :color color
- :move-fn move-fn})
-
-(defn hit-wall? [{[[x y] & _] :trail}]
- (or
- (neg? x)
- (neg? y)
- (> x width)
- (> y height)))
-
-(defn hit-trail? [{[pt & trail] :trail :as cycle} cycles]
- (let [other-cycles (disj (set cycles) cycle)
- other-trails (mapcat :trail other-cycles)
- trails (concat trail other-trails)]
- (some #{pt} trails)))
-
-(defn dead? [cycle cycles]
- (or
- (hit-wall? cycle)
- (hit-trail? cycle cycles)))
-
-(defn turn [{[cur-pt prev-pt & _] :trail :as cycle} new-dir]
- (let [new-pt (add-points new-dir cur-pt)]
- (if (= new-pt prev-pt) cycle
- (assoc cycle :dir new-dir))))
-
-(defn move [{:keys [trail dir] :as cycle} cycles]
- (let [new-pt (add-points dir (first trail))
- new-trail (cons new-pt trail)]
- (assoc cycle :trail new-trail)))
-
-;; AI bot move function
-(defn move-random [cycle cycles]
- (let [dirs [[0 -1] [-1 0] [0 1] [1 0]]
- biased-dirs (concat dirs (repeat 8 (:dir cycle)))
- make-move #(move (turn cycle %) cycles)
- next-moves (map make-move biased-dirs)
- valid-moves (remove #(dead? % cycles) next-moves)]
- (if-not (empty? valid-moves) (rand-nth valid-moves)
- (move cycle cycles))))
-
-(defn create-cycles []
- [(create-cycle "Player 1" [37 50] [0 -1] yellow move)
- (create-cycle "Player 2" [37 0] [0 1] blue move)
- (create-cycle "Rand 1" [0 24] [1 0] red move-random)
- (create-cycle "Rand 2" [75 24] [-1 0] red move-random)])
-
-;; mutable state ahead
-(defn reset-game [cycles-ref]
- (dosync (ref-set cycles-ref (create-cycles))))
-
-(defn update-direction [cycles-ref name new-dir]
- (let [old-cycle (first (filter #(= name (:name %)) @cycles-ref))
- new-cycle (turn old-cycle new-dir)
- replace-cycle (partial replace {old-cycle new-cycle})]
- (dosync (alter cycles-ref replace-cycle))))
-
-(defn update-positions [cycles-ref]
- (let [cycles @cycles-ref
- apply-move-fns (partial map #((:move-fn %) % cycles))]
- (dosync (alter cycles-ref apply-move-fns))))
-
-(defn clear-dead [cycles-ref]
- (let [cycles @cycles-ref
- remove-dead (partial remove #(dead? % cycles))]
- (dosync (alter cycles-ref remove-dead))))
+(ns engine
+ (:import (java.awt Color)))
+
+(def width 75)
+(def height 50)
+(def point-size 10)
+(def turn-millis 75)
+
+(def black (Color. 0 0 0))
+(def blue (Color. 0 0 255))
+(def red (Color. 255 0 0))
+(def yellow (Color. 255 255 0))
+(def white (Color. 255 255 255))
+
+(defn add-points [& pts]
+ (vec (apply map + pts)))
+
+(defn create-cycle [name pt dir color move-fn]
+ {:name name
+ :trail [pt]
+ :dir dir
+ :color color
+ :move-fn move-fn})
+
+(defn hit-wall? [{[[x y] & _] :trail}]
+ (or
+ (neg? x)
+ (neg? y)
+ (> x width)
+ (> y height)))
+
+(defn hit-trail? [{[pt & trail] :trail :as cycle} cycles]
+ (let [other-cycles (disj (set cycles) cycle)
+ other-trails (mapcat :trail other-cycles)
+ trails (concat trail other-trails)]
+ (some #{pt} trails)))
+
+(defn dead? [cycle cycles]
+ (or
+ (hit-wall? cycle)
+ (hit-trail? cycle cycles)))
+
+(defn turn [{[cur-pt prev-pt & _] :trail :as cycle} new-dir]
+ (let [new-pt (add-points new-dir cur-pt)]
+ (if (= new-pt prev-pt) cycle
+ (assoc cycle :dir new-dir))))
+
+(defn move [{:keys [trail dir] :as cycle} cycles]
+ (let [new-pt (add-points dir (first trail))
+ new-trail (cons new-pt trail)]
+ (assoc cycle :trail new-trail)))
+
+;; AI bot move function
+(defn move-random [cycle cycles]
+ (let [dirs [[0 -1] [-1 0] [0 1] [1 0]]
+ biased-dirs (concat dirs (repeat 8 (:dir cycle)))
+ make-move #(move (turn cycle %) cycles)
+ next-moves (map make-move biased-dirs)
+ valid-moves (remove #(dead? % cycles) next-moves)]
+ (if-not (empty? valid-moves) (rand-nth valid-moves)
+ (move cycle cycles))))
+
+(defn create-cycles []
+ [(create-cycle "Player 1" [37 50] [0 -1] yellow move)
+ (create-cycle "Player 2" [37 0] [0 1] blue move)
+ (create-cycle "Rand 1" [0 24] [1 0] red move-random)
+ (create-cycle "Rand 2" [75 24] [-1 0] red move-random)])
+
+;; mutable state ahead
+(defn reset-game [cycles-ref]
+ (dosync (ref-set cycles-ref (create-cycles))))
+
+(defn update-direction [cycles-ref name new-dir]
+ (let [old-cycle (first (filter #(= name (:name %)) @cycles-ref))
+ new-cycle (turn old-cycle new-dir)
+ replace-cycle (partial replace {old-cycle new-cycle})]
+ (dosync (alter cycles-ref replace-cycle))))
+
+(defn update-positions [cycles-ref]
+ (let [cycles @cycles-ref
+ apply-move-fns (partial map #((:move-fn %) % cycles))]
+ (dosync (alter cycles-ref apply-move-fns))))
+
+(defn clear-dead [cycles-ref]
+ (let [cycles @cycles-ref
+ remove-dead (partial remove #(dead? % cycles))]
+ (dosync (alter cycles-ref remove-dead))))
View
@@ -1,75 +1,75 @@
-(ns gui
- (:use [engine])
- (:import (java.awt Dimension)
- (java.awt.event ActionListener KeyEvent KeyListener)
- (javax.swing JFrame JOptionPane JPanel Timer)))
-
-(def p1-dirs {KeyEvent/VK_W [ 0 -1]
- KeyEvent/VK_A [-1 0]
- KeyEvent/VK_S [ 0 1]
- KeyEvent/VK_D [ 1 0]})
-
-(def p2-dirs {KeyEvent/VK_UP [ 0 -1]
- KeyEvent/VK_LEFT [-1 0]
- KeyEvent/VK_DOWN [ 0 1]
- KeyEvent/VK_RIGHT [ 1 0]})
-
-(defn point-to-screen-rect [[x y]]
- (map #(* point-size %) [x y 1 1]))
-
-(defn fill-point [g pt color]
- (let [[x y width height] (point-to-screen-rect pt)]
- (.setColor g color)
- (.fillRect g x y width height)))
-
-(defn paint-cycles [g cycles]
- (doseq [{:keys [trail color]} cycles]
- (doseq [point trail]
- (fill-point g point color))))
-
-(defn paint-hits [g cycles]
- (doseq [{[pt & _] :trail :as cycle} cycles]
- (if (hit-trail? cycle cycles) (fill-point g pt white))))
-
-(defn game-panel [frame win-fn cycles-ref]
- (proxy [JPanel ActionListener KeyListener] []
- (paintComponent [g]
- (proxy-super paintComponent g)
- (paint-cycles g @cycles-ref)
- (paint-hits g @cycles-ref))
- (actionPerformed [e]
- (clear-dead cycles-ref)
- (update-positions cycles-ref)
- (let [win-msg (win-fn @cycles-ref)]
- (when win-msg
- (reset-game cycles-ref)
- (JOptionPane/showMessageDialog frame win-msg)))
- (.repaint this))
- (keyPressed [e]
- (let [p1-dir (p1-dirs (.getKeyCode e))
- p2-dir (p2-dirs (.getKeyCode e))]
- (cond
- p1-dir (update-direction cycles-ref "Player 1" p1-dir)
- p2-dir (update-direction cycles-ref "Player 2" p2-dir))))
- (getPreferredSize []
- (Dimension. (* (inc width) point-size)
- (* (inc height) point-size)))
- (keyReleased [e])
- (keyTyped [e])))
-
-(defn game [win-fn]
- (let [cycles-ref (ref (create-cycles))
- frame (JFrame. "Light Cycle")
- panel (game-panel frame win-fn cycles-ref)
- timer (Timer. turn-millis panel)]
- (doto panel
- (.addKeyListener panel)
- (.setBackground black)
- (.setFocusable true))
- (doto frame
- (.add panel)
- (.pack)
- (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
- (.setVisible true))
- (.start timer)
- [cycles-ref timer]))
+(ns gui
+ (:use [engine])
+ (:import (java.awt Dimension)
+ (java.awt.event ActionListener KeyEvent KeyListener)
+ (javax.swing JFrame JOptionPane JPanel Timer)))
+
+(def p1-dirs {KeyEvent/VK_W [ 0 -1]
+ KeyEvent/VK_A [-1 0]
+ KeyEvent/VK_S [ 0 1]
+ KeyEvent/VK_D [ 1 0]})
+
+(def p2-dirs {KeyEvent/VK_UP [ 0 -1]
+ KeyEvent/VK_LEFT [-1 0]
+ KeyEvent/VK_DOWN [ 0 1]
+ KeyEvent/VK_RIGHT [ 1 0]})
+
+(defn point-to-screen-rect [[x y]]
+ (map #(* point-size %) [x y 1 1]))
+
+(defn fill-point [g pt color]
+ (let [[x y width height] (point-to-screen-rect pt)]
+ (.setColor g color)
+ (.fillRect g x y width height)))
+
+(defn paint-cycles [g cycles]
+ (doseq [{:keys [trail color]} cycles]
+ (doseq [point trail]
+ (fill-point g point color))))
+
+(defn paint-hits [g cycles]
+ (doseq [{[pt & _] :trail :as cycle} cycles]
+ (if (hit-trail? cycle cycles) (fill-point g pt white))))
+
+(defn game-panel [frame win-fn cycles-ref]
+ (proxy [JPanel ActionListener KeyListener] []
+ (paintComponent [g]
+ (proxy-super paintComponent g)
+ (paint-cycles g @cycles-ref)
+ (paint-hits g @cycles-ref))
+ (actionPerformed [e]
+ (clear-dead cycles-ref)
+ (update-positions cycles-ref)
+ (let [win-msg (win-fn @cycles-ref)]
+ (when win-msg
+ (reset-game cycles-ref)
+ (JOptionPane/showMessageDialog frame win-msg)))
+ (.repaint this))
+ (keyPressed [e]
+ (let [p1-dir (p1-dirs (.getKeyCode e))
+ p2-dir (p2-dirs (.getKeyCode e))]
+ (cond
+ p1-dir (update-direction cycles-ref "Player 1" p1-dir)
+ p2-dir (update-direction cycles-ref "Player 2" p2-dir))))
+ (getPreferredSize []
+ (Dimension. (* (inc width) point-size)
+ (* (inc height) point-size)))
+ (keyReleased [e])
+ (keyTyped [e])))
+
+(defn game [win-fn]
+ (let [cycles-ref (ref (create-cycles))
+ frame (JFrame. "Light Cycle")
+ panel (game-panel frame win-fn cycles-ref)
+ timer (Timer. turn-millis panel)]
+ (doto panel
+ (.addKeyListener panel)
+ (.setBackground black)
+ (.setFocusable true))
+ (doto frame
+ (.add panel)
+ (.pack)
+ (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
+ (.setVisible true))
+ (.start timer)
+ [cycles-ref timer]))
View
@@ -1,5 +1,5 @@
-(ns light-cycle
- (:use [gui :only (game)])
- (:use [win-fns :only (ffa-win-fn)]))
-
-(game ffa-win-fn)
+(ns light-cycle
+ (:use [gui :only (game)])
+ (:use [win-fns :only (ffa-win-fn)]))
+
+(game ffa-win-fn)
View
@@ -1,7 +1,7 @@
-(ns win-fns)
-
-(defn ffa-win-fn [cycles]
- (case (count cycles)
- 1 (str (:name (first cycles)) " wins!")
- 0 "Tie!"
- nil))
+(ns win-fns)
+
+(defn ffa-win-fn [cycles]
+ (case (count cycles)
+ 1 (str (:name (first cycles)) " wins!")
+ 0 "Tie!"
+ nil))

0 comments on commit 5fe97b6

Please sign in to comment.