Guest User

oranenj

a guest
Nov 17th, 2008
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.15 KB | None | 0 0
  1. (defn has-winner? [board]
  2.   (let [size (int (Math/sqrt (count board)))
  3.     wins (generate-wins size)
  4.         sum-wins (fn [board]
  5.                        (map #(sum-indexes board %) wins))]
  6.     (> (count
  7.         (filter #(or (= % size) (= % (* 9 size)))
  8.                 (sum-wins board)))
  9.     0)))
  10.  
  11. (defn generate-rows [size]
  12.   (let [gen-row (fn [idx] (take size (iterate inc idx)))]
  13.   (map gen-row (take size (iterate #(+ size %) 0)))))
  14.  
  15. (defn generate-cols [size]
  16.   (let [gen-row (fn [idx] (take size (iterate #(+ size %) idx)))]
  17.     (map gen-row (take size (iterate inc 0)))))
  18.  
  19. (defn generate-throughs [size]
  20.   (conj nil (take size (iterate #(+ 1 size %) 0))
  21.             (take size (iterate #(+ -1 size %) (- size 1)))))
  22.  
  23. (defn generate-wins [size]
  24.   (concat (generate-rows size) (generate-cols size) (generate-throughs size)))
  25.  
  26. (defn sum-indexes [board indexes]
  27.   (apply + (map #(board %) indexes)))
  28.  
  29. (defn valid-move? [pos board]
  30.   (let [val (nth board pos 1)]
  31.     (and (not= val 1)
  32.          (not= val 9))))
  33.  
  34. (defn print-board [board]
  35.   (doseq [part (partition (int (Math/sqrt (count board))) board)] (println part)))
  36.  
  37. (defmulti move (fn [player board] player))
  38.  
  39. (defmethod move :com [player board]
  40.   (println "Computer moves")
  41.   (loop [mov (Math/round (* (rand) 8))]
  42.     (if (valid-move? mov board)
  43.       (assoc board mov 9)
  44.       (recur (Math/round (* (rand) 8))))))
  45.  
  46. (defmethod move :player [player board]
  47.   (println "Player moves")
  48.   (loop [mov (Integer. (read-line))]
  49.     (if (valid-move? mov board)
  50.       (assoc board mov 1)
  51.       (do
  52.     (println "Invalid move. Move again.")
  53.     (recur (Integer. (read-line)))))))
  54.  
  55. (defmulti player-name identity)
  56. (defmethod player-name :com [player]
  57.   "Computer")
  58. (defmethod player-name :player [player]
  59.   "Player")
  60.  
  61. (defn next-player [player]
  62.   (if (= player :player)
  63.     :com
  64.     :player))
  65.  
  66. (defn play-turn [player board]
  67.   (let [new-board (move player board)]
  68.     (print-board new-board)
  69.     (if (has-winner? new-board)
  70.       (println (player-name player) "won!")
  71.       (recur (next-player player) new-board))))
  72.  
  73. (defn run [size]
  74.   (let [empty-board (into [] (take (* size size) (repeat 0)))]
  75.     (print-board empty-board)
  76.     (play-turn :player empty-board)))
  77.  
Advertisement
Add Comment
Please, Sign In to add comment