【问题标题】:Nested loop in common LISP普通 LISP 中的嵌套循环
【发布时间】:2016-11-30 02:59:25
【问题描述】:

我正在尝试创建一个可以在 LISP 中解决游戏 Mastermind 的玩家。我尝试在辅助函数中使用以下嵌套循环

(defparameter *counter* 0) 

;analyze the score to determine whether points need to be added to counter
(defun analyze (last-response)
  (if (> (first last-response) 0)
      (setf *counter* (+ (first last-response) *counter*))))

;helper function for finding correct color
(defun guessColor (length colors last-response)
    (loop while (< *counter* 4) do
       (loop for i from 1 to length
          collect (first colors)
          (setf colors (rest colors)))
    (analyze (last-reponse))))

;baseline Holyguacamole player will guess all colors before trying all combinations of correct color 
(defun HolyGuacamole (board colors SCSA last-response)
  (declare (ignore SCSA))
  ;(print last-response)
  (guessColor board colors last-response)
  (print *counter*)
    ;(sortColor)
)

while 循环应该在全局变量*counter* 小于 4 时运行。内部循环应该根据所需的钉子长度(可变长度)猜测颜色。我一直遇到编译错误

在 (LOOP WHILE (COUNTER 4) ...) 的宏展开期间。使用 ;
BREAK-ON-SIGNALS 拦截。

我不熟悉 LISP,所以我不确定该错误代码的含义以及如何修复它。我觉得我用正确的括号正确地嵌套了它,但我实际上不确定它有什么问题。

Link 到 Mastermind 环境。

【问题讨论】:

  • 整个程序有多大?您可以粘贴它还是将其缩减为一个独立的示例?我没有看到 scoreanalyze 的定义或 *counter* 的声明
  • @GregoryNisbet 游戏本身的代码非常大。我编辑了我的辅助函数以及 counter 的声明。 score 更改为 last-response
  • 我认为(analyze (last-reponse)))) 应该是(analyze last-reponse))) ...似乎还有其他一些错误...我无法使用clisp 或@ 重现那个确切的编译器错误987654330@.
  • 我认为即使括号正确,我最大的问题还是循环本身。
  • 错误可能是内层循环中的(SETF...)引起的。 COLLECT 子句中只允许使用一种形式。你可能应该把它放在DO-clause 中。或者您可以使用POP insted of FIRST 并删除SETF。我不确定您期望内部循环实现什么。它从COLORS 中收集第一个LENGTH 元素,但它的返回值只是被外循环丢弃。

标签: common-lisp


【解决方案1】:

原则上,将一个循环嵌套在另一个循环中是没有障碍的。但是,@jkiiski 指出,COLLECTCOLLECTING 子句只能采用单个表达式。

比如下面这个程序

(defun nested-loop ()
  (loop for i from 1 to 10 doing
        (loop for j from 1 to 10 collecting
              (print "some string")
              (print (list 'nested-loop i j)))))

(nested-loop)

在 CLISP 下产生语法错误。

*** - LOOP: illegal syntax near (PRINT (LIST 'NESTED-LOOP I J)) in
       (LOOP FOR J FROM 1 TO 10 COLLECTING (PRINT "some string")
        (PRINT (LIST 'NESTED-LOOP I J)))

使用dodoing 子句有效,将与collecting 子句关联的多个表达式与progn 分组也是如此。

(defun nested-loop ()
  (loop for i from 1 to 10 doing
        (loop for j from 1 to 10 collecting
              (progn
                (print "some string")
                (print (list 'nested-loop i j))))))

(nested-loop)

【讨论】:

  • 感谢您的回复。经过进一步思考,我认为使用嵌套循环不会像我想要的那样工作。我在下面重写了我的代码。它可以编译,但是在使用 print last-response 进行测试时,它会打印所有 NIL
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-11
  • 2010-12-12
  • 2012-04-27
  • 2016-08-12
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
相关资源
最近更新 更多