Skip to content

Commit

Permalink
Add logic for first three AI strengths.
Browse files Browse the repository at this point in the history
  • Loading branch information
JanEricNitschke committed Jun 7, 2024
1 parent 1ef5613 commit d1638ac
Showing 1 changed file with 49 additions and 20 deletions.
69 changes: 49 additions & 20 deletions tictactoe_clojure/tictactoe.clj
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
(def win-conditions [[0 1 2] [3 4 5] [6 7 8] [0 3 6] [1 4 7] [2 5 8] [0 4 8] [2 4 6]])


(defn ask []
(println "Please answer \"y\"[yes] or \"n\"[no]:")
(.trim (read-line)))

(defn get-valid-answer [question]
(println question)
(let [answer (->> (repeatedly ask)
(filter #{"y" "n"})
(first))]
(= answer "y")))

(defn swap-player [player]
(if (= player "X")
"O"
"X"))

(defn get-player-input [])

(defn show-board [board]
(println (str (nth board 0) " | " (nth board 1) " | " (nth board 2)))
Expand All @@ -32,7 +20,6 @@
(println (str "Player " player " turn"))
(show-board board)
(let [player-input (read-string (read-line))]
(println player-input)
(if (and (number? player-input) (<= 0 player-input 8))
(assoc board player-input player)
(do
Expand All @@ -44,17 +31,59 @@
(do (println "Game drawn!") true)
false))

(defn won-win-condition [board player win-condition]
(defn won-win-condition [player board win-condition]
(every? #(= player (nth board %)) win-condition))

(defn game-won [board player]
(if (some (partial won-win-condition board player) win-conditions)
(defn is-win [player board]
(some (partial won-win-condition player board) win-conditions))

(defn game-won [player board]
(if (is-win player board)
(do (println (str "Player " player " wins!")) true)
false))

(defn ai-turn-easy [player board]
(let [empty-spaces (filter #(not (or (= % "X") (= % "O"))) board)
random-space (nth empty-spaces (rand-int (count empty-spaces)))]
(assoc board (Integer. random-space) player)))

(defn try-win-move [player board]
(let [empty-spaces (filter #(not (or (= % "X") (= % "O"))) board)]
(some (fn [space]
(let [new-board (assoc board (Integer. space) player)]
(if (is-win player new-board)
(Integer. space)
false)))
empty-spaces)))

(defn ai-turn-medium [player board]
(let [ win-move-spot (try-win-move player board)]
(if (nil? win-move-spot)
(ai-turn-easy player board)
(assoc board win-move-spot player))))

(defn ai-turn-hard [player board]
(let [win-move-spot (try-win-move player board)]
(if (nil? win-move-spot)
(let [block-move-spot (try-win-move (swap-player player) board)]
(if (nil? block-move-spot)
(ai-turn-easy player board)
(assoc board block-move-spot player)))
(assoc board win-move-spot player))))

(defn ai-turn-best [player board]
board)

(defn ai-turn [player board strength]
(println (str "AI turn as player " player " with strength " strength))
board)
(show-board board)
(let [board-after-ai-move (case strength
1 (ai-turn-easy player board)
2 (ai-turn-medium player board)
3 (ai-turn-hard player board)
(ai-turn-best player board))]
(Thread/sleep 1000)
board-after-ai-move))

(defn ai-turn? [player X-strength O-strength]
(if (= player "X")
Expand All @@ -67,14 +96,14 @@
O-strength))

(defn play [board X-strength O-strength]
(loop [game-board board player "X"]
(if (or (game-won game-board (swap-player player)) (board-full game-board))
(loop [player "X" game-board board]
(if (or (game-won (swap-player player) game-board) (board-full game-board))
(show-board game-board)
(let
[new-board (if (ai-turn? player X-strength O-strength)
(ai-turn player game-board (strength-for-player player X-strength O-strength))
(player-turn player game-board))]
(recur new-board (swap-player player))))))
(recur (swap-player player) new-board)))))

(defn parse-args
"Parses command line arguments and returns a map with X-strength and O-strength."
Expand Down

0 comments on commit d1638ac

Please sign in to comment.