lambda内部的非法函数调用

时间:2013-01-07 20:34:22

标签: lambda lisp common-lisp chess

我正在研究一种在国际象棋游戏中计算棋子有效动作的功能。函数white-pawn-move有效。当我试图将其推广到任一玩家的棋子(pawn-move)时,我会遇到非法的函数调用。我已经在repl中测试了funcalls,我认为这不是问题。

我做错了什么?

http://pastebin.com/fEiQTwi5

(defun white-pawn-move (file rank)       
  (let ((movelist '()))
    (if (and (within-boardp file (+ rank 1))
             (eql #\s (aref *board* (+ rank 1) file)))
        (push (cons file (+ rank 1)) movelist))
    (if (= rank 1) 
        (push (cons file (+ rank 2)) movelist))
    (if (and (within-boardp (- file 1) (+ rank 1))
             (belongs-to-opponent (aref *board*  (+ rank 1) (- file 1))))
        (push (cons (- file 1) (+ rank 1)) movelist))
    (if (and (within-boardp (+ file 1) (+ rank 1))
             (belongs-to-opponent (aref *board* (+ rank 1) (+ file 1))))
        (push (cons (+ file 1) (+ rank 1)) movelist))
    movelist))      

;refactor:
;file / rank numeric      
(defun pawn-move (direction)
  (let ((startrank (if (eql direction #'+)
                       1
                       6)))
    (lambda (file rank)
      (let ((movelist '()))
        (if (and (within-boardp file (funcall direction rank 1))
                 (eql #\s (aref *board* (funcall direction rank 1) file)))
            (push (cons file (funcall direction rank 1)) movelist))
        (if (= rank startrank) 
            (push (cons file (funcall direction rank 2)) movelist))
        (if (and (within-boardp (- file 1) (funcall direction rank 1))
                 (belongs-to-opponent (aref *board* 
                                            (funcall direction rank 1)
                                            (- file 1))))
            (push (cons (- file 1) (funcall direction rank 1)) movelist))
        (if (and (within-boardp (+ file 1) (funcall direction rank 1))
                 (belongs-to-opponent (aref *board*
                                            (funcall direction rank 1)
                                            (+ file 1))))
            (push (cons (+ file 1) (funcall direction rank 1)) movelist))
        movelist))))
;desired usage
(setf (gethash #\P *move-table*) (pawn-move #'+))    
(setf (gethash #\p *move-table*) (pawn-move #'-))

2 个答案:

答案 0 :(得分:0)

你能表明你得到的错误吗?

我刚刚使用Emacs Lisp尝试了您的代码(将字符表示更改为Emacs-Lisp),并且我没有错误用于性别(pawn-move #'+)(pawn-move #'-)。他们是什么引起了你的错误?我为(pawn-move #'+)得到了这个,例如:

     (lambda (file rank)
       (let ((movelist 'nil))
         (if (and (within-boardp
                   file
                   (funcall direction rank 1))
                  (eql 115
                       (aref *board*
                             (funcall direction rank 1)
                             file)))
             (push (cons file (funcall direction rank 1))
                   movelist))
         (if (= rank startrank)
             (push (cons file (funcall direction rank 2))
                   movelist))
         (if (and (within-boardp
                   (- file 1)
                   (funcall direction rank 1))
                  (belongs-to-opponent
                   (aref *board* (funcall direction rank 1)
                         (- file 1))))
             (push (cons (- file 1) (funcall direction rank 1))
                   movelist))
         (if (and (within-boardp
                   (+ file 1)
                   (funcall direction rank 1))
                  (belongs-to-opponent
                   (aref *board*
                         (funcall direction rank 1)
                         (+ file 1))))
             (push (cons (+ file 1) (funcall direction rank 1))
                   movelist))
         movelist))


总之,或许可以更详细地说明你所看到的内容。

答案 1 :(得分:0)

你的white-pawn-move会返回一个movelist,而你的pawn-move会返回一个可以返回一个movelist的函数。我想您曾尝试调用先前调用(pawn-move #'+)的{​​{1}},但您必须调用(white-pawn-move)