views:

88

answers:

4

I'm working on making a two player tic-tac-toe game, and am in the phase where I work out all of the errors in my code. The current error i'm stuck on is an illegal function call error in the following code:

(cond

[...snip...]

((= CHOICE 3)
 (IF (NUMBERP (AREF *BOARD* 0 2))
     (SETF (AREF *BOARD* 0 2) *MARKER*)
     (INVALID-SELECTION)))

What am I doing wrong?

EDIT The whole function looks like this:

(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))))
+1  A: 

It's pretty simple, the code is trying to use (= choice 3) as an operator or lambda-expression, which it isn't, so you get an error. Maybe you mis-typed something? Looks like a disembodied COND clause to me.

Cirno de Bergerac
Those aren't the evaluation rules Common Lisp uses.
Xach
Sorry, it is a clause in a `(cond`
Andrew
@Xach Oh, I see now.
Cirno de Bergerac
A: 

The first thing in a normally-evaluated form should almost always be a symbol that names a function, macro, or special operator. The first thing in your form is the list (= CHOICE 3). More context would help; as Cirno said, this looks like a disembodied COND clause.

edit I put your code in a function and added enough parentheses and variable definitions to evaluate it, and it evaluates fine. Still need more context.

Xach
+1  A: 

I figured it out! I had too many parentheses in the function due to poor copy+pasting skills.

Andrew
That should teach you. Never use copy/paste. In this case, you can `(let ((x (floor choice 3)) (y (rem choice 3))) (if (numberp (aref *board* x y)) (setf (aref *board* x y) *marker*) (invalid-selection)))`, instead of the long `cond`. In other cases, factor out the duplicate code into a function or macro.
Svante
If you know what multiple values are, you can also use both return values from the `floor` function directly: `(multiple-value-bind (x y) (floor choice 3) (if ...))`.
Svante
+1  A: 

Your function only looks like that, only because it is not indented correctly.

Select the code and indent the region - any editor that understands a bit Lisp, should do that for you. In LispWorks this is done with the extended editor command 'Indent Region'.

You can also replace the COND with a simpler CASE:

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

The whole function can be made smaller using CASE and a local function:

(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)))))
Rainer Joswig
My function was indented differently than is shown,that's just how it came out when I pasted it on the page :/
Andrew