前面已经做了设计汉诺塔的一些工作,接下来我们该如何相对完整的实现汉诺塔的问题了,从开始的设计汉诺塔图形(呵呵没有颜色不算图形吧),之后了解汉诺塔的递归过程,现在就是如何把设计图形和递归的过程结合在一起呢?我做了也就120多行的代码,简简单单把汉诺塔游戏的演示过程设计出来了,其中这思想来源于书本,可是书本上太多错误了源代码也无法运行,有些还看不懂,只能根据它的设计思想,然后到网上查找汉诺塔的过程,才有了进一步的了解,其中也有很多不理想的地方,正在学习如何修改,进一步的设计美好的图形界面,由于本人水平有限呵呵,只能这样了。这里说一下,那程序的缺点,汉诺塔盘子的层数不得超过9层,每一次重新打印图形的时候会闪屏,还有很............,本程序只提供学习思想,并无其他,如有建议请尽量提出,本人感激不尽!!(ps:可能有些地方会解释的不清楚)
#include <stdio.h>
#include <conio.h> //运用到了getch()函数
#include <stdlib.h> //运用到了清屏函数
#define N 10 //数组的行
#define M 19 //数组的列
char a[N][M], b[N][M], c[N][M];
int count; //用来记录汉诺塔操作的次数
void HanMove(char x[N][M], char y[N][M]);
void InitHanoi(int n) //初始化图形
{
for(int i=0; i<10; i++) //控制行
{
for(int j=0; j<19; j++)//控制列
{
if(j==9) //每个汉诺塔的第9列都以|为柱子
{
a[i][j] = '|';
b[i][j] = '|';
c[i][j] = '|';
}
else
{
if(i>=N-n) //输出n层汉诺塔的盘子
{
int k=i+n-10+1; //随着i(行)的增加,打印*的左右范围扩大
if(j>=9-k&&j<=9+k)
{
a[i][j] = '*';
}
else //在盘子部分也有打印空字符的部分
{
a[i][j] = ' ';
}
}
else //上面已经打印空了但严格来讲i<N-n那部分也要打印空字符
{
a[i][j] = ' ';
}
b[i][j] = ' '; //两个汉诺塔除了打印柱子,还需要打印空字符
c[i][j] = ' ';
}
}
}
}
void DrawHanoi() //打印汉诺塔
{ int i, j;
getch(); //停顿,不然会一直循环到结束,这样有利于观察汉诺塔的演示
system("CLS"); //清屏,很大缺点是会闪屏
printf(" 汉诺塔游戏\n\n");
for(i=0; i<N; i++)
{
for(j=0; j<M; j++) //打印第一个汉诺塔初始化图形
{
printf("%c",a[i][j]);
}
for(j=0; j<M; j++) //打印第二个汉诺塔初始化图形
{
printf("%c",b[i][j]);
}
for(j=0; j<M; j++) //打印第三个个汉诺塔初始化图形
{
printf("%c",c[i][j]);
}
printf("\n"); //打印完一行换行
}
printf("---------------------------------------------------------------\n");
}
void Hanoi(int num, char one[N][M], char two[N][M], char three[N][M])
{
if(num==1)HanMove(one,three); //这里就不介绍了
else
{
Hanoi(num-1,one,three,two);
HanMove(one,three);
Hanoi(num-1,two,one,three);
}
}
void HanMove(char x[N][M], char y[N][M])
{
int i, j;
int first = 0, second = 0; //first记录被移动汉诺塔是否已经找到有*的那一层
count++; //secod记录移动到的汉诺塔是否已经找到有空字符的那一层
for(i=0; i<10; i++) //搜索要移动的盘子的汉诺塔的最顶层
{
if(x[i][8]=='*')
{
first = i;
break;
}
}
for(i=9; i>=0; i--) //搜索被移动到的汉诺塔有*的上一层,没有*就最底层
{
if(y[i][8]==' ')
{
second = i;
break;
}
}
for(j=0; j<M; j++)
{
y[second][j] = x[first][j]; //搜索到了两个汉诺塔的两层,移动
if(9==j)
x[first][j] = '|'; //被移动完后的那一层要重新初始化
else
x[first][j] = ' ';
}
DrawHanoi(); //移动完后要重新打印图形
}
int main()
{ int n; //汉诺塔的层数
printf("请输入汉诺塔的层数:");
scanf("%d",&n);//(汉诺塔层数要小于10大于0)
InitHanoi(n); //初始化汉诺塔的数组
printf("请输入任意键继续\n");
DrawHanoi(); //打印汉诺塔
Hanoi(n, a, b, c); //
printf("总共进行了%d操作\n",count);
printf("汉诺塔演示结束\n");
getch();
return 0;
}