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
Recursion clojure循环/递归_Recursion_Clojure - Fatal编程技术网

Recursion clojure循环/递归

Recursion clojure循环/递归,recursion,clojure,Recursion,Clojure,我想学一些Clojure。我制作了一个非常基本的儿童游戏“滑梯和梯子”模型。当一名玩家得分大于或等于100分时,游戏结束。 现在这只适用于唯一的玩家 以“(play player1)”开始游戏 我一直在思考如何让它成为多人游戏,必须使用Recursion,而不是“foreach”语句。 如何将其修改为多人游戏 (defn roll [] (+ 1 (rand-int 6))) (def chutes { 10 5, 12 3, 55 38, 77 69}) (def ladders { 12

我想学一些Clojure。我制作了一个非常基本的儿童游戏“滑梯和梯子”模型。当一名玩家得分大于或等于100分时,游戏结束。 现在这只适用于唯一的玩家

以“(play player1)”开始游戏

我一直在思考如何让它成为多人游戏,必须使用Recursion,而不是“foreach”语句。
如何将其修改为多人游戏

(defn roll []
 (+ 1 (rand-int 6)))

(def chutes { 10 5, 12 3, 55 38, 77 69})
(def ladders { 12 16, 10 25, 20 55, 77 91})

(defn apply_chutes [player]
 (if (contains? chutes @player)
  (do (reset! player (chutes @player))
      (println "down chute! " @player))))

(defn apply_ladders [player]
 (if (contains? ladders @player)
  (do (reset! player (ladders @player))
  (println "up ladder! " @player))))

(defn move [player]
 (do(swap! player + (roll))
  (println "p: " @player)
  (apply_chutes player)
  (apply_ladders player)
    player))
  (if 
("done")))

(defn play [player]
 (move player)
 (if (>= @player 100)
  (println "done")
  (play player)))

(def player1 (atom 0))

好的,我不会向您提供完整的代码,但更好的是关于函数编程的高级设计,特别是Clojure中的循环/递归

让我们从函数式编程中一个非常重要的概念开始-不变性。功能程序试图避免系统状态的任何变化。程序不是改变状态,而是产生新的状态。例如,如果您有vector
v1=[1,2,3,4]
并希望在其末尾插入5,则不会销毁
v1
,而是生成
v2=[1,2,3,4,5]
v1
保持在内存中不变)。有关函数式编程中不变性的更多详细信息,请参见问题

有了这个,最好的方法就是创建一个特殊的变量
state
,它将保存游戏的整体状态

接下来要考虑的是<强>循环< /强>。同样,函数式编程中的循环概念几乎被递归所取代。循环和递归通常是相似的——它们都允许您在某些代码终止之前重复多次。在大多数命令式编程语言(例如Python、Java)中,递归会导致堆栈增长,但在函数式语言中,尾部递归的概念非常流行。如果你不熟悉这个概念,我强烈建议你学习它。现在我只说,尾部递归只能发生在尾部位置(控制流中的最后一条语句),它不会导致堆栈增长,因此可以用作循环构造

在Clojure中,尾部递归使用
recur
关键字组织:

(defn play [state ...]
   ...
   (recur new-state ...))
在这里,我们使用参数
state
定义
play
函数,并在最后一行使用关键字
recur
递归调用它(我们也可以将其称为
(play new state…
,但在这种情况下,JVM不会优化代码以使其成为尾部递归)<代码>新状态在函数体中的某个位置定义,并完全代表它的含义-游戏的新状态

最后,您希望使您的游戏成为多人游戏,也就是说,在每次迭代后更改当前玩家。通过循环/递归,只需交换玩家即可轻松实现:

(defn play [state current-player next-player]
   ;; do play with current-player and compute new-state
   (recur new-state next-player current-player))
请注意,在重复调用中,玩家交换了他们的位置,因此下一个玩家成为当前玩家,反之亦然,在新调用的
play


有了这些,您应该能够将代码翻译成新版本

你是在问Clojure、递归还是游戏设计?请提出精确的问题,描述精确的问题。不是真正的游戏设计,尽管我很感激任何函数式编程技巧-我想知道如何让多个玩家都能玩,但当第一个玩家突破100时就停止。特别是“播放”功能-将其修改为适用于多个播放器。我想我应该使用doseq或更高阶的函数映射,但是当游戏结束时,我如何停止遍历玩家序列呢?我应该使用递归并每次为不同的玩家调用“play”函数吗?这有帮助吗?我知道这不是真正的具体问题。谢谢你的回答-这很有意义,我会尝试一下。从递归的角度考虑如何在clojure中管理状态对我来说还不太自然。@Taylor:现在你在全局变量
滑槽
阶梯
中有了状态。您应该做的是将它们放入map
{:ladders-graddes,:chutes-chutes}
中,并将此映射传递给需要访问该状态的所有函数。要创建新状态,请执行类似于
(让[新状态(关联旧状态:斜槽新斜槽:阶梯新阶梯)]…)
。另外,生成函数,更改其中一个变量,只返回此变量,例如,生成
应用梯形图
获取状态和旧玩家,只返回新玩家,而不修改状态或玩家中的任何内容。您应该没有任何
变量