疑问记录-三个关卡的推箱子小游戏代码(c语言)

#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的原因。于是记录在此,希望以后得以解决。

 

 

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值