Exit the looping loop in Clojure
I would like to exit the loop below and return best-min-move when line 10 evaluates to true. I scanned the output using print statements, and when line 10 does evaluate to true, it finds the data I'm looking for, but keeps repeating. In Clojure, is there a way to stop the loop when the statement evaluates to true? Or should I be using something other than looping over?
(defn minimax [board max-mark min-mark depth best-score]
(loop [board board
max-mark max-mark
min-mark min-mark
depth depth
best-score best-score]
(if (= best-score (best-min-score board max-mark min-mark depth))
(best-max-move board max-mark min-mark depth)
(do
(if (= best-score (best-min-score board min-mark max-mark depth))
(best-min-move board min-mark max-mark depth)
(recur
(b/make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)
min-mark
max-mark
(inc depth)
(dec best-score)))))))
source to share
ABOUT loop
- It's not
loop
that loops: itrecur
. -
loop
is thatlet
which forms the pointrecur
. - You cannot and cannot break out of the loop: it
recur
breaks you into one.
loop
is equivalent to setting up and calling an anonymous function. for example
(loop [n 5, s "Hello, world!"]
(if (zero? n)
(first s)
(recur (dec n) (rest s))))
... is equivalent
((fn [n s]
(if (zero? n)
(first s)
(recur (dec n) (rest s))))
5 "Hello, world!")
With some loss of performance, it loop
could have been written as a macro that performs the above conversion.
As for your code:
There are six undefined functions here. To clean up compilation, we
(declare best-min-score
best-max-move
best-min-move
best-max-move
make-move-on
remaining-scores)
There are also two redundant forms. They do no active harm, but hide the code.
-
loop
not required: the function itself is a suitable target forrecur
. -
do
does nothing: it includes one form.
Your function boils down to
(defn minimax [board max-mark min-mark depth best-score]
(if (= best-score (best-min-score board max-mark min-mark depth))
(best-max-move board max-mark min-mark depth)
(if (= best-score (best-min-score board min-mark max-mark depth))
(best-min-move board min-mark max-mark depth)
(recur
(make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)
min-mark
max-mark
(inc depth)
(dec best-score)))))
While any of the undefined functions can be repeated, the best option is best-min-move
.
source to share