home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / lisp211.zip / QUEENS.L < prev    next >
Lisp/Scheme  |  1986-05-15  |  3KB  |  99 lines

  1.  
  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. ; I do not know who the original Author of this is but it was found with some
  10. ; XLISP example lisp programs. This has been slightly modified to run on   
  11. ; PC-LISP V2.11.
  12. ;
  13. ;               Peter Ashwood-Smith
  14. ;               May 15, 1986
  15.  
  16. ; Do two queens threaten each other ?
  17.  
  18. (defun threat (i j a b)
  19.   (or (= i a)                       ;Same row
  20.       (= j b)                       ;Same column
  21.       (= (- i j) (- a b))           ;One diag.
  22.       (= (+ i j) (+ a b))))         ;the other diagonal
  23.  
  24. ; Is poistion (n,m) on the board safe for a queen ?
  25.  
  26. (defun conflict (n m board)
  27.   (cond ((null board) nil)
  28.     ((threat n m (caar board) (cadar board)) t)
  29.     (t (conflict n m (cdr board)))))
  30.  
  31.  
  32. ; Place queens on a board of size SIZE
  33.  
  34. (defun queens (size)
  35.   (prog (n m board soln)
  36.     (setq soln 0)                   ;Solution #
  37.     (setq board ())
  38.     (setq n 1)                      ;Try the first row
  39.    loop-n     
  40.     (setq m 1)                      ;Column 1
  41.    loop-m     
  42.     (cond ((conflict n m board) (go un-do-m))) ;Check for conflict
  43.     (setq board (cons (list n m) board))       ; Add queen to board
  44.     (cond ((> (setq n (1+ n)) size)            ; Placed N queens ?
  45.            (print-board (reverse board) (setq soln (1+ soln))))) ; Print it
  46.     (go loop-n)                                ; Next row which column?
  47.    un-do-n     
  48.     (cond ((null board) (return 'Done)))       ; Tried all possibilities
  49.     (setq m (cadar board))                     ; No, Undo last queen placed
  50.     (setq n (caar board))
  51.     (setq board (cdr board))  
  52.    un-do-m
  53.     (cond ((> (setq m (1+ m)) size)          ; Go try next column
  54.            (go un-do-n))
  55.           (t (go loop-m)))))
  56.  
  57.  
  58. ;Print a board
  59.  
  60. (defun print-board  (board soln)
  61.   (prog (size)
  62.     (setq size (length board))            ;we can find our own size
  63.     (princ "\f\n\t\tSolution: ")
  64.     (princ soln)
  65.     (princ "\n\n\t")
  66.     (print-header size 1)
  67.     (princ "\n")
  68.     (print-board-aux board size 1)
  69.     (princ "\n")
  70.   )
  71. )
  72.  
  73. ; Put Column #'s on top
  74.  
  75. (defun print-header (size n)
  76.   (cond ((> n size) (princ "\n"))
  77.     (t (prog () (patom n)
  78.             (princ " ") 
  79.             (print-header size (1+ n))))))
  80.  
  81. (defun print-board-aux (board size row)
  82.   (princ "\n")
  83.   (cond ((null board) ())
  84.     (t (prog () 
  85.          (princ row)                  ;print the row #
  86.          (princ "\t")
  87.          (print-board-row (cadar board) size 1) ;Print the row
  88.          (print-board-aux (cdr board) size (1+ row))))))  ;Next row
  89.  
  90. (defun print-board-row (column size n)
  91.   (cond ((> n size)())
  92.     (t (prog () 
  93.           (cond ((equal column n) (princ "Q"))
  94.             (t (princ ".")))
  95.           (princ " ") 
  96.           (print-board-row column size (1+ n))))))
  97.  
  98.