首先,你仍然在勢在必行土地。
(defun get-neighbours (board x y)
(let ((output '()))
(push (get-if-possible board (1+ x) y) output)
(push (get-if-possible board (1- x) y) output)
(push (get-if-possible board x (1+ y)) output)
(push (get-if-possible board x (1- y)) output)
(push (get-if-possible board (1+ x) (1+ y)) output)
(push (get-if-possible board (1- x) (1- y)) output)
(push (get-if-possible board (1+ x) (1- y)) output)
(push (get-if-possible board (1- x) (1+ y)) output)
output))
你這樣做:變量聲明,將其綁定到NIL,變量的變異,返回變量。
很簡單,就是:
(defun get-neighbours (board x y)
(list (get-if-possible board (1+ x) y)
(get-if-possible board (1- x) y)
(get-if-possible board x (1+ y))
(get-if-possible board x (1- y))
(get-if-possible board (1+ x) (1+ y))
(get-if-possible board (1- x) (1- y))
(get-if-possible board (1+ x) (1- y))
(get-if-possible board (1- x) (1+ y))))
可以 '縮短' 與當地的宏代碼:
(defun get-neighbours (board x y)
(macrolet ((all-possible (&rest x-y-combinations)
`(list
,@(loop for (a b) on x-y-combinations by #'cddr
collect `(get-if-posssible board ,a ,b)))))
(all-possible (1+ x) y
(1- x) y
x (1+ y)
x (1- y)
(1+ x) (1+ y)
(1- x) (1- y)
(1+ x) (1- y)
(1- x) (1+ y))))
現在人們可以抽象了一點:
(defmacro invoke-fn-on (fn &rest x-y-combinations)
`(funcall (function ,fn)
,@(loop for (a b) on x-y-combinations by #'cddr
collect `(get-if-posssible board ,a ,b))))
(defun get-neighbours (board x y)
(invoke-fn-on list
(1+ x) y
(1- x) y
x (1+ y)
x (1- y)
(1+ x) (1+ y)
(1- x) (1- y)
(1+ x) (1- y)
(1- x) (1+ y)))
關於LOOP:
> (loop for (a b) on '(1 2 3 4 5 6) by #'cddr collect (list a b))
((1 2) (3 4) (5 6))
ON將模式(a b)移動到列表上(1 2 3 4 5 6)。它會給(1 2),(2 3),(3 4),(4 5)和(5 6)。每次迭代時,通過使用CDR獲取剩餘列表,將列表向前移動一個。現在說,我們移動CDDR的兩個項目,而不是CDR的一個項目。所以我們得到三次迭代和對(1 2),(3 4)和(5 6)。
另一種方法是通過引入不同的表結構的座標對稍微簡化LOOP:
(defmacro invoke-fn-on (fn x-y-combinations)
`(funcall (function ,fn)
,@(loop for (a b) in x-y-combinations
collect `(get-if-posssible board ,a ,b))))
(defun get-neighbours (board x y)
(invoke-fn-on list
'(((1+ x) y )
((1- x) y )
(x (1+ y))
(x (1- y))
((1+ x) (1+ y))
((1- x) (1- y))
((1+ x) (1- y))
((1- x) (1+ y)))))
嗯,好吧,循環宏中關鍵字「by」和「on」的含義對我而言仍然是未知的。我仍然比較喜歡安格斯的答案,但我仍然非常感謝你的幫助! – Johan 2011-04-26 21:12:39
我不知道你可以用循環做這樣複雜而有用的事情。有投票權! – whoplisp 2011-07-04 00:42:43