2012-10-29 53 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角)。代码很粗糙,并且有几种方法可以使它更美观和可重用。我应该解释一下发生了什么或代码是否足够清楚?