loops - 在 (LOOP FOR A ...) 的宏扩展期间出错

标签 loops macros lisp common-lisp

我正在尝试编写一个 Lisp 程序来实现与点和方 block 非常相似的棋盘游戏,这意味着我有两个玩家相互竞争但可以连续移动。我正在尝试实现最简单的 minimax 算法来实现这一点,没有 alpha beta 修剪并假设移动是交替的。由于我是 Common Lisp 的新手,如果您能给我任何反馈,我将不胜感激,尤其是当我尝试编译我的文件时出现以下错误的原因:

caught ERROR:
;   during macroexpansion of (LOOP FOR A ...).
;   Use *BREAK-ON-SIGNALS* to intercept.

这是我目前的代码。一个问题就是一个游戏。 initial-state 我认为这是不言自明的。 terminal-test-p 接收当前游戏状态并指示这是否是终端游戏状态。 player 函数接收当前游戏状态并指示轮到哪个玩家玩。 actions 函数接收当前游戏状态并返回该状态下所有可用 Action 的列表。 result 函数接收当前游戏状态和一个 Action ,并返回将该 Action 应用到该状态后的游戏状态。最后,utility-function 接收当前游戏状态和玩家 ID,并返回该玩家的期望分数。

(defstruct problem
  initial-state
  player
  actions
  result
  terminal-test-p
  utility-function)

这是我到目前为止的极小极大。我知道它仍然很差,但我真的不能进步太多,因为我不太了解这种语言。

(defparameter *infinity* 999999999)

(defun minimax (prob int)
  (let ((action nil)
        (utility nil)
        (current-state (problem-initial-state prob)))
    (loop for a in (funcall (problem-actions prob) current-state)
          (setq next-prob (make-problem
                              :initial-state (funcall (problem-result prob)
                                                      current-state a)))
      (if (> (min-value next-prob int) utility)
          (progn  
            (setf action a)
            (setf utility (min-value next-prob int)))))
(values action utility)))

函数MAX-VALUE:

(defun max-value (prob int)
  (if (funcall (problem-terminal-test-p prob))
      (return-from max-value (funcall (problem-utility-function prob)
                                      (problem-initial-state prob))))
  (let ((utility (- *infinity*)))
    (loop for a in (funcall (problem-actions prob)
                            (problem-initial-state prob))
          (let ((next-prob (make-problem
                             :initial-state (funcall (problem-result prob)
                                                     (problem-initial-state prob)
                                                     a))))
            (setf utility (max utility (min-value next-prob int)))))
    utility))

函数 MIN-VALUE:

(defun min-value (prob int)
  (if (fun call (problem-terminal-test-p prob))
      (return-from min-value (funcall (problem-utility-function prob)
                                      (problem-initial-state prob))))
  (let ((utility *infinity*))
    (loop for a in (funcall (problem-actions prob) (problem-initial-state prob))
          (let ((next-prob (make-problema
                            :initial-state (fun call
                                                (problem-result prob)
                                                (problem-initial-state prob)
                                                a))))
            (setf utility (min utility (max-value next-prob int)))))
    utility))

最佳答案

您的LOOP 中缺少DO。它应该看起来像这样:

(loop for a in (funcall (problem-actions prob) current-state)
      DO (setq next-prob (make-problem :initial-state (funcall (problem-result prob) current-state a)))
      ...)

关于loops - 在 (LOOP FOR A ...) 的宏扩展期间出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20163420/

相关文章:

vba - Excel DDE RTD 自动刷新

clojure - 按契约(Contract)库为 Common Lisp 设计?

c - 为什么中断是停止程序而不是跳回?

ios - 如何在 SWIFT 的 Objective-C 中替换 #define 宏?

python - 循环时比较python中的列表

macros - undef 和 define <MACRO> 0 有什么区别?

clojure - 为什么不以 def 形式破坏?

clojure - 如何实现原始程序 "apply"

jquery - 删除值数组中不存在的选择选项

java - 如何从数组中打印出 int 值?