(defparameter *moves*
'((1 2)
(2 1)
(-1 2)
(-2 1)
(-1 -2)
(-2 -1)
(1 -2)
(2 -1))
"List of possible moves")
(defun position-valid-p (position)
(and (> (first position) 0)
(< (first position) 8)
(> (second position) 0)
(< (second position) 8)))
(defun move (position move)
(mapcar #'+ position move))
(defun positi target)
(every #'identity (mapcar #'equal position target)))
(defun knight-moves (init-position target-position max-n
&key; (unique nil))
"Return path from INIT-POSITION to TARGET-POSITION in MAX-N moves.
Path must not reach TARGET-POSITION in fewer than MAX-N moves
If UNIQUE is T, path must not revist already visited places"
(let (path)
(labels
((evaluate-next (current-position n)
#+skip1 (format t "~a: ~a~%" n current-position)
(push current-position path)
(if (zerop n)
(if (positi target-position)
(return-from knight-moves (nreverse path))
(pop path))
(if (positi target-position)
(pop path)
(dolist (move *moves* (pop path))
(let ((new-position (move current-position move)))
(when (and (position-valid-p new-position)
(if (and unique
path)
(not (find current-position path :test #'equal))
t))
(evaluate-next new-position (1- n)))))))))
(evaluate-next init-position max-n))
(rest path)))Add a code snippet to your website: www.paste.org