From: blu@cellar.org (Dan Reed)
Newsgroups: alt.cad.autocad
Subject: TOWER.LSP, Towers of Hanoi game.
Date: 22 Dec 92 16:06:55 GMT
Organization: The Cellar BBS and public access system

Ok, Ok, I hate this game for the life of me...
 
HOWEVER!  Tell it to make like 50 rings, then type SOLVE.
 
Watch your computer go nuts!  Kinda cool..
-----------------------------------------
;
;       Tower of Hanoi
;
;                               Kelvin R. Throop   March 1985
;
;       This file implements the Tower of Hanoi problem.  It is as
;       specified in the rules:
;
;          1.  Only one disc may be moved at a time.
;          2.  No disc may be placed on top of a smaller one.
;
;       The only incompatibility with the original is that the universe
;       will not come to an end when this function completes (however, if
;       you run it with the specified number of discs, 64, the protons may
;       decay before it's done).
;
;       One defines the tower with the command TOWER, which asks for the
;       number of discs.  Scaling is automatic, as is clearing away of any
;       previous execution.  Once the tower is defined, the solution may
;       be accomplished with the command SOLVE.
;
;       The solution function, TRANSFER, is as given in Winston and Horn,
;       "LISP", second edition, pp. 112-114.
;
(defun C:TOWER ()
 
        (setq nrings (getint "Enter number of rings: "))
 
        (setq bthick 1)            ; base thickness
        (setq rthick 1)            ; ring thickness
        (setq smring 1.5)          ; smallest ring
        (setq ringinc 1.0)         ; ring size increment
        (setq postdia 1)           ; post diameter
        (setq airspace 0.1)        ; air space between rings
 
        (setq lring (+ smring (* nrings ringinc))) ; largest ring diameter
        (setq posta nil postb nil postc nil)       ; clearpossibleearlierrun
        (setq postl '(posta postb postc))          ; list of post lists
        (setq rspace (+ rthick airspace))          ; ring vertical spacing
 
        (setvar "blipmode" 0)      ; get rid of annoying distractions
        (setvar "cmdecho" 0)       ; disable echoing of commands
        (setvar "fillmode" 0)      ; make for better display
 
        ; Clean up if previous display on screen
 
        (if before (progn
              (command "vpoint" "0,0,0")
              (setq a 1)
              (while (<= a before)
                 (command "erase" "l" "")
                 (setq a (1+ a))
              )
              (command "layer" "set" "base" "")
           )
           (progn
              (command "layer" "new" "base,1,2,3,4,5,6"
                 "colour" 7 "base"
              )
              (setq a 0)
              (while (<= (setq a (1+ a)) 6)
                 (command "colour" a a)
              )
              (command "set" "base" "")
           )
        )
 
        ; Draw the base
 
        (command "elev" 0 bthick)
        (setq a (+ lring (* postdia 2)))
        (setq b (+ (* 3 (+ postdia lring)) postdia))
        (command "vpoint" "0,0,0") ; insure ZOOM does the right thing
        (command "solid" '(0 0) (list 0 a) (list b 0) (list b a))
        (command)                  ; terminate solid
        (command "zoom" "e")
 
        ; Draw the posts
 
        (command "elev" bthick (* rspace (1+ nrings)))
        (setq a (+ postdia lring))
        (setq b (+ postdia (/ lring 2)))
        (setq postposy (+ postdia (/ lring 2)))
        (setq postposx (list b (+ b a) (+ b a a)))
        (command "circle" (list (car postposx) postposy) "d" postdia)
        (command "circle" (list (cadr postposx) postposy) "d" postdia)
        (command "circle" (list (caddr postposx) postposy) "d" postdia)
        (setq bthick (+ bthick airspace))    ; offsetpositionoflowestring
        (command "vpoint" "1,1,1") ; establish viewpoint
 
        ; Put rings on post 1 initially
 
        (setq i 1 l 5)
        (setq d bthick)
        (setq r (/ lring 2))
        (while (<= i nrings)
           (command "layer" "set" (1+ (setq l (rem (1+ l) 6))) "")
           (command "elev" d rthick)
           (command "circle" (list b postposy) r)
           (setq posta (cons (list r (1+ l)) posta))
           (setq r (- r (/ ringinc 2)))
           (setq d (+ d rspace))
           (setq i (1+ i))
        )
 
        ; Tell the user how to proceed
 
        (setq before (+ nrings 4)) ; save previous ring count
        (princ "\nType SOLVE to perform the solution.\n")
)
 
; Command function to perform solution
 
(defun C:SOLVE ()
        (transfer 1 2 3 nrings)
        (redraw)
)
 
; Move disc from one post to another
 
(defun move-disc (from to)
        (setq lfrom (nth (1- from) postl))
        (setq lto (nth (1- to) postl))
        (setq elfrom (eval lfrom))
        (setq elto (eval lto))
; **    (print (list 'Move 'disc 'from lfrom 'to lto))
        (setq top (car elfrom))
        (set lfrom (cdr elfrom))
        (command "layer" "set" (cadr top) "")
        (command "elev" (+ bthick (* (length elfrom) rspace)) rthick)
        (command "erase" (list (nth (1- from) postposx)
                               (+ postposy (car top))) "")
        (command "elev" (+ bthick (* (length elto) rspace)) rthick)
        (command "circle" (list (nth (1- to) postposx) postposy) (car top))
        (set lto (cons top elto))
)
 
; Perform transfer of discs  (This is actually the entire solver)
 
(defun transfer (from to spare n)
        (cond ((= n 1) (move-disc from to))
              (t (transfer from spare to (1- n))
                 (move-disc from to)
                 (transfer spare to from (1- n)
              )
           )
        )
)
-----

have fun!

     Dan Reed - blu@cellar.org - AutoCAD Geek -Industrial Music Lover
      68'Cougar, 89'VW Golf, 74'Honda Cb360, 89'Rollerblade Zetras'
  "Anyone can get a gun Otis. You can make a phone call and get a gun."
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU