宏观扩展期间的错误(LOOP FOR A ...)

时间:2013-11-23 14:17:57

标签: loops macros lisp common-lisp

我正在尝试编写一个Lisp程序,它实现了一个非常类似于点和盒子的棋盘游戏,这意味着我有两个相互竞争但可以连续移动的玩家。我试图实现最简单的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函数接收当前游戏状态并返回该状态下所有可用操作的列表。 result函数接收当前游戏状态和动作,并返回将该动作应用于该状态的结果的游戏状态。最后,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))

1 个答案:

答案 0 :(得分:3)

DO中遗漏了LOOP。它应该是这样的:

(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)))
      ...)