公共Lisp中的非法函数调用
我正在制作一个两人的tic-tac-toe游戏,我正处于解决代码中所有错误的阶段。我遇到的当前错误是以下代码中的公共Lisp中的非法函数调用,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,我正在制作一个两人的tic-tac-toe游戏,我正处于解决代码中所有错误的阶段。我遇到的当前错误是以下代码中的非法函数调用错误: (cond [...snip...] ((= CHOICE 3) (IF (NUMBERP (AREF *BOARD* 0 2)) (SETF (AREF *BOARD* 0 2) *MARKER*) (INVALID-SELECTION))) 我做错了什么 编辑整个函数如下所示: (defun select (choice) (
非法函数调用
错误:
(cond
[...snip...]
((= CHOICE 3)
(IF (NUMBERP (AREF *BOARD* 0 2))
(SETF (AREF *BOARD* 0 2) *MARKER*)
(INVALID-SELECTION)))
我做错了什么
编辑整个函数如下所示:
(defun select (choice)
(cond ((= choice 1)
(if (numberp (aref *board* 0 0)) (setf (aref *board* 0 0) *marker*)
(invalid-selection))))
((= choice 2)
(if (numberp (aref *board* 0 1)) (setf (aref *board* 0 1) *marker*)
(invalid-selection))))
((= choice 3)
(if (numberp (aref *board* 0 2)) (setf (aref *board* 0 2) *marker*)
(invalid-selection))))
((= choice 4)
(if (numberp (aref *board* 1 0)) (setf (aref *board* 1 0) *marker*)
(invalid-selection))))
((= choice 5)
(if (numberp (aref *board* 1 1)) (setf (aref *board* 1 1) *marker*)
(invalid-selection))))
((= choice 6)
(if (numberp (aref *board* 1 2)) (setf (aref *board* 1 2) *marker*)
(invalid-selection))))
((= choice 7)
(if (numberp (aref *board* 2 0)) (setf (aref *board* 2 0) *marker*)
(invalid-selection))))
((= choice 8)
(if (numberp (aref *board* 2 1)) (setf (aref *board* 2 1) *marker*)
(invalid-selection))))
((= choice 9)
(if (numberp (aref *board* 2 2)) (setf (aref *board* 2 2) *marker*)
(invalid-selection))))
通常计算形式中的第一件事几乎总是一个命名函数、宏或特殊运算符的符号。表单中的第一件事是列表
(=选项3)
。更多的背景会有所帮助;正如西诺所说,这看起来像是一个无实体的条件条款
edit我将您的代码放在一个函数中,并添加了足够多的括号和变量定义来计算它,它的计算结果很好。还需要更多的上下文。我想出来了!由于复制和粘贴技能差,函数中的括号太多。您的函数看起来就是这样,只是因为它没有正确缩进 选择代码并缩进区域-任何理解一点Lisp的编辑器都应该为您这样做。在LispWorks中,这是通过扩展编辑器命令“缩进区域”完成的 您还可以使用更简单的情况替换COND:
(case choice
(1 ...)
(2 ...))
使用案例和局部函数可以使整个函数更小:
(defun select (choice)
(flet ((do-something (x y)
(if (numberp (aref *board* x y))
(setf (aref *board* x y) *marker*)
(invalid-selection))))
(case choice
(1 (do-something 0 0))
(2 (do-something 0 1))
(3 (do-something 0 2))
(4 (do-something 1 0))
(5 (do-something 1 1))
(6 (do-something 1 2))
(7 (do-something 2 0))
(8 (do-something 2 1))
(9 (do-something 2 2)))))
这应该会教你。切勿使用复制/粘贴。在这种情况下,您可以
(let((x(楼层选择3))(y(rem选择3))(if(numberp(aref*board*xy))(setf(aref*board*xy)*marker*)(无效选择))
,而不是长条件。在其他情况下,将重复代码分解成函数或宏。如果您知道多个值是什么,也可以直接使用floor
函数的两个返回值:(多值绑定(xy)(floor choice 3)(If…)
。我的函数缩进方式与显示的不同,当我把它粘贴到页面上时,它就是这样出现的:/