相信大家在学习C语言嵌套的时候已经学习过经典问题汉诺塔了,我学习时就想能不能搞个汉诺塔的游戏出来,结果睡了一觉就给忘了。今天突然想起,搞出来与大家分享,水平一般,但符合汉诺塔规则。最终代码我放在文章最后,希望能对大家的学习有一些帮助。
做出来是长这样的:
重要函数
除了stdio.h中的函数以外,我们还需要用到一些其它的库函数增加游戏体验。
#include<conio.h> getch()
直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回。
#include<windows.h> system("cls")
清屏函数
打印界面
最简单的一步,printf,不需要多赘述,打印完后清屏,输出操作方法与玩法.
printf(" ########################################\n");
printf(" ########################################\n");
printf(" ##### 汉诺塔 #####\n");
printf(" ########################################\n");
printf(" ########################################\n");
printf(" #### 按任意键开始 ####################\n");
printf(" ########################################\n");
printf(" ########################################\n");
getch();
system("cls");
//输出操作方法
printf(" 游戏玩法\n");
printf(" 1.首先靠按键 A D 移动选择初始汉诺塔层数,回车确认\n");
printf(" 2.使用数字键对塔上圆盘进行移动,例如连续输入 1 3 即表示将第1根柱子最上面的圆盘移动到第三根上\n");
printf(" 3.无法移动处于第一个以下的圆盘,大的圆盘不能在小的上面\n");
printf(" 若知晓,按任意键即可开始游戏\n");
getch();
system("cls");
添加必要参数
int i,ceng = 1; /* i负责控制循环,ceng用来记录选择的层数*/
char c; /*得到从键盘输入的值*/
int wei1,wei2,bushu = 0; /*记录输入的第一根柱子,第二根柱子,已经走过的步数*/
int li[4]; /*立柱1 2 3 上的圆盘的个数*/
int zhu[4][6] = {0}; /*记录每个柱上每层圆盘的大小*/
li[2] = li[3] = 0;
选择难度,汉诺塔层数 (目前仅供选择 1 3 5 )
在得到每个合法输入之后进行对变量值的调整,清屏后重新输入。
while(1)
{printf(" ***********************\n");
printf(" **** 选择层数 ****\n");
printf(" ***********************\n");
printf("\n ");
if(ceng == 1)
printf("||1层|| ");
else
printf(" 1层 ");
if(ceng == 3)
printf("||3层|| ");
else
printf(" 3层 ");
if(ceng == 5)
printf("||5层|| ");
else
printf(" 5层 ");
c = getch();
if(c == 'd'||c == 'D')
{if( ceng == 5 )
ceng = 1;
else if( ceng == 3 )
ceng = 5;
else
ceng = 3;
}
if( c == 'a' || c == 'a' )
{if( ceng == 1 )
ceng = 5;
else if( ceng == 5 )
ceng = 3;
else
ceng = 1;
}
system("cls");
if( c == 13 )
break;
}
初始画面打印 (这里以横坐标7 9 31 为立柱的位置)
int hang,lie;
li[1] = ceng ;
for(i = 0;i < ceng; i++)
zhu[1][i] = ceng - i;
for( hang = 4 ;hang >= 0 ; hang-- )
{if( hang != 4 )
printf("\n");
for( lie = 0 ;lie <= 40 ;lie++ )
{if( lie == 7 || lie == 19 || lie == 31 )
printf("|");
else if( hang < li[1] && abs( lie - 7 ) <= zhu[1][hang] )
printf("*");
else
printf(" ");
}
}
printf("\n");
for(lie=0;lie<=40;lie++)
printf("-");
printf("\n");
printf("%d %d %d\n",li[1],li[2],li[3]);
printf("%d %d %d\n",zhu[1][ li[1] - 1 ],zhu[2][ li[2] - 1 ],zhu[3][ li[3] - 1 ]);
汉诺塔移动(游戏核心)
while(1)
{if( li[3] == ceng )
break;
wei1 = getch() - '0';
printf("输入柱1:%d号柱子\n",wei1);
wei2 = getch() - '0';
printf("输入柱2:%d号柱子\n",wei2);
Sleep(800);
if( 0 < wei1 && wei1 < 4 && 0 < wei2 && wei2 < 4 )
{if( ( zhu[wei1][ li[wei1] - 1 ] < zhu[wei2][ li[wei2] - 1 ] || zhu[wei2][ li[wei2] - 1 ] == 0 ) && zhu[wei1][ li[wei1] - 1 ] !=0 )
{int t; /*数据转换*/
t = zhu[wei1][ li[wei1] - 1 ];
zhu[wei1][ li[wei1] - 1 ] = 0;
zhu[wei2][ li[wei2] ] = t;
li[wei1]--;
li[wei2]++;
system("cls");
for( hang = 4 ;hang >= 0 ; hang-- )
{if( hang != 4 )
printf("\n");
for( lie = 0 ;lie <= 40 ;lie++ )
{if( lie == 7 || lie == 19 || lie == 31 )
printf("|");
else if( hang < li[1] && abs( lie - 7 ) <= zhu[1][hang] )
printf("*");
else if( hang < li[2] && abs( lie - 19 ) <= zhu[2][hang] )
printf("*");
else if( hang < li[3] && abs( lie - 31 ) <= zhu[3][hang] )
printf("*");
else
printf(" ");
}
}
printf("\n");
for(lie=0;lie<=40;lie++)
printf("-");
printf("\n");
bushu++;
printf("%d %d %d\n",li[1],li[2],li[3]);
printf("%d %d %d 总步数:%d\n",zhu[1][ li[1] - 1 ],zhu[2][ li[2] - 1 ],zhu[3][ li[3] - 1 ],bushu);
}
else if( wei1 == wei2 )
printf("违法操作:如果我没有看错,这是同一根柱子,对吧。\n");
else if( zhu[wei1][ li[wei1] - 1 ] > zhu[wei2][ li[wei2] - 1 ] )
printf("违法操作:大的圆盘将压到小的圆盘\n");
else if( zhu[wei1][ li[wei1] - 1 ] ==0 )
printf("违法操作:难道要我把空气移动上去?或许其他的游戏可以吧\n");
}
else
printf("违法操作:我们可不存在这样的柱子\n");
}
printf("你赢了\n");
善后处理
游戏本身不存在输的结果,在跳出循环之后,即可恭喜玩家获得胜利。再结合goto使游戏就可以循环着玩了。如果说如何退出,emmm,右上角的叉叉值得托付。
游戏的最终代码
#include<stdio.h>
#include<conio.h>
#include<windows.h>
int main(){
int i,ceng = 1;
char c;
int wei1,wei2,bushu = 0;
/*立柱位置7 19 31 */
int li[4];
int zhu[4][6] = {0};
li[2] = li[3] = 0;
/*打印界面*/
KAIDUAN:
system("cls");
printf(" ########################################\n");
printf(" ########################################\n");
printf(" ##### 汉诺塔 #####\n");
printf(" ########################################\n");
printf(" ########################################\n");
printf(" #### 按任意键开始 ####################\n");
printf(" ########################################\n");
printf(" ########################################\n");
getch();
system("cls");
//输出操作方法
printf(" 游戏玩法\n");
printf(" 1.首先靠按键 A D 移动选择初始汉诺塔层数,回车确认\n");
printf(" 2.使用数字键对塔上圆盘进行移动,例如连续输入 1 3 即表示将第1根柱子最上面的圆盘移动到第三根上\n");
printf(" 3.无法移动处于第一个以下的圆盘,大的圆盘不能在小的上面\n");
printf(" 若知晓,按任意键即可开始游戏\n");
getch();
system("cls");
/*选择难度,汉诺塔层数*/
while(1)
{printf(" ***********************\n");
printf(" **** 选择层数 ****\n");
printf(" ***********************\n");
printf("\n ");
if(ceng == 1)
printf("||1层|| ");
else
printf(" 1层 ");
if(ceng == 3)
printf("||3层|| ");
else
printf(" 3层 ");
if(ceng == 5)
printf("||5层|| ");
else
printf(" 5层 ");
c = getch();
if(c == 'd'||c == 'D')
{if( ceng == 5 )
ceng = 1;
else if( ceng == 3 )
ceng = 5;
else
ceng = 3;
}
if( c == 'a' || c == 'a' )
{if( ceng == 1 )
ceng = 5;
else if( ceng == 5 )
ceng = 3;
else
ceng = 1;
}
system("cls");
if( c == 13 )
break;
}
/*处理初始地图*/
int hang,lie;
li[1] = ceng ;
for(i = 0;i < ceng; i++)
zhu[1][i] = ceng - i;
for( hang = 4 ;hang >= 0 ; hang-- )
{if( hang != 4 )
printf("\n");
for( lie = 0 ;lie <= 40 ;lie++ )
{if( lie == 7 || lie == 19 || lie == 31 )
printf("|");
else if( hang < li[1] && abs( lie - 7 ) <= zhu[1][hang] )
printf("*");
else
printf(" ");
}
}
printf("\n");
for(lie=0;lie<=40;lie++)
printf("-");
printf("\n");
printf("%d %d %d\n",li[1],li[2],li[3]);
printf("%d %d %d\n",zhu[1][ li[1] - 1 ],zhu[2][ li[2] - 1 ],zhu[3][ li[3] - 1 ]);
/*汉诺塔移动*/
while(1)
{if( li[3] == ceng )
break;
wei1 = getch() - '0';
printf("输入柱1:%d号柱子\n",wei1);
wei2 = getch() - '0';
printf("输入柱2:%d号柱子\n",wei2);
Sleep(800);
if( 0 < wei1 && wei1 < 4 && 0 < wei2 && wei2 < 4 )
{if( ( zhu[wei1][ li[wei1] - 1 ] < zhu[wei2][ li[wei2] - 1 ] || zhu[wei2][ li[wei2] - 1 ] == 0 ) && zhu[wei1][ li[wei1] - 1 ] !=0 )
{int t; /*数据转换*/
t = zhu[wei1][ li[wei1] - 1 ];
zhu[wei1][ li[wei1] - 1 ] = 0;
zhu[wei2][ li[wei2] ] = t;
li[wei1]--;
li[wei2]++;
system("cls");
for( hang = 4 ;hang >= 0 ; hang-- )
{if( hang != 4 )
printf("\n");
for( lie = 0 ;lie <= 40 ;lie++ )
{if( lie == 7 || lie == 19 || lie == 31 )
printf("|");
else if( hang < li[1] && abs( lie - 7 ) <= zhu[1][hang] )
printf("*");
else if( hang < li[2] && abs( lie - 19 ) <= zhu[2][hang] )
printf("*");
else if( hang < li[3] && abs( lie - 31 ) <= zhu[3][hang] )
printf("*");
else
printf(" ");
}
}
printf("\n");
for(lie=0;lie<=40;lie++)
printf("-");
printf("\n");
bushu++;
printf("%d %d %d\n",li[1],li[2],li[3]);
printf("%d %d %d 总步数:%d\n",zhu[1][ li[1] - 1 ],zhu[2][ li[2] - 1 ],zhu[3][ li[3] - 1 ],bushu);
}
else if( wei1 == wei2 )
printf("违法操作:如果我没有看错,这是同一根柱子,对吧。\n");
else if( zhu[wei1][ li[wei1] - 1 ] > zhu[wei2][ li[wei2] - 1 ] )
printf("违法操作:大的圆盘将压到小的圆盘\n");
else if( zhu[wei1][ li[wei1] - 1 ] ==0 )
printf("违法操作:难道要我把空气移动上去?或许其他的游戏可以吧\n");
}
else
printf("违法操作:我们可不存在这样的柱子\n");
}
printf("你赢了\n");
/*重新开始*/
for( hang = 3 ;hang >= 0 ;hang--)
for( lie = 0 ;lie <= 5 ;lie++)
zhu[hang][lie] = 0;
bushu = li[3] = 0;
Sleep(800);
printf("按任意键重新开始\n");
getch();
goto KAIDUAN;
return 0;
}