对“推箱子”小游戏代码的改进
一.代码来源
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;
}
}
五.修改后的运行结果
开始界面

游戏内初始画面

游戏进行时画面

胜利结算界面

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

浙公网安备 33010602011771号