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