Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
78
Task/Minesweeper-game/Clojure/minesweeper-game.clj
Normal file
78
Task/Minesweeper-game/Clojure/minesweeper-game.clj
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
(defn take-random [n coll]
|
||||
(->> (repeatedly #(rand-nth coll))
|
||||
distinct
|
||||
(take n ,)))
|
||||
|
||||
(defn postwalk-fs
|
||||
"Depth first post-order traversal of form, apply successive fs at each level.
|
||||
(f1 (map f2 [..]))"
|
||||
[[f & fs] form]
|
||||
(f
|
||||
(if (and (seq fs) (coll? form))
|
||||
(into (empty form) (map (partial postwalk-fs fs) form))
|
||||
form)))
|
||||
|
||||
(defn neighbors [x y n m pred]
|
||||
(for [dx (range (Math/max 0 (dec x)) (Math/min n (+ 2 x)))
|
||||
dy (range (Math/max 0 (dec y)) (Math/min m (+ 2 y)))
|
||||
:when (pred dx dy)]
|
||||
[dx dy]))
|
||||
|
||||
(defn new-game [n m density]
|
||||
(let [mines (set (take-random (Math/floor (* n m density)) (range (* n m))))]
|
||||
(->> (for [y (range m)
|
||||
x (range n)
|
||||
:let [neighbor-mines (count (neighbors x y n m #(mines (+ %1 (* %2 n)))))]]
|
||||
(#(if (mines (+ (* y n) x)) (assoc % :mine true) %) {:value neighbor-mines}))
|
||||
(partition n ,)
|
||||
(postwalk-fs [vec vec] ,))))
|
||||
|
||||
(defn display [board]
|
||||
(postwalk-fs [identity println #(condp % nil
|
||||
:marked \?
|
||||
:opened (:value %)
|
||||
\.)] board))
|
||||
|
||||
(defn boom [{board :board}]
|
||||
(postwalk-fs [identity println #(if (:mine %) \* (:value %))] board)
|
||||
true)
|
||||
|
||||
(defn open* [board [[x y] & rest]]
|
||||
(if-let [value (get-in board [y x :value])] ; if nil? value -> nil? x -> nil? queue
|
||||
(recur
|
||||
(assoc-in board [y x :opened] true)
|
||||
(if (pos? value)
|
||||
rest
|
||||
(concat rest
|
||||
(neighbors x y (count (first board)) (count board)
|
||||
#(not (get-in board [%2 %1 :opened]))))))
|
||||
board))
|
||||
|
||||
(defn open [board x y]
|
||||
(let [x (dec x), y (dec y)]
|
||||
(condp (get-in board [y x]) nil
|
||||
:mine {:boom true :board board}
|
||||
:opened board
|
||||
(open* board [[x y]]))))
|
||||
|
||||
(defn mark [board x y]
|
||||
(let [x (dec x), y (dec y)]
|
||||
(assoc-in board [y x :marked] (not (get-in board [y x :marked])))))
|
||||
|
||||
(defn done? [board]
|
||||
(if (:boom board)
|
||||
(boom board)
|
||||
(do (display board)
|
||||
(->> (flatten board)
|
||||
(remove :mine ,)
|
||||
(every? :opened ,)))))
|
||||
|
||||
(defn play [n m density]
|
||||
(let [board (new-game n m density)]
|
||||
(println [:mines (count (filter :mine (flatten board)))])
|
||||
(loop [board board]
|
||||
(when-not (done? board)
|
||||
(print ">")
|
||||
(let [[cmd & xy] (.split #" " (read-line))
|
||||
[x y] (map #(Integer. %) xy)]
|
||||
(recur ((if (= cmd "mark") mark open) board x y)))))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue