zca*_*ate 3 clojure clojurescript
我在这里玩一个狡猾的教程:
http://buildnewgames.com/introduction-to-crafty/
我想知道如何在clojurescript/clojure中实现这个特定的功能
 var max_villages = 5;
 for (var x = 0; x < Game.map_grid.width; x++) {
   for (var y = 0; y < Game.map_grid.height; y++) {
     if (Math.random() < 0.02) {
       Crafty.e('Village').at(x, y);
       if (Crafty('Village').length >= max_villages) {
        return;
       }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
我知道我们可以拥有(for [])构造但是当max_villages达到5时你会如何让它停下来?
这是一种方法:
(def max-villages 5)
(->> (for [x (range map-width)
           y (range map-height)]
       [x y])
     (filter (fn [_] (< (rand) 0.02)))
     (take max-villages))
Run Code Online (Sandbox Code Playgroud)
然后可能添加(map make-village-at)或类似管道的下一个阶段; 如果它意味着执行副作用,添加一个dorun或doall作为最后阶段强制它们立即发生(根据返回值是否有趣选择一个或另一个).
NB.由于seq分块,可能会生成一些额外的向量和随机数,但它会小于32.
使用计数器进行比较的更为迫切的方法:
(let [counter (atom 0)]
  (doseq [x (range map-width)
          :while (< @counter max-villages)
          y (range map-height)
          :while (< @counter max-villages)
          :when (< (rand) 0.02)]
    (swap! counter inc)
    (prn [x y]))) ; call make-village-at here
Run Code Online (Sandbox Code Playgroud)
:while当测试表达式失败时,在当前嵌套级别终止循环; :when立即进入下一次迭代.doseq也支持分块,但:while会阻止它执行不必要的工作.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           397 次  |  
        
|   最近记录:  |