2014-10-16 67 views
2

我想跳出下面的循環,並在第10行計算結果爲真時返回最小移動。我使用print語句查看了輸出,並且當第10行的值爲true時,它會查找我正在查找的數據,但會繼續發生。在Clojure中,有一種方法可以在語句評估爲真時停止循環?或者我應該使用循環以外的其他東西嗎?在Clojure退出循環迴路

(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))))))) 
+0

只有當第二個if爲false時,您的代碼纔會重複出現。 – 2014-10-16 19:12:46

+0

你能詳細點嗎?當第二個if爲true時,它不返回值(最小移動板最小標記最大標記深度)。它繼續進行得分動作,這讓我相信它是反覆出現的。 – user3245240 2014-10-16 19:16:44

+1

你怎麼知道它是反覆出現的?你是否聲稱'如果'不能像它應該那樣工作?如果你的條件是真的,你的'if'將評估這兩個的第一個s表達式。如果這是你正在執行的代碼,除非條件爲假,否則它不能重複。 – 2014-10-16 22:55:37

回答

6

關於loop

  • 這不是loop是循環:這是recur
  • loop是一個let,形成一個recur點。
  • 你不會也不會突圍一個圈recur把你打成一片。

loop相當於設置和調用一個匿名函數。例如

(loop [n 5, s "Hello, world!"] 
    (if (zero? n) 
    (first s) 
    (recur (dec n) (rest s)))) 

...相當於

((fn [n s] 
    (if (zero? n) 
    (first s) 
    (recur (dec n) (rest s)))) 
5 "Hello, world!") 

隨着性能的一些損失,loop可能已被編寫爲執行上述轉換的宏。


至於你的代碼:

這裏有6種未定義功能。要清除彙編,我們

(declare best-min-score 
     best-max-move 
     best-min-move 
     best-max-move 
     make-move-on 
     remaining-scores) 

還有兩種多餘的形式。這些不會造成主動傷害,但會掩蓋代碼。

  • loop無需:函數本身是recur合適 目標。
  • do什麼也不做:它包含一個單一的表單。

你的函數簡化爲

(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))))) 

而任何的未定義功能可能會反覆出現,最好的辦法是best-min-move

+0

謝謝!我用你的建議,並刪除循環。我也將第一個if語句抽象爲它自己的函數。 – user3245240 2014-10-17 17:21:52

+0

@ user3245240如果您的子功能僅在本地使用,您可以使用'let'或 - 如果它們是相互遞歸的 - 'letfn'來定義它們。有時你可以從上下文中提取一些參數。 – Thumbnail 2014-10-18 10:02:37