C语言写迷宫游戏

C语言写迷宫游戏

这篇文章是给学完并学懂了C语言的分支(选择和循环)结构和二维数组的朋友看的。

要做一个游戏或者程序先要想好有那些要求,以下是我认为一个迷宫必带的要求: 

  1. 迷宫要先打印出来(要设置墙、空气、小球的起点),是墙就不能,是空气就可以走。
  2. 每次输入'w'、'a'、's'、'd'为上、左、下、右,并每次输入后,不用按回车或任意键继续就能输出,每次走一步(按键盘的键走)后,先清屏再输出现在迷宫以及小球现在在哪里。
  3. 要有起点和终点的X、Y轴,如果小球与终点的位置相同了,就提示胜利并退出游戏。 

定义地图

首先我们要打印出地图,因为地图有长和宽的长度,所以我们要用二维数组来定义一个地图,代码如下:

    char map[50][50]={
                    "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                    "#O #  ",//'#'是墙(不可以走的地方)
                    "# ## #",//'O'是起点(可控制)
                    "#  # #",//' '是空气(可以走的地方)
                    "##   #",
                    "######",//横竖都是012345,012345(数组下标从0开始)
                    };

打印地图方法一

定义完二维数组,就要把它打印出来,代码如下:

int i,j;
for(i=0;i<6;i++)//i循环用来控制打印地图的行数
{
    for(j=0;j<6;j++)//j循环用来控制打印地图的列数
    {
        printf("%c",map[i][j]);//打印每次i和j的行数和列数
    }
    printf("\n");//一行打印完毕需要换行
}

打印地图方法二

上面这段代码是通过双重循环打印出地图的每行每列。

如果学过puts函数来输出字符数组的朋友可以这样写,代码如下:

int i;
for(i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
    puts(map[i]);//表示输出每一行的字符串

是不是简单了许多,不懂puts函数的朋友也没关系,你用第一种方法就行,对于puts函数你只需要知道:

  1. 使用 puts() 显示字符串时,系统会自动在其后添加一个换行符。
  2. 只有遇到 '\0' 也就是字符串结束标志符才会停止。

定义起点和终点位置

然后再定义起点和终点的X、Y轴位置(当然上面定义二维数组时已经看得出来了),代码如下:

​int x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
            //p,q为空白(终点" ")结束位置竖横轴
x=1;y=1;//x为竖轴初始位置为1,y为初始横轴位置为1
p=1;q=5;//p为竖轴结束位置为1,q为结束横轴位置为5

总结以上代码

目前为止,我们做了定义地图、打印地图、定义起点终点的X、Y轴,目前全部代码如下:

#include//printf("");的头文件
#include//system("");的头文件
#include//Sleep();的头文件
int m1ain(void)
{
    char map[50][50]={
                        "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                        "#O #  ",//'#'是墙(不可以走的地方)
                        "# ## #",//'O'是起点(可控制)
                        "#  # #",//' '是空气(可以走的地方)
                        "##   #",
                        "######",//横竖都是012345,012345(数组下标从0开始)
                        };
    int i,x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
                  //p,q为空白(终点" ")结束位置竖横轴
    int ch;//申请需要输入的字符(名称是ch),当移动(w,a,s,d)
    x=1;y=1;p=1;q=5;//x为竖轴初始位置为1,y为初始横轴位置为1
                    //p为竖轴结束位置为1,q为结束横轴位置为5
    for(i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
        puts(map[i]);//表示输出每一行的字符串
    Sleep(5000);//上面代码全部执行完毕后过五秒自动关闭程序
    return 0;
}

现在我们就要想办法控制小球了,这里利用键盘上的'w''s''a''d'四个键来控制这个小球进行上、下、左、右移动,当然你如果喜欢,也可以用别的按键。

第一步:先来控制小球向下移动,也就是当你按下's'键时,小球向下移动一步。

那么如何获得's'这个按键呢,换句话说:当你按下's'键时,我们的程序怎样知道你按的是's'键呢?


实现读取按键

很简单,因为你按下's'键时,本质上是输入了1个字符's',我们只需要读取这个字符's'就可以了,读取一个字符有4种方法:

char ch;
scanf("%c",&ch);//读取一个字符,输入后等待用户按"Enter"键结束(带回显)
ch=getchar;//读取一个字符,输入后等待用户按"Enter"键结束(带回显)
ch=getche;//读取一个字符,输入后立即获取字符,不用按"Enter"键结束(带回显)
ch=getch;//读取一个字符,输入后立即获取字符,不用按"Enter"键结束(不带回显)

而我们并不想显示输入的字符,并且希望输入的字符可以立即被程序获得,而不用在敲击一个字符后再敲击一个"Enter"键。

因此我们选用最后一个语句ch=getch();。


实现小球下向下移动一步

接下来,我们要把在键盘上敲击的字符存储在字符变量ch中,再接下来实现当敲击's'时。让小球向下移动一步,代码如下:

​if(ch=='s')//判断你是否输入(按)'s'这个字符
{
    if(map[x+1][y]!='#')//确认输入(按)的是's'时,就执行[x+1][y](往下走,x为竖轴,+1为往下,y不变),提前是还要判断往下走是否为'#'(墙)
    {                       
        map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
        x++;//为向下走
        map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'
    }
}

在上面代码中,我们通过if语句来判断敲击的字符是否是字符's',如果是字符's',我们就让小球向下移动一步,但在小球向下移动之前,需要首先判断下面一步是否能移动,只有下一步不是墙'#'时小球才能移动。

也就是说当if(map[x+1][y]!='#')条件成立时,就表示下一步不是墙,小球可以移动。

可能有些朋友会问:为什么[x+1][y]就表示向下走一部的格子呢?

其实很简单:向下移动时,小球当然还在当前这个列,不过不在这一行,而是在下一行,因此向下移动是y不变,x加1。

如果是向右边移动,很显然还是在同一行,所以x不变,但是小球已经不在刚才那一竖列了,而在右边的一个竖列,因此y需要加1。


总结小球移动规律

  • 向下移动是y不变,x加1。
  • 向上移动是y不变,x减1。
  • 向左移动是x不变,y减1。
  • 向右移动是x不变,y加1。

接下来我们来讲解下面这3句话的意思:

map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
x++;//为向下走
map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'

让小球向下移动,就是让小球原本位置上的'O'变成空格,而让下一个空格变成'O'。

第一句:map[x][y]=' ';(注意此处两个单引号之间中间有一个空格)就是让小球的当前位置变为空格,

第二句:x++;这句话非常重要,它表示更改小球的位置,因为小球向下运动只需要x++就可以了,y不变。

第三句:a[x][y]='O';语句就是将小球新位置上的内容替换为小球'O'。

请注意上面一个代码,可不能写成:

map[x][y]=' ';           
map[x+1][y]='O';

至于为什么,大家自己去想想吧!


实现重新打印地图

因为小球的位置有了变化,因此还需要将新迷宫的状态重新打印一次,在打印之前记得要将之前的屏幕清屏,代码如下:

int i;
system("cls");//每次移动了小球就清屏一次
for(i=0;i<6;i++)//清屏了再次循环输出新的地图
    puts(map[i]);//清屏了再次输出新的地图

总结以上代码

​#include//printf("");的头文件
#include//system("");的头文件
#include//Sleep();的头文件
#include//getch();的头文件
int main(void)
{
    char map[50][50]={
                        "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                        "#O #  ",//'#'是墙(不可以走的地方)
                        "# ## #",//'O'是起点(可控制)
                        "#  # #",//' '是空气(可以走的地方)
                        "##   #",
                        "######",//横竖都是012345,012345(数组下标从0开始)
                        };
    int i,x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
                  //p,q为空白(终点" ")结束位置竖横轴
    int ch;//申请需要输入的字符(名称是ch),当移动(w,a,s,d)
    x=1;y=1;p=1;q=5;//x为竖轴初始位置为1,y为初始横轴位置为1
                    //p为竖轴结束位置为1,q为结束横轴位置为5
    for(i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
        puts(map[i]);//表示输出每一行的字符串
    ch=getch();//这语句表示给ch变量输入的字符可以立即被程序获取(不用按任意键继续),也不会回显
    if (ch=='s')//判断你是否输入(按)'s'这个字符
    {
        if (map[x+1][y]!='#')//确认输入(按)的是's'时,就执行[x+1][y](往下走,x为竖轴,+1为往下,y不变),提前是还要判断往下走是否为'#'(墙)
        {                       
            map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
            x++;//为向下走
            map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'
        }
    }
    system("cls");//每次移动了小球就清屏一次
    for(i=0;i<6;i++)//清屏了再次循环输出新的地图
       puts(map[i]);//清屏了再次输出新的地图
    Sleep(5000);//上面代码全部执行完毕后过五秒自动关闭程序
    return 0;
}

运行一下,然后按一下's'键,是不是已经可以看到小球向下移动了一步了呢?

但是你只能移动一步,如何实现连续移动呢?


实现连续移动

很简单,实现连续移动我们可以通过while循环来解决问题:

#include//printf("");的头文件
#include//system("");的头文件
#include//Sleep();的头文件
#include//getch();的头文件
int m1ain(void)
{
    char map[50][50]={
                        "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                        "#O #  ",//'#'是墙(不可以走的地方)
                        "# ## #",//'O'是起点(可控制)
                        "#  # #",//' '是空气(可以走的地方)
                        "##   #",
                        "######",//横竖都是012345,012345(数组下标从0开始)
                        };
    int i,x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
                  //p,q为空白(终点" ")结束位置竖横轴
    int ch;//申请需要输入的字符(名称是ch),当移动(w,a,s,d)
    x=1;y=1;p=1;q=5;//x为竖轴初始位置为1,y为初始横轴位置为1
                    //p为竖轴结束位置为1,q为结束横轴位置为5
    for(i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
        puts(map[i]);//表示输出每一行的字符串
    while(1)//暂时无限循环
    {
        ch=getch();//这语句表示给ch变量输入的字符可以立即被程序获取(不用按任意键继续),也不会回显
        if(ch=='s')//判断你是否输入(按)'s'这个字符
        {
            if(map[x+1][y]!='#')//确认输入(按)的是's'时,就执行[x+1][y](往下走,x为竖轴,+1为往下,y不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
                x++;//为向下走
                map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'
            }
        }
        system("cls");//每次移动了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次循环输出新的地图
           puts(map[i]);//清屏了再次输出新的地图
    }
    Sleep(5000);//上面代码全部执行完毕后过五秒自动关闭程序
    return 0;
}

暂时先使用while(1)无限循环来解决这个问题,好了,运行一下吧。

此时小球是不是可以连续移动了?

当然,目前小球还只能朝一个方向运动,接下来我们来实现小球向其它3个方向的运动。


实现小球下向上下左右移动

向其它3个方向移动其实和"向下移动"是差不多的,只要注意是x在变化还是y在变化,是加1还是减1就可以了。无限移动4个方向代码如下:

#include//printf("");的头文件
#include//system("");的头文件
#include//Sleep();的头文件
#include//getch();的头文件
int m1ain(void)
{
    char map[50][50]={
                        "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                        "#O #  ",//'#'是墙(不可以走的地方)
                        "# ## #",//'O'是起点(可控制)
                        "#  # #",//' '是空气(可以走的地方)
                        "##   #",
                        "######",//横竖都是012345,012345(数组下标从0开始)
                        };
    int i,x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
                  //p,q为空白(终点" ")结束位置竖横轴
    int ch;//申请需要输入的字符(名称是ch),当移动(w,a,s,d)
    x=1;y=1;p=1;q=5;//x为竖轴初始位置为1,y为初始横轴位置为1
                    //p为竖轴结束位置为1,q为结束横轴位置为5
    for (i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
        puts(map[i]);//表示输出每一行的字符串
    while(1)//暂时无限循环
    {
        ch=getch();//这语句表示给ch变量输入的字符可以立即被程序获取(不用按任意键继续),也不会回显
        if(ch=='s')//判断你是否输入(按)'s'这个字符
        {
            if(map[x+1][y]!='#')//确认输入(按)的是's'时,就执行[x+1][y](往下走,x为竖轴,+1为往下,y不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
                x++;//为向下走
                map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='w')//判断你是否输入(按)'w'这个字符
        {
            if(map[x-1][y]!='#')//确认输入(按)的是'w'时,就执行[x-1][y](往上走,x为竖轴,-1为往上,y不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往上走不是墙时,把当前的'O'输出成' '
                x--;//为向上走
                map[x][y]='O';//确认往上走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='a')//判断你是否输入(按)'a'这个字符
        {
            if(map[x][y-1]!='#')//确认输入(按)的是'a'时,就执行[x][y-1](往左走,y为横轴,-1为往左,x不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往左走不是墙时,把当前的'O'输出成' '
                y--;//为向左走
                map[x][y]='O';//确认往左走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='d')//判断你是否输入(按)'d'这个字符
        {
            if(map[x][y+1]!='#')//确认输入(按)的是'd'时,就执行[x][y-1](往右走,y为横轴,+1为往右,x不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往右走不是墙时,把当前的'O'输出成' '
                y++;//为向右走
                map[x][y]='O';//确认往右走不是墙时,把下一步的' '输出成'O'
            }
        }
        system("cls");//每次移动了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次循环输出新的地图
           puts(map[i]);//清屏了再次输出新的地图
    }
    Sleep(5000);//上面代码全部执行完毕后过五秒自动关闭程序
    return 0;
}

好了,你是不是已经成功走出了迷宫?

可是貌似程序并没有让你很惊喜,因为没有判定你已经成功走出迷宫。

最后我们来写一个"获胜"的检测部分,其实只需要将我们之前写的while(1)改为while(x!=p||y!=q)就可以了。


实现小球走到终点就胜利

还记得吗,之前我们用p和q分别存储了迷宫出口的坐标位置,当然了,在最后我们需要打印"你获胜了"。完整代码如下:

#include//printf("");的头文件
#include//system("");的头文件
#include//Sleep();的头文件
#include//getch();的头文件
int m1ain(void)
{
    printf("欢迎来到迷宫小游戏\n");//介绍这个迷宫游戏
    printf("操作方式:\nw为往上走\ns为往下走\na为往左走\nd为往右走\n");//介绍操作方式
    char map[50][50]={
                        "######",//申请50*50的二维字符串当迷宫地图,但这里是6*6的地图
                        "#O #  ",//'#'是墙(不可以走的地方)
                        "# ## #",//'O'是起点(可控制)
                        "#  # #",//' '是空气(可以走的地方)
                        "##   #",
                        "######",//横竖都是012345,012345(数组下标从0开始)
                        };
    int i,x,y,p,q;//x,y为小球(起点"O")初始位置竖横轴 
                  //p,q为空白(终点" ")结束位置竖横轴
    int ch;//申请需要输入的字符(名称是ch),当移动(w,a,s,d)
    x=1;y=1;p=1;q=5;//x为竖轴初始位置为1,y为初始横轴位置为1
                    //p为竖轴结束位置为1,q为结束横轴位置为5
    for(i=0;i<6;i++)//从0到5,共进行了6次循环,依次输出迷宫的第0至5行
        puts(map[i]);//表示输出每一行的字符串
     while (x!=p||y!=q)//只要x的值不等p或y的值不等q就无限循环   
    {
        ch=getch();//这语句表示给ch变量输入的字符可以立即被程序获取(不用按任意键继续),也不会回显
        if(ch=='s')//判断你是否输入(按)'s'这个字符
        {
            if(map[x+1][y]!='#')//确认输入(按)的是's'时,就执行[x+1][y](往下走,x为竖轴,+1为往下,y不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往下走不是墙时,把当前的'O'输出成' '
                x++;//为向下走
                map[x][y]='O';//确认往下走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='w')//判断你是否输入(按)'w'这个字符
        {
            if(map[x-1][y]!='#')//确认输入(按)的是'w'时,就执行[x-1][y](往上走,x为竖轴,-1为往上,y不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往上走不是墙时,把当前的'O'输出成' '
                x--;//为向上走
                map[x][y]='O';//确认往上走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='a')//判断你是否输入(按)'a'这个字符
        {
            if(map[x][y-1]!='#')//确认输入(按)的是'a'时,就执行[x][y-1](往左走,y为横轴,-1为往左,x不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往左走不是墙时,把当前的'O'输出成' '
                y--;//为向左走
                map[x][y]='O';//确认往左走不是墙时,把下一步的' '输出成'O'
            }
        }
        if(ch=='d')//判断你是否输入(按)'d'这个字符
        {
            if(map[x][y+1]!='#')//确认输入(按)的是'd'时,就执行[x][y-1](往右走,y为横轴,+1为往右,x不变),提前是还要判断往下走是否为'#'(墙)
            {                       
                map[x][y]=' ';//确认往右走不是墙时,把当前的'O'输出成' '
                y++;//为向右走
                map[x][y]='O';//确认往右走不是墙时,把下一步的' '输出成'O'
            }
        }
        system("cls");//每次移动了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次循环输出新的地图
           puts(map[i]);//清屏了再次输出新的地图
    }
    system("cls");//最后通关后清屏
    printf("恭喜你赢了!\n");//最后通关后提示输出语句
    Sleep(5000);//上面代码全部执行完毕后过五秒自动关闭程序
    return 0;
}

欢迎大家来加我自己的编程语言交流QQ群群号:387618421

你可能感兴趣的:(C,#,迷宫,C游戏,c语言,开发语言,后端)