对“推箱子”小游戏代码的改进

一.代码来源
https://www.cnblogs.com/heyu123/p/14844284.html

二.运行环境
DEV--C++

三.原代码及其运行结果
原代码:

int map[8][8]={
    {1,1,1,1,1,1,1,1},//0 空地 
    {1,0,0,0,1,0,0,1},//1 墙 
    {1,0,1,0,1,4,3,1},//3 目的地 
    {1,0,0,0,0,4,3,1},//4 箱子 
    {1,0,1,0,1,4,3,1},//5 人 
    {1,0,0,0,1,0,0,1},//7 箱子和目的地重合 
    {1,1,1,1,1,5,0,1},//8 人和目的地 
    {0,0,0,0,1,1,1,1}};

void GamePaint()
{
    //输出
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            switch(map[i][j])
            {
                case 0:printf("  ");break;
                case 1:printf("■");break;
                case 3:printf("☆");break;
                case 4:printf("□");break;
                case 5:printf("♀");break;
                case 7:printf("★");break;
                case 8:printf("♀");break;
            } 
        }
        cout<<endl; 
    } 
}


void GamePlay()
{
    int r,c;//人的下标
    int flag=0;
    for(r=0;r<8;r++)
     {
         for(c=0;c<8;c++)
        {if(map[r][c]==5||map[r][c]==8)
            {
             flag=1;
              break;
            }
        }
     if(flag)
     break;
     }
     cout<<"人的下标:"<<r<<" "<<c;
     char key;
     key=getch();
     switch(key)
     {
         case 'w': 
         if(map[r-1][c]==0||map[r-1][c]==3)//人的前面是空地或目的地 
         { map[r-1][c]+=5; //人来+5
           map[r][c]-=5;//人走-5 
            }  
        else if(map[r-1][c]==4||map[r-1][c]==7)//人前面是箱子或箱子加目的地
        {
              if(map[r-2][c]==0||map[r-2][c]==3)//人前面的前面是空地或目的地 
              {
                  map[r-2][c]+=4;
                  map[r-1][c]+=1;
                  map[r][c]-=5;
              } 
        }         
            
             break;
         case 's':
             if(map[r+1][c]==0||map[r+1][c]==3)//人的后面是空地或目的地 
         { map[r+1][c]+=5; //人来+5
           map[r][c]-=5;//人走-5 
            }  
        else if(map[r+1][c]==4||map[r+1][c]==7)//人后面是箱子或箱子加目的地
        {
              if(map[r+2][c]==0||map[r+2][c]==3)//人后面的前面是空地或目的地 
              {
                  map[r+2][c]+=4;
                  map[r+1][c]+=1;
                  map[r][c]-=5;
              } 
        }         
              break;
         case 'a':
             if(map[r][c-1]==0||map[r][c-1]==3)//人的左面是空地或目的地 
         { map[r][c-1]+=5; //人来+5
           map[r][c]-=5;//人走-5 
            }  
        else if(map[r][c-1]==4||map[r][c-1]==7)//人左面是箱子或箱子加目的地
        {
              if(map[r][c-2]==0||map[r][c-2]==3)//人左面的左面是空地或目的地 
              {
                  map[r][c-2]+=4;
                  map[r][c-1]+=1;
                  map[r][c]-=5;
              } 
        } 
          break;
          
         case 'd': 
             if(map[r][c+1]==0||map[r][c+1]==3)//人的右面是空地或目的地 
         { map[r][c+1]+=5; //人来+5
           map[r][c]-=5;//人走-5 
            }  
        else if(map[r][c+1]==4||map[r][c+1]==7)//人右面是箱子或箱子加目的地
        {
              if(map[r][c+2]==0||map[r][c+2]==3)//人右面的右面是空地或目的地 
              {
                  map[r][c+2]+=4;
                  map[r][c+1]+=1;
                  map[r][c]-=5;
              } 
        }      
         break;
     }
}


int main()
{   while(1)//让下面语句不断运行
    {system("cls");//清屏函数
    GamePaint();
    GamePlay();
    }
    return 0;
}

运行结果:

四.原代码问题以及改进方案
问题:
1.从原代码和运行结果可以明显看出这个小游戏没有‘开始界面’和完成游戏后的‘结束界面’,导致使用体验不佳。
2.在不同的电脑上运行该程序,会发现输出特殊字符时会发生错位现象,这就导致用户体验极差。
3.在原代码里,为了保证游戏页面干净,在主函数内写上'while(1)',这样就导致游戏无法正常结束。
错位现象:

解决方案:
1.我在原代码的基础上,为其添加上‘开始界面’和‘胜利界面’的代码。在开始界面,按‘a’进入游戏。在胜利结算界面,按‘a’退出游戏。
2.经过一番尝试,我还是放弃了用特殊符号来表示各个元素的想法,改用汉字。
3.我设置了一个全局变量int flag=0;顶替原来的'1',用来判断游戏是否正在进行。当falg=0时就是游戏结束,flag=1就是游戏仍在进行。
“开始界面”代码:

void Start(){
	printf("============================\n");
    printf("==                        ==\n");
    printf("==        欢迎来到        ==\n");
    printf("==       推箱子游戏       ==\n");
    printf("==     !!!!!!!     ==\n");
    printf("==     (按'a'进入游戏)    ==\n");
    printf("==                        ==\n");
    printf("============================\n");
    char key;
	key=getch();
    if(key=='a'){
     	flag=1;
	}
}

“胜利结算界面”代码:

void GameJudge()
{
	int z=0;
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            if(map[i][j]==7) z++;
        }
    }
    if(z==3){
    	system("cls");
    	printf("============================\n");
    	printf("==                        ==\n");
    	printf("==        恭喜通关        ==\n");
    	printf("==      !!!!!!!    ==\n");
    	printf("==                        ==\n");
    	printf("==     (按'a'退出游戏)    ==\n");
    	printf("==                        ==\n");
    	printf("============================\n");
    	char key;
     	key=getch();
     	if(key=='a'){
     		flag=0;
		 }
	}
}

修改后的各元素的表示的代码:

void GamePaint()
{
    //输出
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            switch(map[i][j])
            {
                case 0:printf("  ");break;
                case 1:printf("墙");break;
                case 3:printf("洞");break;
                case 4:printf("箱");break;
                case 5:printf("人");break;
                case 7:printf("星");break;
                case 8:printf("人");break;
            } 
        }
        cout<<endl; 
    } 
}

五.修改后的运行结果

开始界面

游戏内初始画面

游戏进行时画面

胜利结算界面

六.实验总结与体会
经过这次实验,我认识到逆向软件工程是一件麻烦的事情,尤其是在原代码缺少注释、变量名起的随心所欲、有大量无意义的变量时,代码的可读性大幅度下降,导致我对一些有趣的项目丧失了想法,完全不想去读那些难以明辨的代码。在修改推箱子小游戏的代码时,我发现作为一个益智小游戏缺少一个重要的功能——悔棋,但是很遗憾,我才疏学浅,无法再短时间内完成。我想这个项目肯定还能进步,我会在之后不久将其完善。

posted @ 2025-02-27 19:19  李昊韩  阅读(86)  评论(0)    收藏  举报