#include<stdio.h>
#include<conio.h>
#include<windows.h>
//原始的图表,五行六列,其中 0 代表着空白的地方; 1 代表着墙;2 代表着人;
//3 代表着箱子;4 代表着箱子的终点位置。
//图的变化要靠自己来编写数组,通过数字来进行图的构造。
void drawmain(int map[9][11]);
void tuidong(int map[9][11]);
int winshu(int map[9][11]);
int guan=0;
int bushu=0;
int map[9][11];
int map0[9][11]={
{0,0,0,0,1,1,1,0,0,0,0},
{0,0,0,0,1,4,1,0,0,0,0},
{0,0,0,0,1,0,1,0,0,0,0},
{1,1,1,1,1,3,1,1,1,1,1},
{1,4,0,0,3,2,3,0,0,4,1},
{1,1,1,1,1,3,1,1,1,1,1},
{0,0,0,0,1,0,1,0,0,0,0},
{0,0,0,0,1,4,1,0,0,0,0},
{0,0,0,0,1,1,1,0,0,0,0}
};
int map1[9][11]={
{1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,4,1},
{1,0,0,0,3,0,0,0,3,0,1},
{1,0,0,3,2,3,0,3,0,0,1},
{1,0,0,0,3,0,0,0,3,0,1},
{1,0,0,0,0,0,0,0,0,0,1},
{1,0,4,4,0,4,0,0,0,0,1},
{1,0,4,4,0,4,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1}
};
int map2[9][11]={
{1,1,1,1,1,1,1,1,1,1,1},
{1,4,0,0,0,0,1,0,0,4,1},
{1,1,1,0,3,0,0,0,0,0,1},
{0,0,1,0,0,3,0,3,0,0,1},
{1,1,1,0,3,2,3,0,0,0,1},
{1,4,0,0,0,1,1,0,3,0,1},
{1,0,4,0,0,0,0,0,0,0,1},
{1,0,0,4,1,1,4,0,0,1,1},
{1,1,1,1,1,1,1,1,1,1,1}
};
下面是主函数
int main()//主函数
{
int i,j;
int v=0;
if(guan==0){
for(i=0;i<9;i++){
for(j=0;j<11;j++)
{ map[i][j]=map0[i][j];
}
}
}
while(1)
{
system("cls");//c语言清屏
printf("<推箱子>\n符号说明:空白代表空地,■代表墙,♀代表人,∷代表箱子,\n");
printf("×代表终点,♂代表人站在终点上 ,※代表箱子已推进终点\n");
printf("玩法:使用上下左右或wsad进行控制,规定步数内将箱子完成三关即为通过\n");
v=winshu(map); //调用输赢的函数 !
if (v==-1||v==2){
return 0;
}
drawmain(map);//画图
tuidong(map);//移动
bushu=bushu+1;
}
return 0;
}
下面是绘图函数
//把图形刻画出来
void drawmain(int map[9][11])
{
int i,j;
printf("\n");
for(i=0;i<9;i++)
{
for(j=0;j<11;j++)
{
switch(map[i][j])
{
case 0:
printf(" "); //空白的地方
break;
case 1:
printf("■"); //墙
break;
case 2:
printf("♀"); //人
break;
case 3:
printf("∷"); //箱子
break;
case 4:
printf("×"); //终点地方
break;
case 6:
printf("♂");//人加终点位置
break;
case 7:
printf("※") ;//箱子加终点位置
break;
}
}
printf("\n");
}
printf("您已经走了%d步了,在200步内完成所有关卡即为通关",bushu/2);
}
下面是移动函数
void tuidong(int map[9][11])
{
int count,caw=0;//行和列
int i,j;
char tui;
for(i=0;i<9;i++){
for (j=0;j<11;j++)
{
if(map[i][j]==2||map[i][j]==6) //2为人,6为人加终点位置
{
count=i;//行号与列号
caw=j;
}
}
}
tui=getch();//不回显函数;与getchar()有区别的是:getchar()输入一个字符后需要回车来进行下一个字符的输入,
//比较麻烦 ,getch()则不需要回车就能连续输入多个字符。
switch(tui)
{//上
case 'w':
case 72:
//map[i][j]==2||map[i][j]==6初始
if(map[count-1][caw]==0||map[count-1][caw]==4) // 人的前面是空地|| 人的前面是终点位置
{
map[count][caw]-=2;//原来人在的位置变空地 2-2=0即变为空地
map[count-1][caw]+=2;//原来人上面的位置变成人标 或人+终点标
}
else if(map[count-1][caw]==3||map[count-1][caw]==7)//人前是箱子||人前面是箱子+终点
{
if(map[count-2][caw]==0||map[count-2][caw]==4)//箱子||箱子+终点 再前面是 空地||终点
{
map[count][caw]-=2;//原来人在的位置变空地
map[count-1][caw]-=1;//人前面的箱子变成人 ||箱子+终点变成人+终点
map[count-2][caw]+=3;//再前面变箱子||箱子+终点
}
}
break;
//下
case 's':
case 80://键值
if(map[count+1][caw]==0||map[count+1][caw]==4)//下边是空地||下边是终点
{
map[count][caw]-=2;
map[count+1][caw]+=2;
}
else if(map[count+2][caw]==0||map[count+2][caw]==4)//下边的左边是空地||终点
{
if(map[count+1][caw]==3||map[count+1][caw]==7) //下边是 箱子||箱子加终点
{
map[count][caw]-=2;
map[count+1][caw]-=1;
map[count+2][caw]+=3;
}
}
break;
//左
case 'a':
case 75:
if(map[count][caw-1]==0||map[count][caw-1]==4)
{
map[count][caw]-=2;
map[count][caw-1]+=2;
}
else if(map[count][caw-2]==0||map[count][caw-2]==4)
{
if(map[count][caw-1]==3||map[count][caw-1]==7)
{
map[count][caw]-=2;
map[count][caw-1]-=1;
map[count][caw-2]+=3;
}
}
break;
//右
case 'd':
case 77:
if(map[count][caw+1]==0||map[count][caw+1]==4)
{
map[count][caw]-=2;
map[count][caw+1]+=2;
}
else if(map[count][caw+2]==0||map[count][caw+2]==4)
{
if(map[count][caw+1]==3||map[count][caw+1]==7)
{
map[count][caw]-=2;
map[count][caw+1]-=1;
map[count][caw+2]+=3;
}
}
break;
}
}
下面是判断输赢函数
int winshu(int map[9][11]) //校验输赢
{
int k = 0;//初始化
int j,i;
int v=0;
for(i=0;i<9;i++)//遍历数组看有没有没到和终点的箱子,如果有就++
{
for (j=0;j<11;j++)
{
if(map[i][j]==3)
k++;
}
}
if(bushu>400){
system("cls");//c语言清屏
printf("\n\n!!!GAME OVER!!!\n");
printf("按任意键退出窗口") ;
v=-1;
}
if(k==0&&guan==0){
printf("恭喜你成功进入第二关!");
guan++;
if(guan==1){
for(i=0;i<9;i++){
for(j=0;j<11;j++)
{ map[i][j]=map1[i][j];
}
}
}
}
else if(k==0&&guan==1){
printf("恭喜你成功进入第三关!");
guan++;
if(guan==2){
for(i=0;i<9;i++){
for(j=0;j<11;j++)
{ map[i][j]=map2[i][j];
}
}
}
}
else if(k==0&&guan==2){
system("cls");//c语言清屏
printf("\n\n!!!!!恭喜你通关!!!!\n\n");
printf("按任意键退出窗口") ;
v=2;
}
return v;
}
结束
最后记录自己的疑问:在我的想法中:主函数里人物每移动一下,也就是操作者每按下一次键盘,使得步数+1。可是在实际调试中,每按一下键,步数其实+2。也就是说,这个代码中,如果用户按键一下,bushu变量实际上变成了2。
为了掩盖这个错误,我把通关判断中的bushu变量的最大值设置为400(也就是用户按键200下),提示窗口中显示已走步数为 bushu / 2,这么样程序运行下来和预想的就一样了。
可是我始终想不明白为什么,此程序按键一下但步数却+2的原因。于是记录在此,希望以后得以解决。