Loops 宏扩展期间出错(循环用于…)
我正在尝试编写一个Lisp程序,它实现了一个非常类似于点和框的棋盘游戏,这意味着我有两个玩家可以互相竞争,但可以连续移动。我正在尝试实现最简单的minimax算法来实现这一点,不需要进行alpha-beta修剪,并且假设移动是交替的。由于我是Common Lisp新手,我希望您能给我任何反馈,特别是为什么在我尝试编译文件时出现以下错误:Loops 宏扩展期间出错(循环用于…),loops,macros,lisp,common-lisp,Loops,Macros,Lisp,Common Lisp,我正在尝试编写一个Lisp程序,它实现了一个非常类似于点和框的棋盘游戏,这意味着我有两个玩家可以互相竞争,但可以连续移动。我正在尝试实现最简单的minimax算法来实现这一点,不需要进行alpha-beta修剪,并且假设移动是交替的。由于我是Common Lisp新手,我希望您能给我任何反馈,特别是为什么在我尝试编译文件时出现以下错误: caught ERROR: ; during macroexpansion of (LOOP FOR A ...). ; Use *BREAK-ON-S
caught ERROR:
; during macroexpansion of (LOOP FOR A ...).
; Use *BREAK-ON-SIGNALS* to intercept.
这是我到目前为止的代码。问题是游戏。初始状态是不言自明的。terminal-test-p
接收当前游戏状态并指示这是否为终端状态。player
功能接收当前游戏状态并指示轮到哪个玩家玩。actions
函数接收当前游戏状态,并返回该状态下所有可用操作的列表。result
函数接收当前游戏状态和一个动作,并返回将该动作应用于该状态所产生的游戏状态。最后,实用程序函数
接收当前游戏状态和玩家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)))
函数最大值
:
(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))
(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))
函数MIN-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))
(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))
您的
循环中缺少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)))
...)
真不敢相信这么简单。。。非常感谢。您是否复制并粘贴了整个错误消息@LarsBrinkhoff的回答回答了这个问题,但我注意到在SBCL的输出中,“在宏扩展期间捕获错误…”之后的行(在一个简化的示例中)“在(SETQ…)
中找到循环
关键字expected\current循环
上下文:用于in…(SETQ…
”这似乎准确地指出了错误所在…