![]() |
Even Smaller Snake
In 35 lines. (It had to be done.)
Here’s a take on Jeremy’s Snake, implemented in Clojure (a Lisp for the JVM). As you can see, I’m still using the same library classes. Only the language is different.
A major difference is that this is the whole application code, including incantations and setup. Excerpting the Snake-specific bits would make it shorter — maybe under 30 lines even.
Still, it is a little messy for the sake of brevity. With a more liberal style, it could be a neat 50-100 line Snake.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | (import '(java.awt.event KeyEvent ActionListener KeyListener) '(javax.swing JPanel JFrame Timer)) (defn gen-apple [] {:x (int (* 790 (. Math (random)))) :y (int (* 590 (. Math (random))))}) (def snake (ref {:body (list {:x 10 :y 10}) :dir {:x 10 :y 0}})) (def apple (ref (gen-apple))) (def dirs {(. KeyEvent VK_LEFT) {:x -10 :y 0} (. KeyEvent VK_RIGHT) {:x 10 :y 0} (. KeyEvent VK_UP) {:x 0 :y -10} (. KeyEvent VK_DOWN) {:x 0 :y 10}}) (defn move [{body :body dir :dir :as snake} & opts] (merge snake {:body (cons {:x (+ (:x dir) (:x (first body))) :y (+ (:y dir) (:y (first body)))} (if (:grow (apply hash-map opts)) body (butlast body)))})) (defn turn [snake newdir] (if newdir {:body (:body snake) :dir newdir} snake)) (defn collision? [{[b & bs] :body} a] (and (>= (+ 10 (:x b)) (:x a)) (<= (:x b) (+ 10 (:x a))) (>= (+ 10 (:y b)) (:y a)) (<= (:y b) (+ 10 (:y a))))) (defn run-snake [] (let [panel (proxy [JPanel ActionListener KeyListener] [] (paintComponent [g] (proxy-super paintComponent g) (. g (fillRect (:x @apple) (:y @apple) 10 10)) (doseq p (:body @snake) (. g (fillRect (:x p) (:y p) 10 10))) (if (collision? @snake @apple) (dosync (ref-set apple (gen-apple)) (alter snake move :grow true)))) (actionPerformed [e] (dosync (alter snake move)) (. this (repaint))) (keyPressed [e] (dosync (alter snake turn (get dirs (. e (getKeyCode)))))))] (doto panel (setFocusable true) (addKeyListener panel)) (doto (new JFrame "Snake") (add panel) (setSize 800 600) (setVisible true)) (. (new Timer 75 panel) (start)))) |
Edit: fixed per cgrand’s comment.



Dig
Dam you. I actually undustood the java version. This looks like a curry recipe.
Pfft, there’s hardly any currying going on there!
pretty slick. what do you need to do to compile it?
Zorab: what sort of curry do you eat? :S Or are you referring to the yellow and red bits
Nice!
There’s an error (dir instead of newdir) in the definition of turn:
(defn turn [snake newdir] (if newdir {:body (:body snake) :dir newdir} snake))