home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / ctop.arj / TOWERS.C < prev   
C/C++ Source or Header  |  1989-02-28  |  5KB  |  215 lines

  1. /*
  2.  *           IBM RBBS-PC Tulsa, OK
  3.  *           Switching totally to the "C" Language
  4.  *           24 Hour operation 300/1200 baud XMODEM
  5.  *           918-664-8737
  6.  *           SYSOP LYNN LONG
  7.  *
  8.  * Modified for Zortech C & ANSI display Feb 89 by RPP, SAC @ KnowSoft
  9.  *
  10.  *            Towers of Hanoi
  11.  *
  12.  * The object of the game is to transfer the disks from
  13.  * the leftmost tower to the rightmost tower obeying the
  14.  * following set of rules:
  15.  *
  16.  * 1) Only the top disk of any tower may be moved at a time
  17.  * 2) At no time must a larger disk be placed on a smaller disk
  18.  *
  19.  */
  20.  
  21. #define ESC            0x1b
  22.  
  23. #define MAX_RINGS        7    /* any more and we take forever */
  24.  
  25. #define POST            0xba    /* vertical double bar        */
  26. #define POST_BASE        0xca    /* T shape _|_            */
  27. #define BASE            0xcd    /* horizontal double bar    */
  28. #define RING            0xdc    /* solid block            */
  29.  
  30. #define SCREEN_WIDTH        80    /* number of columns        */
  31. #define SCREEN_HEIGHT        25    /* number of lines        */
  32. #define BASE_ROW        15    /* line no. of base of towers    */
  33. #define RING_WIDTH        ((((SCREEN_WIDTH - 2)/3) & 0xfe)-1)
  34. #define LEFT_POST        (RING_WIDTH/2+1)
  35. #define CENTER_POST        (LEFT_POST+RING_WIDTH)
  36. #define RIGHT_POST        (LEFT_POST+2*RING_WIDTH)
  37.  
  38. #define MOVING_ROW        2
  39. #define POST_HEIGHT        11    /* no. of lines in post        */
  40.  
  41. int    top[] = {BASE_ROW-1,BASE_ROW-1,BASE_ROW-1};
  42.  
  43. int pause;
  44.  
  45.  
  46. main()
  47. {
  48.     int nrings;
  49.  
  50.     printf("The Towers of Hanoi:\n");
  51.     printf("\n");
  52.     printf("This program is setup for use with an ANSI.SYS driver.\n");
  53.     printf("\n");
  54.  
  55.     do {
  56.         printf("Enter number of rings (between 1 and %d):",
  57.             MAX_RINGS);
  58.         scanf("%d", &nrings);
  59.     } while (nrings < 1 || nrings > MAX_RINGS);
  60.     
  61.     do {
  62.         printf("Speed factor (1=fast to 10=slow):");
  63.         scanf("%d", &pause);
  64.     } while (pause < 1 || pause > 10);
  65.  
  66.     setup(nrings);
  67.     
  68.     /* move nrings from post 0 to post 2 using post 1 */
  69.     hanoi(nrings, 0, 2, 1);
  70.  
  71.     curse(0, SCREEN_HEIGHT-2);
  72. }
  73.  
  74.  
  75.  
  76. hanoi(n, a, b, c)
  77. int    n, a, b, c;
  78. {
  79.     if (n == 0)    /* no more rings to move */
  80.         return;
  81.  
  82.     hanoi(n-1, a, c, b);
  83.     movering(n, a, b);
  84.     hanoi(n-1, c, b, a);
  85. }
  86.  
  87. setup(n)
  88. int    n;
  89. {
  90.     int    i;
  91.     
  92.     /* ANSI sequence to clear screen: */
  93.     curse(0, 0); outc(ESC); printf("[0J");
  94.     
  95.     /* draw three posts: */
  96.     for(i = MOVING_ROW+2; i < BASE_ROW; ++i) {
  97.         cput(LEFT_POST, i, POST);
  98.         cput(CENTER_POST, i, POST);
  99.         cput(RIGHT_POST, i, POST);
  100.     }
  101.     
  102.     /* draw the base: */
  103.     curse(0, BASE_ROW);
  104.     for(i = 1; i < SCREEN_WIDTH; ++i)
  105.         outc(BASE);
  106.  
  107.     /* draw the bottoms of the posts: */
  108.     cput(LEFT_POST, BASE_ROW, POST_BASE);
  109.     cput(CENTER_POST, BASE_ROW, POST_BASE);
  110.     cput(RIGHT_POST, BASE_ROW, POST_BASE);
  111.  
  112.     /* finally, draw in each ring on the left post: */
  113.     for(i = n; i > 0; --i)
  114.         draw(i, LEFT_POST, top[0]--, RING);
  115. }
  116.  
  117. outc(c)
  118. char    c;
  119. {
  120.     printf("%c", c);
  121. }
  122.     
  123. /* move the cursor to col x, row y */
  124. curse(x, y)
  125. int    x, y;
  126. {
  127.     wait();
  128.     outc(ESC); outc('[');
  129.     printf("%d;%dH", y+1, x+1);
  130. }
  131.  
  132. /* move the cursor to col x, row y, and output the character ch */
  133. cput(x, y, ch)
  134. char    ch;
  135. int    x, y;
  136. {
  137.     curse(x, y);
  138.     outc(ch);
  139. }
  140.  
  141.  
  142. /* draw a 'ring' of character ch, on row y, centred on col centre */
  143. draw(ringno, centre, y, ch)
  144. int    ringno, centre, y;
  145. char    ch;
  146. {
  147.     int    i;
  148.     curse(centre-ringno, y);
  149.     for(i=0; i<ringno; ++i)
  150.         outc(ch);
  151.     curse(centre+1, y);
  152.     for(i=0; i<ringno; ++i)
  153.         outc(ch);
  154. }
  155.  
  156. /* move a given ring from post 'from' to post 'to' */
  157. movering(ringno, from, to)
  158. int    ringno, from, to;
  159. {
  160.     int    fromc, toc,
  161.         fromy, toy;
  162.  
  163.     fromc = LEFT_POST + from * RING_WIDTH;
  164.     toc = LEFT_POST + to * RING_WIDTH;
  165.     fromy = ++top[from];
  166.     toy = top[to]--;
  167.  
  168.     while (fromy != MOVING_ROW) {
  169.     /* lift the ring up off the post: */
  170.         draw(ringno, fromc, fromy, ' ');
  171.         draw(ringno, fromc, --fromy, RING);
  172.     }
  173.  
  174.     /*
  175.      *    move the ring over the desired post as follows:
  176.      *        xxx xxx
  177.      *         xx xxx
  178.      *         xxxxxx
  179.      *         xxx xx
  180.      *         xxx xxx
  181.      */
  182.     if (fromc < toc)
  183.         while (fromc != toc) {
  184.             cput(fromc-ringno, fromy, ' ');
  185.             cput(fromc, fromy, RING);
  186.             cput(fromc+1, fromy, ' ');
  187.             cput(fromc+ringno+1, fromy, RING);
  188.             ++fromc;
  189.         }
  190.     else if (fromc > toc)
  191.         while (fromc != toc) {
  192.             cput(fromc+ringno, fromy, ' ');
  193.             cput(fromc, fromy, RING);
  194.             cput(fromc-1, fromy, ' ');
  195.             cput(fromc-ringno-1, fromy, RING);
  196.             --fromc;
  197.         }
  198.  
  199.     while (fromy != toy) {
  200.     /* now lower the ring onto the new post: */
  201.         draw(ringno, fromc, fromy, ' ');
  202.         draw(ringno, fromc, ++fromy, RING);
  203.     }
  204. }
  205.  
  206.  
  207. /* do nothing for a while */
  208. wait()
  209. {
  210.     int i;
  211.     i = 1 << pause;
  212.     while (i)
  213.         i--;
  214. }
  215.