C语言实现推箱子游戏完整代码,供大家参考,具体内容如下
前言
自己做的,可能有些代码不够工整,或者有些小问题,但游戏的基本操作是可以实现的
代码效果
代码一共分为8个部分,4个控制上下左右移动,2个判断输赢,1个统计归为的个数,一个作图。
手动设置地图
用'0'表示空格,“1”表示墙,“2”表示箱子,“3”表示人,“4”表示终点
这样可以提高代码的移植性
如需改为手动输入地图可以直接定义一个二维数组,在给他赋值就可以了
1
2
3
4
5
6
7
8
9
10
11
|
int screen[9][11]={
{0,1,1,1,1,1,1,1,1,0,0},
{0,1,0,0,0,1,0,0,0,1,0},
{0,1,0,2,2,2,2,2,0,1,0},
{0,1,0,2,0,2,0,2,0,1,1},
{0,1,0,0,0,3,0,0,2,0,1},
{1,1,0,1,1,1,1,0,2,0,1},
{1,0,4,4,4,4,4,1,0,0,1},
{1,0,4,4,4,4,4,0,0,1,1},
{1,1,1,1,1,1,1,1,1,1,0}
}; //定义为全局变量 (地图) i表示行,j表示列
|
计算地图中终点的个数
这一步主要是为了后面判断游戏输赢的
1
2
3
4
5
6
7
8
9
10
11
|
int cum(){
int i,j,k=0;
for (i=0;i<9;i++){
for (j=0;j<11;j++){
if (screen[i][j]==2){
k++;
}
}
} //遍历整个二维数组
return k;
} //计算地图中有多少个终点
|
打印地图函数
通过switch函数对二维数组中的值进行可视化,也就是画出地图
注意:这里还定义出了6和7,是通过重叠的关系来算的,就是箱子在终点上,这个位置又有箱子又有终点2个标识,所以让两个的数值加起来,方便理解,也方便后面的计算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
void print(){
int i,j;
printf ( "请用wsad代表上下左右来进行游戏\n" );
for (i=0;i<9;i++){
for (j=0;j<11;j++){
switch (screen[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" );
}
}
|
判断游戏输赢
这里我写了2个函数,一个判断赢,一个判断输,并返回值,然后在主函数的最后面通过判断返回值来确定游戏的输赢
判断赢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int win(){
int i,j,k=0;
int t=0;
for (i=0;i<9;i++){
for (j=0;j<11;j++){
if (screen[i][j]==6){
k++;
}
}
} //遍历整个二维数组,计算箱子在终点上的个数
if (k==cum()){
t=1;
} //如果个数等于前面计算出的终点个数,则说明所有终点都放了箱子,说明游戏胜利
return t;
} //判断赢
|
判断输
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
int lose(){
int i,j;
int k=0;
for (i=0;i<9;i++){
for (j=0;j<11;j++){
if (i>0 && j>0 ){
if (screen[i][j] == 2 || screen[i][j] == 6){
if (((screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6) && (screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6))
|| ((screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6) && (screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6))
|| ((screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6) && (screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6))
|| ((screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6) && (screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6))){
k++;
}
}
}
} /*这里也是遍历了整个数组,判断所有的箱子四个方向的情况,
如果有三个方向被堵住了说明箱子无法移动了,也表明这个箱子失效了,
用k来记录失效的个数,当全部失效时游戏失败
(这是游戏的玩法,其实有一个被堵住就已经不可能胜利了)*/
}
if (k==cum()){
k=1;
}
return k; //返回1说明游戏失败
}
|
接下来是最重要的四个控制函数
向上移动
通过数字的变化来控制二维数组的变化,进而控制地图的更新
这里非常重要的就是要理解:加1,加2,加3减3都是什么意思
加1:箱子的值是2,人的值是3,所以箱子的位置变成人需要加1来实现
加2:空地的值是0,箱子的值是2,箱子和终点在一起的值是6,所以在推箱子的时候,前方的空格或者终点放上箱子后数值会加2
加3减3:人的值是3,人要动的话,它原先在的格子就会因为人走了导致数值减3,走到的那个格子就会因为站了人而加3
如果这个理解的话,代码就非常简单了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
void movew(){
if (x>0){
if (screen[x-1][y]==1){
return ; /*如果箱子的上面是墙,则地图不会发生变化,因为
推不动嘛*/
} else if (screen[x-1][y]==0){
screen[x-1][y]+=3;
screen[x][y]-=3;
x--; /*如果前面是空地,则需要向前移动一格,也就是原先人的位置
变成空地,前方的空地变成人,空地(0)变成人(3)需要加3,
人变成空地需要减3*/
} else if (screen[x-1][y]==4){
screen[x-1][y]+=3;
screen[x][y]-=3;
x--;
} //一样的
else if (screen[x-1][y]==2||screen[x-1][y]==6){
if (screen[x-2][y]==0){
screen[x-2][y]+=2; //箱子前面的格变成箱子(2)
screen[x-1][y]+=1; //箱子的位置变成人(3)
screen[x][y]-=3; /*如果前面是空地,则需要向前移动
一格,也就是原先是箱子的格子变成人,人的位置变成空
地,原先的空地变成箱子,箱子(2)变成人(3)需要减
3,空地变成人*/
x--;
} else if (screen[x-2][y]==1){
return ;
} else if (screen[x-2][y]==2){
return ; //如果箱子的前面是墙或者其他的箱子,则箱子推不动
} else if (screen[x-2][y]==4){
screen[x-2][y]+=2;
screen[x-1][y]+=1;
screen[x][y]-=3;
x--;
} //这个情况别漏了
}
}
}
|
其他三个方向的代码思路和这个是一样的
向下移动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
void moves(){
if (x<9){
if (screen[x+1][y]==1){
return ;
} else if (screen[x+1][y]==0){
screen[x+1][y]+=3;
screen[x][y]-=3;
x++;
} else if (screen[x+1][y]==4){
screen [x+1][y]+=3;
screen[x][y]-=3;
x++;
}
else if (screen[x+1][y]==2||screen[x+1][y]==6){
if (screen[x+2][y]==1){
return ;
} else if (screen[x+2][y]==0){
screen[x+2][y]+=2;
screen[x+1][y]+=1;
screen[x][y]-=3;
x++;
} else if (screen[x+2][y]==2){
return ;
} else if (screen[x+2][y]==4){
screen[x+2][y]+=2;
screen[x+1][y]+=1;
screen[x][y]-=3;
x++;
}
}
}
}
|
向左移动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
void movea(){
if (y>0){
if (screen[x][y-1]==1){
return ;
} else if (screen[x][y-1]==4){
screen[x][y-1]+=3;
screen[x][y]-=3;
y--;
}
else if (screen[x][y-1]==0){
screen[x][y-1]+=3;
screen[x][y]-=3;
y--;
} else if (screen[x][y-1]==2||screen[x][y-1]==6){
if (screen[x][y-2]==0){
screen[x][y-2]+=2;
screen[x][y-1]+=1;
screen[x][y]-=3;
y--;
} else if (screen[x][y-2]==1){
return ;
} else if (screen[x][y-2]==2){
return ;
} else if (screen[x][y-2]=4){
screen[x][y-2]+=2;
screen[x][y-1]+=1;
screen[x][y]-=3;
y--;
}
}
}
}
|
向右移动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
void moved(){
if (y<9){
if (screen[x][y+1]==1){
return ;
} else if (screen[x][y+1]==4){
screen[x][y+1]+=3;
screen[x][y]-=3;
y++;
}
else if (screen[x][y+1]==0){
screen[x][y+1]+=3;
screen[x][y]-=3;
y++;
} else
if (screen[x][y+1]==2||screen[x][y+1]==6){
if (screen[x][y+2]==0){
screen[x][y+2]+=2;
screen[x][y+1]+=1;
screen[x][y]-=3;
y++;
} else if (screen[x][y+2]==4){
screen[x][y+2]+=2;
screen[x][y+1]+=1;
screen[x][y]-=3;
y++;
} else if (screen[x][y+2]==2){
return ;
} else if (screen[x][y+2]==1){
return ;
}
}
}
}
|
主函数
这个主函数写的有点乱,直接看注释吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
int main(){
int n,t;
int j,k;
int b=1;
here:
system ( "cls" ); //
printf ( "开始游戏请按1\n退出游戏请按2\n" );
scanf ( "%d" ,&j);
if (j==1){
printf ( "请用wsad代表上下左右来进行游戏\n" ); //这个就引导进入游戏
while (1){
system ( "cls" ); /*在每一次移动过后都清除上一个地图,不然就会每走
一步生成一个图*/
print(); //先打印地图
scanf ( "%c" ,&n); //读入用户的操作
switch (n){
case 'w' :
movew();
break ;
case 's' :
moves();
break ;
case 'a' :
movea();
break ;
case 'd' :
moved();
break ;
} //控制人移动
t=win();
if (t==1){
goto there;
} //每次操作完先判断游戏是否胜利,如果胜利了直接跳到函数最后
if (b == lose()){
system ( "cls" );
print();
printf ( "游戏失败" );
return 0;
} //游戏失败提示
}
} else {
system ( "cls" );
printf ( "您确认要退出游戏吗\n确认退出按1\t返回上一层按2\n" );
scanf ( "%d" ,&k);
if (k==1){
printf ( "你已退出游戏,期待你的再次到来,谢谢" );
return 0;
} else {
goto here;
}
} //这一块是最前面用户进入游戏那里的,如果用户选择退出游戏执行的操作
there:
printf ( "恭喜你通过了游戏!" );
return 0;
} //主函数
|
所有的代码就到这里了,如果需要完整代码可以留言
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/m0_50855872/article/details/111320297