Clojure:行检查器中的相同向量值
我正在创建一个Clojure Tic-Tac-Toe游戏,其中我有一个带有9个数字的板变量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])
(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