home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / xl21hos2.zip / QUEENS2.LSP < prev    next >
Lisp/Scheme  |  1995-12-27  |  2KB  |  73 lines

  1. ; queens2.lsp
  2. ;
  3. ; Place n queens on a board (graphical version)
  4. ;  See Winston and Horn Ch. 11
  5. ; Usage:
  6. ;    (queens <n>)
  7. ;          where <n> is an integer -- the size of the board - try (queens 4)
  8.  
  9. ; Do two queens threaten each other ?
  10. (defun threat (i j a b)
  11.   (or (eql i a)            ;Same row
  12.       (eql j b)            ;Same column
  13.       (eql (- i j) (- a b))    ;One diag.
  14.       (eql (+ i j) (+ a b))))    ;the other diagonal
  15.  
  16. ; Is position (n,m) on the board safe for a queen ?
  17. (defun conflict (n m board)
  18.   (cond ((null board) nil)
  19.     ((threat n m (caar board) (cadar board)) t)
  20.     (t (conflict n m (cdr board)))))
  21.  
  22.  
  23. ; Place queens on a board of size SIZE
  24. (defun queens (size)
  25.   (prog (n m board soln)
  26.     (setq soln 0)            ;Solution #
  27.     (setq board nil)
  28.     (setq n 1)            ;Try the first row
  29.     loop-n
  30.     (setq m 1)            ;Column 1
  31.     loop-m
  32.     (cond ((conflict n m board) (go un-do-m))) ;Check for conflict
  33.     (setq board (cons (list n m) board))       ; Add queen to board
  34.     (cond ((> (setq n (1+ n)) size)            ; Placed N queens ?
  35.            (print-board (reverse board) (setq soln (1+ soln))))) ; Print it
  36.     (go loop-n)                       ; Next row which column?
  37.     un-do-n
  38.     (cond ((null board) (return 'Done))        ; Tried all possibilities
  39.           (t (setq m (cadar board))           ; No, Undo last queen placed
  40.          (setq n (caar board))
  41.          (setq board (cdr board))))
  42.  
  43.     un-do-m
  44.     (cond ((> (setq m (1+ m)) size)          ; Go try next column
  45.            (go un-do-n))
  46.           (t (go loop-m)))))
  47.  
  48.  
  49. ;Print a board
  50. (defun print-board  (board soln &aux size)
  51.   (setq size (length board))        ;we can find our own size
  52.   (format t "\t\tSolution ~s\n\n\t" soln)
  53.   (print-header size 1)
  54.   (print-board-aux board size)
  55.   (terpri))
  56.  
  57. ; Put Column #'s on top
  58. (defun print-header (size n)
  59.   (dotimes (i size) (format t "~s " (1+ i)))
  60.   (terpri))
  61.  
  62. (defun print-board-aux (board size &aux (row 0))
  63.   (mapc #'(lambda (x) 
  64.           (format t "~s\t" (setq row (1+ row)))
  65.           (print-board-row (cadr x) size))
  66.     board))
  67.           
  68. (defun print-board-row (column size)
  69.        (dotimes (i size) (princ (if (eql column (1+ i)) "Q " ". ")))
  70.        (terpri))
  71.  
  72.