Я сбит с толку. Я играю с игрой в крестики-нолики из главы 10 книги COMMON LISP: A Gentle Introduction to Symbolic Computation https://www.cs.cmu.edu/~dst/LispBook/book.pdf . Я все обработал в IDE, сохранил, а потом скомпилировал+загрузил. Запустил несколько игр без проблем. Итак, я скопировал заведомо рабочий файл и начал настраивать. Опять же, никаких проблем - все работало нормально. Однако теперь, когда я запускаю (играю в одну игру), я получаю следующую ошибку:
Ошибка: попытка получить значение несвязанной переменной '*OPPONENT**'
Я получаю ошибку как в оригинале, так и в копии. Я закрыл AllegroCL и перезагрузил компьютер, но проблема осталась после перезагрузки. Затем я обновил программу и запустил ./update.sh в ее каталоге приложений.
Наконец, я решил скопировать пример прямо из PDF в совершенно новый файл в другом каталоге, и у меня возникла та же проблема. Не знаю, что изменилось, но меня это, мягко говоря, порадовало.
(defun make-board ()
(list 'board 0 0 0 0 0 0 0 0 0))
(defun convert-to-letter (v)
(cond ((equal v 1) "O")
((equal v 10) "X")
(t " ")))
(defun print-row (x y z)
(format t "~& ~A | ~A | ~A"
(convert-to-letter x)
(convert-to-letter y)
(convert-to-letter z)))
(defun print-board (board)
(format t "~%")
(print-row
(nth 1 board) (nth 2 board) (nth 3 board))
(format t "~& -----------")
(print-row
(nth 4 board) (nth 5 board) (nth 6 board))
(format t "~& -----------")
(print-row
(nth 7 board) (nth 8 board) (nth 9 board))
(format t "~%~%"))
(defun make-move (player pos board)
(setf (nth pos board) player)
board)
(setf *triplets*
'((1 2 3) (4 5 6) (7 8 9) ;Horizontal triplets.
(1 4 7) (2 5 8) (3 6 9) ;Vertical triplets.
(1 5 9) (3 5 7))) ;Diagonal triplets.
(defun sum-triplet (board triplet)
(+ (nth (first triplet) board)
(nth (second triplet) board)
(nth (third triplet) board)))
(defun compute-sums (board)
(mapcar #'(lambda (triplet)
(sum-triplet board triplet))
*triplets*))
(defun winner-p (board)
(let ((sums (compute-sums board)))
(or (member (* 3 *computer*) sums)
(member (* 3 *opponent*) sums))))
(defun play-one-game ()
(if (y-or-n-p "Would you like to go first? ")
(opponent-move (make-board))
(computer-move (make-board))))
(defun opponent-move (board)
(let* ((pos (read-a-legal-move board))
(new-board (make-move
*opponent*
pos
board)))
(print-board new-board)
(cond ((winner-p new-board)
(format t "~&You win!"))
((board-full-p new-board)
(format t "~&Tie game."))
(t (computer-move new-board)))))
(defun read-a-legal-move (board)
(format t "~&Your move: ")
(let ((pos (read)))
(cond ((not (and (integerp pos)
(<= 1 pos 9)))
(format t "~&Invalid input.")
(read-a-legal-move board))
((not (zerop (nth pos board)))
(format t
"~&That space is already occupied.")
(read-a-legal-move board))
(t pos))))
(defun board-full-p (board)
(not (member 0 board)))
(defun computer-move (board)
(let* ((best-move (choose-best-move board))
(pos (first best-move))
(strategy (second best-move))
(new-board (make-move
*computer* pos board)))
(format t "~&My move: ~S" pos)
(format t "~&My strategy: ~A~%" strategy)
(print-board new-board)
(cond ((winner-p new-board)
(format t "~&I win!"))
((board-full-p new-board)
(format t "~&Tie game."))
(t (opponent-move new-board)))))
(defun random-move-strategy (board)
(list (pick-random-empty-position board)
"random move"))
(defun pick-random-empty-position (board)
(let ((pos (+ 1 (random 9))))
(if (zerop (nth pos board))
pos
(pick-random-empty-position board))))
(defun make-three-in-a-row (board)
(let ((pos (win-or-block board
(* 2 *computer*))))
(and pos (list pos "make three in a row"))))
(defun block-opponent-win (board)
(let ((pos (win-or-block board
(* 2 *opponent*))))
(and pos (list pos "block opponent"))))
(defun win-or-block (board target-sum)
(let ((triplet (find-if
#'(lambda (trip)
(equal (sum-triplet board
trip)
target-sum))
*triplets*)))
(when triplet
(find-empty-position board triplet))))
(defun find-empty-position (board squares)
(find-if #'(lambda (pos)
(zerop (nth pos board)))
squares))
(defun choose-best-move (board) ;Second version.
(or (make-three-in-a-row board)
(block-opponent-win board)
(random-move-strategy board)))
*opponent*
. Ты? Если нет, то вполне очевидно, почему он не связан. - person Charles Duffy   schedule 06.10.2014defvar
илиdefparameter
для привязки глобальных специальных переменных.Setf
просто устанавливает. - person Svante   schedule 06.10.2014