home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / FPC355_3.ZIP / ZIMMER.ZIP / MIDNIGHT.SEQ < prev    next >
Encoding:
Text File  |  1989-10-05  |  5.6 KB  |  145 lines

  1. \ MIDNIGHT.SEQ  (C) Copyright 1979, 1989 Peter Midnight
  2.  
  3. comment:
  4.  
  5.    I first wrote this graphic presentation of the ancient Towers of Hanoi
  6. puzzle in Pascal.  The class assignment was to use recursion to produce a
  7. list of the moves required to solve the puzzle.  But I wanted to see the
  8. rings move.  That version was published in the Jan/Feb 1980 Newsletter of
  9. the Homebrew Computer Club.
  10.  
  11.    Next I translated this program into FIG Forth.  In order to compare the
  12. two languages, I resisted the temptation to improve the program in the
  13. process of translation.  That version is published in FORTH Dimensions
  14. Volume 2 Number 2 and in The Best of FORTH Dimensions.
  15.  
  16.    Now I have transported the same program into F-PC, again without
  17. improvement.  This is my first machine readable publication of this program.
  18.  
  19.    This program is my claim to fame.  As long as its popularity continues,
  20. I may never need another.   Peter Midnight
  21.  
  22. comment;
  23.  
  24. ONLY FORTH ALSO DEFINITIONS     DECIMAL
  25.  
  26. : GOTOXY        ( row col --- ) \ position cursor
  27.         AT ;
  28.  
  29. : CLEARSCREEN   ( --- )         \ clear screen
  30.         CLS ;
  31.  
  32. COLS 3 - 6 / VALUE NMAX         \ maximum rings for display size
  33.  
  34. NMAX VALUE N                    \ number of rings
  35.  
  36. FALSE CONSTANT HELL_FREEZES_OVER
  37.  
  38. TRUE CONSTANT THE_POPE_IS_A_CATHOLIC
  39.  
  40. ASCII + VALUE COLOR             \ character used to represent a ring
  41.  
  42. 13 ARRAY RING                   \ array (1..N) of tower numbers
  43.  
  44. : DELAY         ( centiseconds --- )    \ pause for clarity
  45.         10 * MS ;
  46.  
  47. : POS           ( tower --- col )       \ get display column for tower
  48.         N 2*   1+   *   N + ;
  49.  
  50. : HALFDISPLAY   ( color size --- )      \ display half a ring
  51.         0 DO   DUP EMIT   LOOP   DROP ;
  52.  
  53. : <DISPLAY>     ( line color size --- ) \ display a whole ring
  54.         2DUP   HALFDISPLAY   ROT 3 <   IF BL   ELSE ASCII |   THEN
  55.         EMIT   HALFDISPLAY ;
  56.  
  57. : DISPLAY       ( size col line color --- )     \ display at proper position
  58.         SWAP >R   -ROT   OVER - R@ GOTOXY
  59.         R>   -ROT   <DISPLAY> ;
  60.  
  61. : PRESENCE      ( tower ring --- f )    \ true if ring is on tower
  62.         RING +   C@   = ;
  63.  
  64. : LINE          ( tower --- line )      \ top of pile on tower
  65.         4   N 1+ 1 DO   OVER I PRESENCE   0= -   LOOP   NIP ;
  66.  
  67.  
  68. : RAISE         ( size tower --- )      \ raise ring
  69.         DUP POS   SWAP LINE   2 SWAP
  70.         DO      2DUP I    BL    DISPLAY \ erase ring where it is
  71.                 2DUP I 1- COLOR DISPLAY \ show it one line higher
  72.         -1 +LOOP   2DROP ;
  73.  
  74. : LOWER         ( size tower --- )      \ lower ring
  75.         DUP POS   SWAP LINE 1+   2
  76.         DO      2DUP I 1- BL    DISPLAY \ erase ring where it is
  77.                 2DUP I    COLOR DISPLAY \ show it one line lower
  78.         LOOP   2DROP ;
  79.  
  80. : MOVELEFT      ( size source destination --- ) \ move ring to left
  81.         POS   SWAP   POS 1-
  82.         DO      DUP I 1+ 1 BL    DISPLAY        \ erase it where it is
  83.                 DUP I    1 COLOR DISPLAY        \ show it 1 column left
  84.         -1 +LOOP   DROP ;
  85.  
  86. : MOVERIGHT     ( size source destination --- ) \ move ring to right
  87.         POS 1+   SWAP   POS 1+
  88.         DO      DUP I 1- 1 BL    DISPLAY        \ erase it where it is
  89.                 DUP I    1 COLOR DISPLAY        \ show it 1 column right
  90.         LOOP   DROP ;
  91.  
  92. : TRAVERSE      ( size source destination --- ) \ move ring sideways
  93.         2DUP >   IF MOVELEFT   ELSE MOVERIGHT   THEN ;
  94.  
  95. : MOVE          ( size source destination --- ) \ complete one move
  96.         KEY?   IF   0 N 6 + GOTOXY   CURSOR-ON   ABORT   THEN
  97.         -ROT 2DUP RAISE
  98.         >R 2DUP R> ROT TRAVERSE
  99.         2DUP   RING + C!                \ also update location array
  100.         SWAP LOWER ;
  101.  
  102. \ The following word is the recursive solution to the puzzle.
  103.  
  104. : MULTIMOVE     ( size source destination spare --- )   RECURSIVE
  105.         3 PICK   1 =                    \ test for case of smallest ring
  106.         IF      DROP MOVE               \ single ring move
  107.         ELSE    2>R SWAP 1- SWAP 2R>    \ refer to next smaller ring, above
  108.                 4DUP SWAP MULTIMOVE     \ move it to spare tower
  109.                 4DUP DROP               \ drop spare tower number
  110.                 ROT 1+ -ROT MOVE        \ move specified ring
  111.                 -ROT SWAP MULTIMOVE     \ move next smaller ring from spare
  112.         THEN ;
  113.  
  114. : MAKETOWER     ( tower --- )           \ draw tower on display
  115.         POS   4 N +   3
  116.         DO      DUP I GOTOXY
  117.                 ASCII | EMIT
  118.         LOOP   DROP ;
  119.  
  120. : MAKEBASE      ( --- )                 \ draw base on display
  121.         0 N 4 + GOTOXY
  122.         N 6 * 3 + 0 DO   ASCII - EMIT   LOOP ;
  123.  
  124. : MAKERING      ( tower size --- )      \ materialize ring on display
  125.         2DUP RING + C!                  \ mark ring location in array
  126.         SWAP LOWER ;
  127.  
  128. : SETUP         ( --- )                 \ initialize display of puzzle
  129.         CLEARSCREEN   CURSOR-OFF
  130.         N 1+ 0 DO   1 RING I + C!   LOOP        \ initialize array
  131.         3 0 DO   I MAKETOWER   LOOP             \ draw towers
  132.         MAKEBASE                                \ draw base
  133.         1 N DO   0 I MAKERING   -1 +LOOP ;      \ materialize rings
  134.  
  135. \ The following word performs the solution repeatedly.
  136.  
  137. : TOWERS        ( quantity --- )        \ use specified number of rings
  138.         1 MAX   NMAX MIN   !> N
  139.         SETUP   N 2 0 1
  140.         BEGIN   OVER POS   N 4 +   GOTOXY       \ put cursor under rings
  141.                 N 0 DO   BEEP   50 DELAY   LOOP \ announce completion
  142.                 ROT   4DUP   MULTIMOVE          \ move all to next tower
  143.         HELL_FREEZES_OVER UNTIL ;               \ repeat indefinitely
  144.  
  145.