【问题标题】:Clojure: Iterating over a vector of vectors to find the first vector that meets a certain conditionClojure:遍历向量向量以找到满足特定条件的第一个向量
【发布时间】:2012-10-29 20:14:32
【问题描述】:

为了学习 Clojure,我正在开发一款 Tic Tac Toe 小游戏。在相对轻松地完成了游戏的第一部分之后,我一直在努力构建一个智能电脑玩家。

对于我正在编写以帮助指导这一点的测试,我想检查计算机是否选择了第 9 点,如果轮到计算机并且这是棋盘:

X | ○ | 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 的回复,但无法将其应用于我的。

【问题讨论】:

  • 我想你想要一些功能。

标签: vector clojure iteration tic-tac-toe


【解决方案1】:

首先,我建议你使用这种结构来担任董事会职位:

(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 条对角线)。代码很粗糙,没有什么方法可以使它更美观和可重用。我应该解释发生了什么还是代码足够清晰?

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    相关资源
    最近更新 更多