Chinaunix首页 | 论坛 | 博客
  • 博客访问: 688423
  • 博文数量: 156
  • 博客积分: 3402
  • 博客等级: 中校
  • 技术积分: 1639
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-13 14:06
个人简介

业余编程爱好者

文章分类

全部博文(156)

文章存档

2014年(1)

2013年(13)

2012年(46)

2011年(38)

2010年(58)

分类: LINUX

2012-09-05 17:18:51

汉诺塔游戏已经基本完成了,新增加的功能有:完成一个级别后自动晋级至下一级别,选关模式,还有记录步数的功能。
操作方法:
‘a’ 左移
‘d’ 右移
‘s’ 拿起/放下
‘>’ 跳至下一关,直至第九关退出。

源代码下载地址:


源代码:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <assert.h>
  4. #include <termios.h>
  5. #include <unistd.h>
  6. #define TRUE    1
  7. #define FALSE    0


  8. /*
  9. ** 汉诺塔实现与操作
  10. **
  11. ** 使用堆栈来实现汉诺塔。
  12. ** 包括动态建立和销毁堆栈,打印堆栈内容,入栈和出栈操作。
  13. ** move_hanoi函数旨在实现安全的移塔操作,不会使堆栈溢出。
  14. */
  15. #define MAX_LEVEL 9
  16.  
  17. typedef struct HANOI {
  18.     int tower[MAX_LEVEL+1];
  19.     int length;
  20.     int *top;
  21. } Hanoi;



  22. Hanoi *init_hanoi(int max)
  23. {
  24.     int i;
  25.     int *temp;
  26.     Hanoi *new;

  27.     new = (Hanoi *)malloc(sizeof(Hanoi));
  28.     assert(new != NULL);
  29.     temp = new->tower;
  30.     for (i = max; i > 0; i--)
  31.         *(++temp) = i;
  32.     new->length = max;
  33.     new->top = temp;
  34.     
  35.     return new;
  36. }


  37. void printf_hanoi(Hanoi *p)
  38. {
  39.     int i;
  40.     int *temp;
  41.     
  42.     temp = p->tower;
  43.     for (i = p->length; i > 0; i--)
  44.         printf("%d ", *(++temp));
  45.     printf("\n");
  46. }


  47. void destroy_hanoi(Hanoi *p)
  48. {
  49.     free(p);
  50. }


  51. void push_hanoi(Hanoi *p, int num)
  52. {
  53.     (p->length)++;
  54.     (p->top)++;
  55.     *(p->top) = num;
  56. }


  57. int pop_hanoi(Hanoi *p)
  58. {
  59.     int num = *(p->top);

  60.     (p->top)--;
  61.     (p->length)--;

  62.     return num;
  63. }


  64. int move_hanoi(Hanoi *from, Hanoi *to)
  65. {
  66.     if ((from->length <= 0)
  67.         || (to->length >= MAX_LEVEL))
  68.         return FALSE;
  69.     else if ((to->top != to->tower)
  70.         && (*(to->top) < *(from->top)))
  71.         return FALSE;

  72.     push_hanoi(to, pop_hanoi(from));
  73.     return TRUE;
  74. }


  75. /*
  76. ** 游戏操作与实现
  77. **
  78. ** next_s
  79. ** 设定汉诺塔操作起始状态为0号塔。
  80. ** 接收当前操作的塔标号now、键盘接收的操作命令c。
  81. ** 使用数字标号标示汉诺塔,0号塔、1号塔和2号塔。
  82. ** 返回每一次移塔后所在的汉诺塔标号。
  83. */
  84. int next_s(int now, char c)
  85. {
  86.     int status [3][3] = {/* 'd' 'a' other */
  87.         /*tower 0*/    { 1, 2, 0 },    
  88.         /*tower 1*/    { 2, 0, 1 },    
  89.         /*tower 2*/    { 0, 1, 2 }
  90.     };
  91.     int i;

  92.     if (c == 'd')
  93.         i = 0;
  94.     else if (c == 'a')
  95.         i = 1;
  96.     else
  97.         i = 2;

  98.     return status[now][i];
  99. }


  100. /*
  101. ** display_game
  102. ** 接收三个汉诺塔结构体指针。
  103. ** 塔的高度l,抓起状态catch,当前操作位置now。
  104. ** 打印出游戏图形。
  105. */
  106. void display_game(Hanoi *x, Hanoi *y, Hanoi *z, int l, int catch, int now)
  107. {
  108.     int i, j;
  109.     char s;
  110.     char buffer[l][3];

  111.     for (i = 0; i < l; i++)
  112.         for (j = 0; j < 3; j++)
  113.             buffer[i][j] = ' ';
  114.     
  115.     for (i = l - x->length, j = x->length; i < l; i++, j--)
  116.         buffer[i][0] = *(x->tower + j) + '0';
  117.     for (i = l - y->length, j = y->length; i < l; i++, j--)
  118.         buffer[i][1] = *(y->tower + j) + '0';
  119.     for (i = l - z->length, j = z->length; i < l; i++, j--)
  120.         buffer[i][2] = *(z->tower + j) + '0';
  121.     
  122.     printf("\n\n\n\n\n\n\n\t\t\t");
  123.     s = (catch == 1) ? '!' : '*';
  124.     for (j = 0; j < now; j++)
  125.         printf("\t");
  126.     printf("%c\n",s);

  127.     for (i = 0; i < l; i++) {
  128.         printf("\t\t\t");
  129.         for (j = 0; j < 3; j++)
  130.             printf("%c\t",buffer[i][j]);
  131.         printf("\n");
  132.     }
  133.     printf("\t\t\tA\tB\tC\n\n\n\n\n\n\n");
  134. }


  135. /*
  136. ** my_getch
  137. ** 实现无回显的立即返回键盘输入的函数。
  138. */
  139. int my_getch(void)
  140. {
  141.     struct termios oldt,
  142.     newt;
  143.     int ch;
  144.     tcgetattr( STDIN_FILENO, &oldt );
  145.     newt = oldt;
  146.     newt.c_lflag &= ~( ICANON | ECHO );
  147.     tcsetattr( STDIN_FILENO, TCSANOW, &newt );
  148.     ch = getchar();
  149.     tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
  150.     return ch;
  151. }


  152. /*
  153. ** level_ok
  154. ** 接收终点2号塔结构体指针和目标高度。
  155. ** 返回当前级别是否已经完成的标志。
  156. **
  157. */
  158. int level_ok(Hanoi *z, int l)
  159. {
  160.     return (z->length == l) ? TRUE : FALSE;
  161. }


  162. /*
  163. ** 主控制结构,测试中。
  164. */
  165. int main()
  166. {
  167.     char c;
  168.     int level, steps, now, next;
  169.     int catch, moved;
  170.     Hanoi *hanoi[3];
  171.     
  172.     for (level = 3; level <= MAX_LEVEL; level++) {
  173.         
  174.         hanoi[0] = init_hanoi(level);
  175.         hanoi[1] = init_hanoi(0);
  176.         hanoi[2] = init_hanoi(0);

  177.         steps = 0;
  178.         now = 0;
  179.         catch = FALSE;

  180.         display_game(hanoi[0], hanoi[1], hanoi[2], level, catch, now);
  181.     
  182.         while ((c = my_getch()) != '>') {
  183.     
  184.             moved = FALSE;
  185.             catch = (c == 's') ? !catch : catch;
  186.             next = next_s(now, c);

  187.             if (catch == TRUE)
  188.                 moved = move_hanoi(hanoi[now], hanoi[next]);

  189.             if ((moved == TRUE) && (next != now))
  190.                 steps++;
  191.             
  192.             if (moved == FALSE)
  193.                 catch = FALSE;

  194.             now = next;

  195.             display_game(hanoi[0], hanoi[1], hanoi[2], level, catch, now);
  196.             printf("%d", steps);

  197.             if (level_ok(hanoi[2], level) == TRUE) {
  198.                 printf("\nGOOD GAME!Used %d steps.\n", steps);
  199.                 break;
  200.             }
  201.         }

  202.         destroy_hanoi(hanoi[0]);
  203.         destroy_hanoi(hanoi[1]);
  204.         destroy_hanoi(hanoi[2]);
  205.     
  206.     }

  207.     return 0;
  208. }

希望各位大牛们不要见笑,我是初学者。
阅读(1395) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~