我正在尝试编写一个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))
你缺少一个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)))
...)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句