gpt4 book ai didi

algorithm - 在 Clojure 中实现 Minimax 算法 - 具有多个递归调用的条件函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:31 25 4
gpt4 key购买 nike

在我想通了一些事情之后,这个问题和我的另一个问题有点合并为一个问题,所以我修改了这个问题。

下面概述了我试图通过我的功能完成的任务。

  1. 遍历所有点。如果它是开放的,请选择带有当前玩家符号的位置。
  2. 如果这一步导致游戏获胜并且轮到计算机玩家了,则将点的键值对(一个整数)和点的分数(一个整数,在本例中为 1)添加到 scored-spots HashMap 。
  3. 递归并调用相同的函数,将 scored-spots 散列映射传递给它,刚刚移动的棋盘被移除,相同 玩家,以及相同符号。
  4. 但是,如果游戏尚未获胜,则继续下一个条件语句并进行检查。
  5. 以相同的方式继续下一个条件语句,只是分数不同(轮到计算机获胜为 1,轮到人类获胜为 -1,平局为 0)。
  6. 如果所有条件语句的计算结果都不为真,则无论如何递归(scored-spots HashMap 在这种情况下不会有任何不同)。

这是我试过的代码,但这并没有返回我期望的值。

注意:
board 是一个像这样的 HashMap :{0 "0", 1 "1", 2 "2"} (spot location - spot value)
sym 是一个符号,如“X”或“O”
current-player 是关键字,如 :computer:human
scored-spots 是一个 HashMap ,如下所示:{}

(defn score-spots [board sym current-player scored-spots]
(for [spot (keys board)]
(if (some #(= % (.toString spot)) (filter #(not= "O" %) (filter #(not= "X" %) (vals board))))
(let [board (assoc board spot sym)]
(cond
(and (game-won board) (= current-player :computer))
(score-spots board sym current-player (assoc scored-spots spot 1))
(and (game-won board) (= current-player :human))
(score-spots board sym current-player (assoc scored-spots spot -1))
(game-tied board)
(score-spots board (switch-symbol sym) (switch-player current-player) (assoc scored-spots spot 0))
:else
(score-spots board (switch-symbol sym) (switch-player current-player) scored-spots)))
scored-spots))))

我期望的返回值是一个散列图,每个空位都已得分。例如,{1 0, 4 1, 5 -1, 6 -1, 8 0}

相反,如果我通过这个板:
{1 "X"2 "X"3 "O"4 "4"5 "5"6 "6"7 "7"8 "X"9 "O"},
我得到一个返回值,其中包含大量散列映射的列表

最佳答案

总的来说,我对 Clojure 和 FP 比较陌生。每当我想到递归时,我总是首先尝试考虑它是否是 map 和/或 reduce 的机会。

在这种情况下,您正在尝试对每个 点进行评分。 收集的每个点都是一 block 板。因此,如果我能对每个点进行评分,然后将它们收集在一起,我就可以完成手头的任务。在 reduce 术语中,我可以对集合中的一个项目(点)做一些事情,然后将该值合并为一个值(板 - 技术上只有没有“X”或“O”的点"用于下面的代码)。

这是我的重写:

(defn score-spot [scored-spot current-player board]
(let [[spot score] scored-spot]
(cond
(and (game-won board) (= current-player :computer)) {spot 1}
(and (game-won board) (= current-player :human)) {spot -1}
(game-tied board) {spot 0}
:else {spot score})))

(defn score-board [board current-player]
(let [spots-to-score (filter #(and (not= "X" (second %))
(not= "O" (second %))) board)]
(reduce #(into %1 (score-spot %2 current-player board)) {} spots-to-score)))

这会给你的结果例如{1 0, 4 1, 5 -1, 6 -1, 8 0}


编辑:

关于递归的需要,你基本上是想使用相互递归。为此,您可以使用 declare转发声明函数,然后使用 trampoline ( here's a quick tutorial ) 用于实际递归。

关于algorithm - 在 Clojure 中实现 Minimax 算法 - 具有多个递归调用的条件函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13278646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com