我正在尝试编写一个 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/