走迷宫
走迷宫是游戏中相当常见的游戏了,大多数游戏都是一大段迷宫走来走去,然后再走出迷宫,闯下一关。我摘取了一个游戏迷宫的代码,来巩固一下自己学习过的c基础知识。
#include <stdio.h>
#include <stdlib.h>
int visit(int,int);
int maze[7][7] = { //地图
{2,2,2,2,2,2,2},
{2,0,0,0,0,0,2},
{2,0,2,0,2,0,2},
{2,0,0,2,0,2,2},
{2,2,0,2,0,2,2},
{2,0,0,0,0,0,2},
{2,2,2,2,2,2,2}
};
int starti = 1, startj = 1;
int endi = 5, endj = 5;
int success = 0;
int main(int argc, const char * argv[])
{
int i,j;
printf("display:\n"); //输出原始地图
for(i = 0; i < 7; i++)
{
for(j = 0; j < 7; j++)
{
if(maze[i][j] == 2)
printf("#");
else
printf(" ");
}
printf("\n");
}
if(visit(starti,startj) == 0)
printf("\nno way\n");
else
{
printf("\ndisplay way:\n"); //输出路线
for(i = 0; i < 7; i++)
{
for(j = 0; j < 7; j++)
{
if(maze[i][j] == 2)
printf("#");
else if(maze[i][j] == 1)
printf("@");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
int visit(int i,int j)
{
maze[i][j] = 1;
if(i == endi && j == endj)
success = 1;
if(success != 1 && maze[i][j+1] == 0) //递归先向右走,循环走到尽头之后是否能到终点
visit(i,j+1);
if(success != 1 && maze[i+1][j] == 0)
visit(i+1,j);
if(success != 1 && maze[i][j-1] == 0)
visit(i,j-1);
if(success != 1 && maze[i-1][j] == 0)
visit(i-1,j);
if(success != 1)
maze[i][j] = 0;
return success;
}
运行结果:
display:
#######
# #
# # # #
# # ##
## # ##
# #
#######
display way:
#######
#@ #
#@# # #
#@@# ##
##@# ##
# @@@@#
#######
走迷宫改进
由于之前的走迷宫游戏只能输出一条路线,现在做了一下修改,把所有路线都输出出来。
#include <stdio.h>
#include <stdlib.h>
void visit(int,int);
int maze[9][9] = {
{2,2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,2,0,0,2},
{2,0,2,0,2,0,2,0,2},
{2,0,0,0,0,0,2,0,2},
{2,2,0,2,2,0,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,2,2,2,2,2,2,2,2}
};
int starti = 1, startj = 1;
int endi = 7, endj = 7;
int main(int argc, const char * argv[])
{
int i,j;
printf("display:\n");
for(i = 0; i < 9; i++)
{
for(j = 0; j < 9; j++)
{
if(maze[i][j] == 2)
printf("#");
else
printf(" ");
}
printf("\n");
}
visit(starti,startj);
return 0;
}
void visit(int i,int j)
{
int m,n;
maze[i][j] = 1;
if(i == endi && j == endj)
{
printf("\ndisplay way:\n");
for(m = 0; m < 9; m++)
{
for(n = 0; n < 9; n++)
{
if(maze[m][n] == 2)
printf("#");
else if(maze[m][n] == 1)
printf("@");
else
printf(" ");
}
printf("\n");
}
}
if(maze[i][j+1] == 0) //直接遍历所有路线,去掉了原来判断是否到达终点的条件
visit(i,j+1);
if(maze[i+1][j] == 0)
visit(i+1,j);
if(maze[i][j-1] == 0)
visit(i,j-1);
if(maze[i-1][j] == 0)
visit(i-1,j);
maze[i][j] = 0;
}
运行结果:
display:
#########
# #
# ## ## #
# # # #
# # # # #
# # #
## ## ###
# #
#########
display way:
#########
#@@@@ #
# ##@## #
# #@@# #
# #@# # #
# @@@# #
## ##@###
# @@@#
#########
display way:
#########
#@@@@ #
# ##@## #
# #@@# #
# #@# # #
# @@ # #
##@## ###
# @@@@@@#
#########
display way:
#########
#@ #
#@## ## #
#@# # #
#@# # # #
#@@@@@# #
## ##@###
# @@@#
#########
display way:
#########
#@ #
#@## ## #
#@# # #
#@# # # #
#@@ # #
##@## ###
# @@@@@@#
#########
推箱子游戏
这个程序是在传智的基础班上课的时候学习到的程序,当时是作为作业自己写了一下。
#include <stdio.h>
//打印函数
void printMap(char map[][6], int row, int col);
int main(int argc, const char * argv[])
{
char map[6][6] = {
{'#','#','#','#','#','#'},
{'#','0',' ',' ',' ',' '},//第一行的第一列
{'#',' ','@',' ',' ','#'},//第二行的第一列
{'#',' ',' ',' ',' ','#'},
{'#',' ',' ',' ',' ','#'},
{'#','#','#','#','#','#'}
};
int row = (sizeof(map)/sizeof(char))/(sizeof(map[0])/sizeof(char));
int col = sizeof(map[0])/sizeof(char);
printMap(map, row, col);
char input;//接收用户输入的变量
int startX = 1;
int startY = 1;
int endX = 1;
int endY = 5;
while (map[endX][endY] != '0') {
input = getchar();//从输入缓冲区拿走一个字符
getchar();//作用是从输入缓冲区取走\n
printf("用户的输入 %c\n",input);
switch (input) {
case 's'://向下走
//判断下一步是否是墙
if(map[startX + 1][startY] != '#'){
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startX++;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX+1][startY] != '#')
map[startX+1][startY] = '@';
map[startX][startY] = '0';
}
break;
case 'w'://向上走
//判断下一步是否是墙
if (map[startX - 1][startY] != '#' ) {
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startX--;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX-1][startY] != '#')
map[startX-1][startY] = '@';
map[startX][startY] = '0';
}
break;
case 'a'://往左走
//判断下一步是否是墙
if(map[startX][startY - 1] != '#'){
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startY--;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX][startY-1] != '#')
map[startX][startY-1] = '@';
map[startX][startY] = '0';
}
break;
case 'd'://往右走
if (map[startX][startY + 1] != '#') {
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startY++;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX][startY+1] != '#')
map[startX][startY+1] = '@';
map[startX][startY] = '0';
}
break;
default:
break;
}
printMap(map, row, col);
}
printf("你真的好NB哦。。。!!!\n");
printf("想超越自己,请付费购买下一版\n");
return 0;
}
void printMap(char map[][6], int row, int col)
{
//遍历二维数组,打印地图
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf("%c",map[i][j]);
}
printf("\n");
}
}
运行结果:
######
#0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
s
用户的输入 s
######
#
# 0 #
# @ #
# #
######
s
用户的输入 s
######
#
# #
# 0 #
# @ #
######
s
用户的输入 s
######
#
# #
# #
# 0 #
######
我玩着玩的时候发现了箱子被我推没了,这是我遇到的第一个bug。这个bug让我感受到了程序在后台运作时有bug的灾难。
推箱子bug修复
当发现bug之后我开了第一次对程序的bug修复工作,虽然很简单但是这个工作我还是认认真真地去对待地。
#include <stdio.h>
//打印函数
void printMap(char map[][6], int row, int col);
int main(int argc, const char * argv[])
{
char map[6][6] = {
{'#','#','#','#','#','#'},
{'#','0',' ',' ',' ',' '},//第一行的第一列
{'#',' ','@',' ',' ','#'},//第二行的第一列
{'#',' ',' ',' ',' ','#'},
{'#',' ',' ',' ',' ','#'},
{'#','#','#','#','#','#'}
};
// 2.打印地图,展示给玩家
int row = (sizeof(map)/sizeof(char))/(sizeof(map[0])/sizeof(char));
int col = sizeof(map[0])/sizeof(char);
printMap(map, row, col);
char input;//接收用户输入的变量
// 起始坐标
int startX = 1;
int startY = 1;
// 终止坐标
int endX = 1;
int endY = 5;
while (map[endX][endY] != '@') {
input = getchar();//从输入缓冲区拿走一个字符
getchar();//作用是从输入缓冲区取走\n
printf("用户的输入 %c\n",input);
switch (input) {
case 's'://向下走
//判断下一步是否是墙
if(map[startX + 1][startY] != '#'){
if (map[startX+1][startY] == '@' && map[startX+2][startY] == '#') {
break;
}
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startX++;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX+1][startY] != '#')
map[startX+1][startY] = '@';
map[startX][startY] = '0';
}
break;
case 'w'://向上走
//判断下一步是否是墙
if (map[startX - 1][startY] != '#' ) {
if (map[startX-1][startY] == '@' && map[startX-2][startY] == '#') {
break;
}
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startX--;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX-1][startY] != '#')
map[startX-1][startY] = '@';
map[startX][startY] = '0';
}
break;
case 'a'://往左走
//判断下一步是否是墙
if(map[startX][startY - 1] != '#'){
if (map[startX][startY-1] == '@' && map[startX][startY-2] == '#') {
break;
}
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startY--;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX][startY-1] != '#')
map[startX][startY-1] = '@';
map[startX][startY] = '0';
}
break;
case 'd'://往右走
if (map[startX][startY + 1] != '#') {
if (map[startX][startY+1] == '@' && map[startX][startY+2] == '#') {
break;
}
//当前小人所在的位置替换成空格
map[startX][startY] = ' ';
startY++;
//替换下一步成"0"
if(map[startX][startY] == '@' && map[startX][startY+1] != '#')
map[startX][startY+1] = '@';
map[startX][startY] = '0';
}
break;
default:
break;
}
// 4.往下走
printMap(map, row, col);
}
printf("你真的好NB哦。。。!!!\n");
printf("想超越自己,请付费购买下一版\n");
return 0;
}
void printMap(char map[][6], int row, int col)
{
//遍历二维数组,打印地图
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf("%c",map[i][j]);
}
printf("\n");
}
}
运行结果:
######
#0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
d
用户的输入 d
######
# 0
# @ #
# #
# #
######
a
用户的输入 a
######
# 0
# @ #
# #
# #
######
a
用户的输入 a
######
# 0
# @ #
# #
# #
######
a
用户的输入 a
######
# 0
# @ #
# #
# #
######
a
用户的输入 a
######
#0
# @ #
# #
# #
######
s
用户的输入 s
######
#
#0@ #
# #
# #
######
s
用户的输入 s
######
#
# @ #
#0 #
# #
######
d
用户的输入 d
######
#
# @ #
# 0 #
# #
######
w
用户的输入 w
######
# @
# 0 #
# #
# #
######
w
用户的输入 w
######
# @
# 0 #
# #
# #
######
w
用户的输入 w
######
# @
# 0 #
# #
# #
######
a
用户的输入 a
######
# @
#0 #
# #
# #
######
w
用户的输入 w
######
#0@
# #
# #
# #
######
d
用户的输入 d
######
# 0@
# #
# #
# #
######
d
用户的输入 d
######
# 0@
# #
# #
# #
######
d
用户的输入 d
######
# 0@
# #
# #
# #
######
你真的好NB哦。。。!!!
想超越自己,请付费购买下一版
经过自己地测试之后,我把游戏地异常退出和箱子被推没地bug都解决了。这回游戏玩起来舒畅多了,就是代码写的啰嗦了点,以后还会改进地。
地图分离文件
我们在玩游戏地时候只玩一个图太没意思了,所以我把程序又做了一个改动,将地图的数组的定义分离出去,现在拿迷宫的游戏为例。
main.c
#include <stdio.h>
#include <stdlib.h>
#include "map.h"
int visit(int,int);
int main(int argc, const char * argv[])
{
int i,j;
printf("display:\n");
for(i = 0; i < len; i++)
{
for(j = 0; j < len; j++)
{
if(maze[i][j] == 2)
printf("#");
else
printf(" ");
}
printf("\n");
}
if(visit(starti,startj) == 0)
printf("\nno way\n");
else
{
printf("\ndisplay way:\n");
for(i = 0; i < len; i++)
{
for(j = 0; j < len; j++)
{
if(maze[i][j] == 2)
printf("#");
else if(maze[i][j] == 1)
printf("@");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
int visit(int i,int j)
{
maze[i][j] = 1;
if(i == endi && j == endj)
success = 1;
if(success != 1 && maze[i][j+1] == 0)
visit(i,j+1);
if(success != 1 && maze[i+1][j] == 0)
visit(i+1,j);
if(success != 1 && maze[i][j-1] == 0)
visit(i,j-1);
if(success != 1 && maze[i-1][j] == 0)
visit(i-1,j);
if(success != 1)
maze[i][j] = 0;
return success;
}
map.h
#ifndef struct_Header_h
#define struct_Header_h
int maze[7][7] = {
{2,2,2,2,2,2,2},
{2,0,0,0,0,0,2},
{2,0,2,0,2,0,2},
{2,0,0,2,0,2,2},
{2,2,0,2,0,2,2},
{2,0,0,0,0,0,2},
{2,2,2,2,2,2,2}
};
int starti = 1, startj = 1;
int endi = 5, endj = 5;
int success = 0;
int len = sizeof(maze[0])/sizeof(int);
#endif
map2.h
#ifndef struct_Header_h
#define struct_Header_h
int maze[8][8] = {
{2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,2,2},
{2,0,2,0,2,0,0,2},
{2,0,0,2,0,2,0,2},
{2,2,0,2,0,2,2,2},
{2,0,0,0,0,0,0,2},
{2,0,2,0,0,0,0,2},
{2,2,2,2,2,2,2,2}
};
int starti = 1, startj = 1;
int endi = 6, endj = 6;
int success = 0;
int len = sizeof(maze[0])/sizeof(int);
#endif
当程序main.c文件中包含map.h文件时运行结果如下:
display:
#######
# #
# # # #
# # ##
## # ##
# #
#######
display way:
#######
#@ #
#@# # #
#@@# ##
##@# ##
# @@@@#
#######
#include就是原模原样把源文件拷贝到调用文件中,所以地图文件完全可以从main.c文件中释放出来单独处理。有的时候为了防止头文件重复包含,需要下段代码来支持:
#ifndef struct_Header_h
#define struct_Header_h
#endif
中间的那部分代码可以不被重复包含,因为当头文件被包含时,#ifndef会判断有没有struct_Header_h这个宏的存在,如果有则中间内容不被包含,如果没有则中间内容包含并定义该宏。
当头文件包含map2.h文件时的运行结果如下:
display:
########
# ##
# # # #
# # # #
## # ###
# #
# # #
########
display way:
########
#@ ##
#@# # #
#@@# # #
##@# ###
# @@@@@#
# # @#
########
这样就可以实现不同地图的游戏玩法了。