2010-10-30 6 views
2

Je travaille sur un jeu de tic-tac-toe à deux joueurs, et je suis dans la phase où je travaille toutes les erreurs dans mon code. L'erreur actuelle je suis bloqué sur une erreur illegal function call dans le code suivant:La fonction illégale appelle en commun Lisp

(cond 

[...snip...] 

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

Qu'est-ce que je fais mal?

EDIT La fonction entière ressemble à ceci:

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

Répondre

0

Je l'ai compris! J'ai eu trop de parenthèses dans la fonction en raison de mauvaises compétences de copie + collage.

+1

Cela devrait vous enseigner. N'utilisez jamais copier/coller. Dans ce cas, vous pouvez '(let ((x (floor choice 3)) (y (rem choix 3))) (if (nombre (aref * board * xy)) (setf (aref * tableau * xy) * marqueur *) (invalid-selection))) ', au lieu du long' cond'. Dans d'autres cas, factoriser le code en double dans une fonction ou une macro. – Svante

+1

Si vous connaissez les valeurs multiples, vous pouvez également utiliser directement les deux valeurs de retour de la fonction 'floor':' (multiple-value-bind (x y) (floor choice 3) (si ...)) '. – Svante

0

La première chose sous une forme normalement évaluée doit presque toujours être un symbole que les noms d'une fonction, macro ou opérateur spécial. La première chose dans votre formulaire est la liste (= CHOICE 3). Plus de contexte aiderait; Comme l'a dit Cirno, cela ressemble à une clause COND désincarnée.

éditer J'ai mis votre code dans une fonction et ajouté assez de parenthèses et de définitions de variables pour l'évaluer, et il évalue bien. Encore besoin de plus de contexte.

2

Votre fonction ne ressemble qu'à cela, uniquement parce qu'elle n'est pas indentée correctement.

Sélectionnez le code et indentez la région - tout éditeur qui comprend un peu Lisp, devrait le faire pour vous. Dans LispWorks, ceci est fait avec la commande d'édition étendue 'Indent Region'.

Vous pouvez également remplacer le COND avec un cas plus simple:

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

La fonction entière peut être réduite en utilisant CASE et une fonction locale:

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

Ma fonction a été indentée différemment de ce qui est affiché, c'est ainsi qu'elle est apparue lorsque je l'ai collée sur la page: / – Andy

Questions connexes