Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure:行检查器中的相同向量值_Clojure - Fatal编程技术网

Clojure:行检查器中的相同向量值

Clojure:行检查器中的相同向量值,clojure,Clojure,我正在创建一个Clojure Tic-Tac-Toe游戏,其中我有一个带有9个数字的板变量(def移动[0 0 0 0 0 0 0])。这个变量被1的en 2填充(还没有“x”或“o”)。在游戏结束时,变量可能看起来像[2 1 2 1 2],其中1拥有第二行。现在我需要一个函数来检查一行中是否有三个。我想从水平方向开始。这意味着我需要一个函数来检查同一行中的每3个数字3后面是否有。有没有办法创建这样的函数? 这就是目前为止的功能: (def moves [0 0 0 0 0 0 0 0 0])

我正在创建一个Clojure Tic-Tac-Toe游戏,其中我有一个带有9个数字的板变量
(def移动[0 0 0 0 0 0 0])
。这个变量被1的en 2填充(还没有“x”或“o”)。在游戏结束时,变量可能看起来像
[2 1 2 1 2]
,其中1拥有第二行。现在我需要一个函数来检查一行中是否有三个。我想从水平方向开始。这意味着我需要一个函数来检查同一行中的每3个数字3后面是否有。有没有办法创建这样的函数? 这就是目前为止的功能:

(def moves [0 0 0 0 0 0 0 0 0])
(defn wongame? [playedmoved]
  (
    (def counter 0)
    ;action here....  
    )
 )
(won moves) ;gives true/false

像这样的方法应该会奏效:

(defn end-of-game? [moves]
  (->> moves
       (partition 3)
       (remove #(= [0 0 0] %))
       (map (partial apply =))
       (some identity)))
使用[2 1 2 1 1 2]
(分区3)
的示例输入给出:

((2 1 2) (1 1 1) (2 1 2))
我们需要对每个列表使用
=
<代码>应用是必需的,因为
=
使用单个参数而不是列表<代码>部分是必需的,因为
apply=
的参数处于挂起状态
#(apply=%)
可以等效使用

(false true false)
some
是关于“(至少)一个或一个”。在这里,如果传递的列表中有一个是真实的,那么将返回该列表

如果确实需要返回true/false的答案,则调用
boolean
作为线程last宏的最后一个函数(
->
)。我忽略了这一点,因为在Clojure中您很少需要实际返回true或false,您可以依赖于零双关语

同样的功能也适用于垂直方向。从一个通用的
转置
函数开始,该函数适用于矩阵(例如
[[0 0 0][0 0 0][0 0 0]]
):

然后在输入之前调整输入,在输出之后调整输出:

(defn transpose-flat [xs]
  (->> xs
       (partition 3)
       transpose
       (mapcat identity)))
首先,如果我们遇到这样的模式,我们需要停止游戏, 否则我们可能会误判这场比赛的获胜者 如果移动达到类似[2 2 1 2 2]的状态。谁是赢家?我们需要在游戏的每个回合调用这个函数

其次,“赢了”这个名字不合适,因为这个函数不告诉赢家,而是告诉游戏结束。“赢?”函数应重命名为[“游戏结束?”“游戏结束?”“结束?”]

第三,我尝试实现“winner”,返回游戏的赢家,如下所示:

(defn winner [moves]
  (let [pattern-of-end {[1 1 1]:1 [2 2 2]:2}]
    (->> moves          #_"I use threading macro to explain"
         (partition 3)  #_"group by each three symbols. 
                           1 line of 9 elements -> 3 lines of 3 elements"
         (keep pattern-of-end) #_"If there is some lines that matches 
                                  the pattern-of-end ,that will return [1] or [2]"
         first          #_"Because the previous expression returns lazy-seq 
                        we can get the scalar by calling first"
)))

这告诉我们游戏的赢家。

如果你有正确的x和o的数字,这会更容易:

(defn the-winner-is [moves]
    (let [x 5
          o 7]
        (->> moves
             (partition 3)
             (map (partial apply +))
             (some #{15 21}))))
这样,它甚至可以说谁是赢家(15或21)


是的,这有点像,但是我的移动从9个零开始,这意味着该方法在开始时返回true。所以它是连续三个,但它们不能是零?是的,将1视为“x”,将2视为“o”,将0视为未填充的空格谢谢帮助!我花了一些时间让转置工作,因为它需要一个分区向量。所以当我划分移动时,比转置和比检查是否结束游戏?没有分区部分,它也可以垂直工作。对不起,我的不好<代码>转置
假设一个矩阵,因此
[[0 0 0][0 0 0][0 0 0 0]]
。要保留数据结构,您必须在调用之前对所有数据进行
分区
,并在调用之后执行类似于
mapcat identity
的操作。
winner
可能也是一个好名字。我不会使用问号,即
winner?
,除非我预期该函数几乎总是用作谓词。
(defn winner [moves]
  (let [pattern-of-end {[1 1 1]:1 [2 2 2]:2}]
    (->> moves          #_"I use threading macro to explain"
         (partition 3)  #_"group by each three symbols. 
                           1 line of 9 elements -> 3 lines of 3 elements"
         (keep pattern-of-end) #_"If there is some lines that matches 
                                  the pattern-of-end ,that will return [1] or [2]"
         first          #_"Because the previous expression returns lazy-seq 
                        we can get the scalar by calling first"
)))
(defn the-winner-is [moves]
    (let [x 5
          o 7]
        (->> moves
             (partition 3)
             (map (partial apply +))
             (some #{15 21}))))
(the-winner-is [5 5 7 7 7 0 7 7 7]) ; 21
(the-winner-is [5 5 5 7 7 5 5 7 7]) ; 15
(the-winner-is [5 7 5 7 7 5 5 7 5]) ; nil