Snakes and Ladders game built during code jugalbandhi at functional conf (http://confengine.com/functional-conf-2015/schedule#session-7464-info)
(ns snl.core | |
(:require [clojure.string :as str] | |
[clojure.pprint :as pp])) | |
(defonce game-state (atom {:players [] :board nil})) | |
(defn board! [] (:board @game-state)) | |
(defn players! [] (:players @game-state)) | |
(defn snakes! [] (:snakes (:board @game-state))) | |
(defn ladders! [] (:ladders (:board @game-state))) | |
(defn snake [size _] | |
(let [sq1 (rand-int size)] | |
[sq1 (inc (rand-int sq1))])) | |
(defn ladder [size _] | |
(let [sq1 (rand-int size) | |
sq2 (+ sq1 (rand-int (- size sq1)))] | |
[sq1 sq2])) | |
(defn generate-board [n] | |
(let [num-cells (* n n) | |
snakes (into {} (map (partial snake num-cells) (range n))) | |
ladders (into {} (map (partial ladder num-cells) (range n)))] | |
{:num-cells num-cells :snakes snakes :ladders ladders})) | |
(defn next-pos [from num-cells] | |
(let [new-pos (+ from (inc (rand-int 6)))] | |
(if (< new-pos num-cells) new-pos from))) | |
(defn is-winning-move? [new-pos] | |
(= new-pos (dec (:num-cells (:board @game-state))))) | |
(defn move! [from] | |
(let [new-pos (next-pos from ((board!) :num-cells)) | |
ladder-pos (get (ladders!) new-pos) | |
snake-pos (get (snakes!) new-pos)] | |
(or snake-pos ladder-pos new-pos))) | |
(defn init-game! [board-size num-players] | |
(let [players (into [] (repeat num-players 0)) | |
board (generate-board board-size)] | |
(reset! game-state {:players players :board board}))) | |
(defn play! [] | |
(while (not-any? is-winning-move? (players!)) | |
(let [positions (map move! (@game-state :players))] | |
(swap! game-state assoc :players positions) | |
(pp/pprint positions)))) | |
(defn -main [] | |
(init-game! 20 5) | |
(play!)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment