我正在尝试编写一个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))
答案 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)))
...)