(ns rosettacode.24game)

(def ^:dynamic *luser*
"You guessed wrong, or your input was not in prefix notation.")

(def ^:private start #(println 
"Your numbers are: " %1 ". Your goal is " %2 ".\n"
"Use the ops [+ - * /] in prefix notation to reach" %2 ".\n"
"q[enter] to quit."))

(defn play
  ([] (play 24))
  ([goal] (play goal (repeatedly 4 #(inc (rand-int 9)))))
  ([goal gns]
     (start gns goal)
     (let [input (read-string (read-line))
           flat  (flatten input)]
      (println
        (if (and (re-find #"^\([\d\s+*/-]+\d?\)$" (pr-str flat))
                 (= (set gns) (set (filter integer? flat)))
                 (= goal (eval input)))
         "You won the game!"
         *luser*))
      (when (not= input 'q) (recur goal gns)))))