项目名称:推箱子
本项目结合了分支,循环,数组的结合,并且对逻辑也是有一定的要求。
1.头文件及数组的确定
我们做的是一个7*8的地图,所以我们也需要用到一个二维数
#include<stdio.h>
#include<stdlib.h>
#include"get_keyboard.h" //键位函数
#include<stdbool.h> //用于后边的判断游戏胜利
int map[7][8]= //定义一张全局地图
{0,1,1,1,1,1,1,0,
0,1,0,0,0,0,1,1,
1,3,0,1,1,2,0,1,
1,0,3,3,2,0,0,1,
1,0,0,1,2,0,0,1,
1,0,0,4,0,1,1,1,
1,1,1,1,1,0,0,0};
int x = 0;int y = 0;//记录人的位置
int cntOfBox = 0;//计算箱子的个数
在这个地图里面,0代表空地,1代表墙,2代表箱子,3代表目的地,4代表小人。
2.画图
我们要将地图输出来,这个时候我们要把‘#’作为墙,‘@’作为箱子,‘$’作为小人来绘制这张字符地图。
void show(int m[][8],size_t len){//生成游戏的地图
system("clear");
for(int i=0;i<len;i++){
printf("\t");
for(int j=0;j<8;j++){
switch(m[i][j]){
case 0:printf(" ");break;
case 1:printf("#");break;
case 2:printf("@");break;
case 3:printf("D");break;
case 4:printf("$");break;
case 5:printf("@");break;//记录箱子在目的地的位置
case 6:printf("$");break;//记录人站在目的地的位置
}
}
printf("\n");
}
}
这个时候我们多了两个数字,5和6分别来记录两个特殊的情况,以便于后边键位的分析。
3.进入游戏,找到小人的位置,并且找到箱子的个数
我们要把我们的我们的初始地图复制给一个通用地图m[ ][ ],然后再确定小人的位置和箱子的个数。
oid init(int m[][8],size_t len){//游戏开始,找到小人的位置
for(int i=0;i<len;i++){
for(int j = 0;j<8;j++){
m[i][j] = map[i][j];
if(m[i][j]==4){
x = i;
y = j;
}
if(m[i][j]==2){
cntOfBox++;
}
}
}
}
在上面的全局变量中,我们初始化了小人的位置,x 和 y,这个时候我们将它赋值到小人身上。
4.键位设置。
这个是最难的部分,也是逻辑思维最强的部分,我把所有的情况都写在了注释里。
void move(int m[][8],size_t len,int n_x,int n_y,int m_x,int m_y){ //新变量是箱子的下下个位置m_x,m_y
switch(m[n_x][n_y]){
case 1:return;//遇到墙,直接退出
case 2://遇到箱子时
switch(m[m_x][m_y]){//这个时候考虑箱子后边的位置,有很多种情况
case 0://箱子后边是空地时
if(m[x][y]==4){//当前位置
m[m_x][m_y]=2;
m[n_x][n_y]=4;
m[x][y]=0;
}
if(m[x][y]==6){ //当前位置是人站在目的地上(前面定义过)
m[m_x][m_y]=2;
m[n_x][n_y]=4;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
case 3://箱子后边是目的地时
if(m[x][y]==4){
m[m_x][m_y]=5;
m[n_x][n_y]=4;
m[x][y]=0;
}
if(m[x][y]==6){
m[m_x][m_y]=5;
m[n_x][n_y]=4;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
case 5://箱子后边是箱子在目的地上时
case 2://箱子后边是箱子在空地上时
case 1://箱子后边是墙时
return;//箱子都不会动
break;
}
break;
case 3://遇到目的地时
if(m[x][y]==4){
m[n_x][n_y]=6;
m[x][y]=0;
}
if(m[x][y]==6){
m[n_x][n_y]=6;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
case 5://遇到箱子在目的地上时,下列情况和case2是差不多的
switch(m[m_x][m_y]){
case 0:
if(m[x][y]==4){
m[m_x][m_y]=2;
m[n_x][n_y]=6;
m[x][y]=0;
}
if(m[x][y]==6){
m[m_x][m_y]=2;
m[n_x][n_y]=6;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
case 3:
if(m[x][y]==4){
m[m_x][m_y]=5;
m[n_x][n_y]=6;
m[x][y]=0;
}
if(m[x][y]==6){
m[m_x][m_y]=5;
m[n_x][n_y]=6;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
case 5:
case 2:
case 1:return;
}
break;
case 0://遇到空地时
if(m[x][y]==4){
m[n_x][n_y]=4;
m[x][y]=0;
}
if(m[x][y]==6){
m[n_x][n_y]=4;
m[x][y]=3;
}
x = n_x;
y = n_y;
break;
}
}
在这个代码段中,是可以缩写的,但是我为了逻辑清楚,所有全部写了出来,存在的就是人在前进时,数字的变化,这样达到移动的效果,关于数字的定义,前面定义的很清楚。
5.判断游戏的输赢
判断游戏的输赢,我们定义了一个变量,就是当一个箱子在目的地上时,我们就定义一个变量cnt++,这样我们就能知道几个箱子到达了目的地,如果这个数字等于箱子的个数,就说明游戏胜利了,就可以用bool函数来判断。
bool isWin(int m[][8],size_t len){
int cnt = 0;//定义的是一个箱子在一个目的地上,如果++就说明两个箱子在两个目的地上
for(int i=0;i<len;i++){
for(int j=0;j<8;j++){
if(m[i][j]==5){//如果箱子在目的地上
cnt++;
}
}
}
if(cnt == cntOfBox){//如果箱子在目的地上的个数等于箱子的个数时,游戏胜利
return true;
}else{
return false;
}
}
这个游戏的判定是最简单的,运用了bool函数。
6.游戏的运行
在这个游戏的运行中,我们需要调用几个前面定义过的函数。
void run(int m[][8],size_t len){
while(true){
show(map,len);//绘制地图
if(isWin(map,len)){//判断游戏胜利
printf("厉害的亲!\n");
}
switch(get_keyboard()){//运用头文件中的get_keyboard来调用上下左右键
case KEY_UP:
move(map,len,x-1,y,x-2,y);break;//键位函数上,只有x发生变化
case KEY_DOWN:
move(map,len,x+1,y,x+2,y);break;//键位函数下,只有x发生变化
case KEY_LEFT:
move(map,len,x,y-1,x,y-2);break;//键位函数左,只有y发生变化
case KEY_RIGHT:
move(map,len,x,y+1,x,y+2);break;//键位函数右,只有y发生变化
case KEY_Q:
printf("sorry!\n");//放弃游戏
return;
case KEY_ENTER://重新开始,重新生成地图进入游戏
init(map,7);
break;
}
}
}
我们调用了前几个函数,来进行游戏的运行。
7.主程序,主函数!
因为前面进行了函数的定义,所以我们现在只需要用就行了!
int main(){
int map[7][8]={};//定义地图
init(map,7);//进入游戏
run(map,7);//运行游戏
return 0;
}
在这个项目中,我知道了其实创作编程是一个程序员必不可少的本领,我也会努力的去总结一开始的失败和经验,在下一个项目中克服这样的困难!