; ; Place n queens on a board (graphical version) ; See Winston and Horn Ch. 11 ; ; Usage: ; (queens ) ; where is an integer -- the size of the board - try (queens 4) ; ; I do not know who the original Author of this is but it was found with some ; XLISP example lisp programs. This has been slightly modified to run on ; PC-LISP V2.13. ; ; Peter Ashwood-Smith ; August 22nd, 1986 ; Do two queens threaten each other ? (defun threat (i j a b) (or (= i a) ;Same row (= j b) ;Same column (= (- i j) (- a b)) ;One diag. (= (+ i j) (+ a b)))) ;the other diagonal ; Is poistion (n,m) on the board safe for a queen ? (defun conflict (n m board) (cond ((null board) nil) ((threat n m (caar board) (cadar board)) t) (t (conflict n m (cdr board))))) ; Place queens on a board of size SIZE (defun queens (size) (prog (n m board soln) (setq soln 0) ;Solution # (setq board ()) (setq n 1) ;Try the first row loop-n (setq m 1) ;Column 1 loop-m (cond ((conflict n m board) (go un-do-m))) ;Check for conflict (setq board (cons (list n m) board)) ; Add queen to board (cond ((> (setq n (1+ n)) size) ; Placed N queens ? (print-board (reverse board) (setq soln (1+ soln))))) ; Print it (go loop-n) ; Next row which column? un-do-n (cond ((null board) (return 'Done))) ; Tried all possibilities (setq m (cadar board)) ; No, Undo last queen placed (setq n (caar board)) (setq board (cdr board)) un-do-m (cond ((> (setq m (1+ m)) size) ; Go try next column (go un-do-n)) (t (go loop-m))))) ;Print a board (defun print-board (board soln) (prog (size) (setq size (length board)) ;we can find our own size (princ "\f\n\t\tSolution: ") (princ soln) (princ "\n\n\t") (print-header size 1) (princ "\n") (print-board-aux board size 1) (princ "\n") ) ) ; Put Column #'s on top (defun print-header (size n) (cond ((> n size) (princ "\n")) (t (prog () (patom n) (princ " ") (print-header size (1+ n)))))) (defun print-board-aux (board size row) (princ "\n") (cond ((null board) ()) (t (prog () (princ row) ;print the row # (princ "\t") (print-board-row (cadar board) size 1) ;Print the row (print-board-aux (cdr board) size (1+ row)))))) ;Next row (defun print-board-row (column size n) (cond ((> n size)()) (t (prog () (cond ((equal column n) (princ "Q")) (t (princ "."))) (princ " ") (print-board-row column size (1+ n))))))