2012-10-29 75 views
5

學習Clojure我正在研究一個小井字遊戲。在完成遊戲的第一部分後,我相當容易地嘗試構建智能電腦播放器。Clojure:遍歷矢量矢量以找到滿足特定條件的第一個矢量

對於測試我寫,以幫助指導這個,我要檢查電腦採點9,如果它是計算機的轉彎,這是董事會:

X | O | 3
4 | X | O
7 | 8 | 9

開始遊戲,董事會的定義如下,與代表在董事會的位置鍵值對一個地圖空間的內容:

(def board {1 "1" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9"}) 

我有幾個想法關於如何解決這個問題。一個是確定中獎套這樣的:

(def winning-sets 
    [[(board 1) (board 2) (board 3)], 
    [(board 4) (board 5) (board 6)], 
    [(board 7) (board 8) (board 9)], 
    [(board 1) (board 4) (board 7)], 
    [(board 2) (board 5) (board 8)], 
    [(board 3) (board 6) (board 9)], 
    [(board 1) (board 5) (board 9)], 
    [(board 3) (board 5) (board 7)]]) 

遍歷每個組:

(for [set winning-sets] 
    (filter #(= symbol %) set)) 

但是,這看起來不正確...我不知道我會從那裏。我試圖解決這個問題可以這樣描述:

告訴計算機過目8個獲勝集,並找出與您的符號一個空位的兩個一組。

我對Clojure相當陌生,所以我不確定我是否理解解決此問題的最佳方法。我一直在尋找ClojureDocs(檢查迭代功能,如forloopcase),但一直無法做到這一點。

什麼是最好的方式來遍歷這些勝利集,目前在矢量形式,並找到具有兩個特定的符號和一個開放的集?或者最好是將勝利組存儲在不同的數據結構中?

注意:我已閱讀this question的回覆,但尚未將它們應用於我的。

+0

我想你想要一些功能。 – Kevin

回答

4

首先,我建議你用這個結構板位置:

(def board [[1 1 0] 
      [0 0 0] 
      [1 0 1]]) 

其中X爲1,O是-1和空單元格是0。在我的例子中,電路板只有X個符號(爲了簡化)。接下來,

(def winning-sets 
    '([[0 0] [0 1] [0 2]] 
    [[1 0] [1 1] [1 2]] 
    [[2 0] [2 1] [2 2]] 
    [[0 0] [1 0] [2 0]] 
    [[0 1] [1 1] [2 1]] 
    [[0 2] [1 2] [2 2]] 
    [[0 0] [1 1] [2 2]] 
    [[0 2] [1 1] [2 0]])) 

這是「獲獎」座標組。如有必要,你可以計算這個值,但對於3x3這個列表實際上並不那麼大。在這方面,對你問題的答案是

(defn check 
    [target combo] 
    (= (map #(count (filter (partial = %) combo)) [target 0]) '(2 1))) 

(defn extract 
    [coords] 
    (apply vector (map (fn [[f s]] ((board f) s)) coords))) 

(filter #(check 1 (extract %)) winning-sets) 

如果您執行在REPL這段代碼,你會看到

user=> (filter #(check 1 (extract %)) winning-sets) 
([[0 0] [0 1] [0 2]] 
[[2 0] [2 1] [2 2]] 
[[0 0] [1 0] [2 0]] 
[[0 0] [1 1] [2 2]]) 

它看起來像正確答案(2條水平線,1縱1角)。代碼很粗糙,並且有幾種方法可以使它更美觀和可重用。我應該解釋一下發生了什麼或代碼是否足夠清楚?