Common Lisp中的非法函数调用

时间:2010-10-30 00:18:43

标签: lisp common-lisp sbcl

我正在努力制作一款双人游戏,我正处于解决代码中所有错误的阶段。我坚持的当前错误是以下代码中的illegal function call错误:

(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 个答案:

答案 0 :(得分:2)

您的功能只是看起来那样,只是因为它没有正确缩进。

选择代码并缩进区域 - 任何理解Lisp的编辑器都应该为您做到这一点。在LispWorks中,这是通过扩展编辑器命令“缩进区域”完成的。

您还可以使用更简单的CASE替换COND:

(case choice
  (1 ...)
  (2 ...))

使用CASE和本地函数可以缩小整个函数:

(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)))))

答案 1 :(得分:0)

通常评估形式中的第一件事应该几乎总是一个命名函数,宏或特殊运算符的符号。表单中的第一件事是列表(= CHOICE 3)。更多背景会有所帮助;正如Cirno所说,这看起来像一个无实体的COND条款。

编辑我把你的代码放在一个函数中,并添加了足够的括号和变量定义来评估它,并且它的评估很好。还需要更多的背景。

答案 2 :(得分:0)

我明白了!由于复制和粘贴技巧不佳,我在函数中有太多括号。