c语言游戏实战(5):走迷宫

 前言:

制作一个迷宫游戏是一个有趣的编程挑战。首先,我们需要设计一个二维数组来表示迷宫的布局,其中每个元素代表迷宫中的一个格子。我们可以使用不同的值来表示空格、墙壁和起点/终点。接下来,我们需生成迷宫。在生成迷宫的过程中,我们需要确保迷宫中有足够的障碍物,以便玩家需要找到一条从起点到终点的路径。最后,我们需要编写代码来显示迷宫,接收用户的输入,更新迷宫的状态,判断游戏是否结束,并提供重新开始的选项。通过完成这个迷宫游戏项目,我们可以提高自己的编程能力和逻辑思维能力。

1. 打印菜单

void menu()
{
	printf("|---------------------------------------|\n");
	printf("|                                       |\n");
	printf("|                走迷宫                 |\n");
	printf("|                1.play                 |\n");
	printf("|                2.exit                 |\n");
	printf("|                                       |\n");
	printf("|---------------------------------------|\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("选择有误,请重新选择!\a\n");
		}
	} while (input);
}

2. 分析迷宫的组成要素

迷宫的组成要素无非就是:墙、路、入口、出口,根据这些要素我们可以设置一个数组然后随机给其赋值为0,1,2,3,当数组等于0时打印路(这里用空格代替),等于1时打印墙(这里用█代替),等于2打印入口(这里用S代替),等于3时打印出口(这里用E代替)。

3. 实现迷宫的组成要素

因为这些要素的生成都与随机数有关,所以这里就要使用到time函数、srand函数和rand函数来进行随机数的生成。

#include<time.h>
srand((time(NULL))
int x = rand();

3.1 生成路

给数组初始化为0生成路,后面再用随机数生成。

  for (int i = 0; i < SIZE; i++)
  {
      for (int j = 0; j < SIZE; j++)
      {
          maze[i][j] = 0;
      }
  }

3.2 生成围墙

还需要设置围墙将我们的迷宫围起来,防止数组的越界访问。

for (int i = 0; i < SIZE; i++)
{
    maze[0][i] = 1;
    maze[i][0] = 1;
    maze[SIZE - 1][i] = 1;
    maze[i][SIZE - 1] = 1;
}

3.3 生成入口和出口

因为入口和出口都是只有一个,所以这里我们需要单独使用随机数生成入口和出口。

 int start_x = rand() % SIZE;
 int start_y = rand() % SIZE;
 maze[start_y][start_x] = 2;

 int end_x = rand() % SIZE;
 int end_y = rand() % SIZE;
 maze[end_y][end_x] = 3;

3.4 防止入口或出口出现在围墙上

这里使用了goto语句

again:
    //围墙
    for (int i = 0; i < SIZE; i++)
    {
        maze[0][i] = 1;
        maze[i][0] = 1;
        maze[SIZE - 1][i] = 1;
        maze[i][SIZE - 1] = 1;
    }
    //设置入口与出口
     int start_x = rand() % SIZE;
     int start_y = rand() % SIZE;
     maze[start_y][start_x] = 2;

     int end_x = rand() % SIZE;
     int end_y = rand() % SIZE;
     maze[end_y][end_x] = 3;
     //防止入口或出口出现在围墙上
     if (start_x == 0 || start_x == SIZE - 1 || start_y == 0 || start_y == SIZE - 1
         || end_x == 0 || end_x == SIZE - 1 || end_y == 0 || end_y == SIZE - 1)
     {
         goto again;
     }

3.5 生成墙

for (int i = 0; i < SIZE; i++)
{
    for (int j = 0; j < SIZE; j++)
    {
        if (maze[i][j] != 2 && maze[i][j] != 3)
        {
            if (rand() % 4 == 0)
            {
                maze[i][j] = 1;
            }
        }
    }
}

4. 操作移动

在这里用到了getch()函数,这个函数需要用#include <conio.h>来进行调用。

#include <conio.h>
int main()
{
	while (1)
	{
		int x = getch(); 
		if (x == 'w')
			printf("上\n");
		if (x == 'a')
			printf("左\n");
		if (x == 's')
			printf("下\n");
		if (x == 'd')
			printf("右\n");
	}
	return 0;
}

do
{
    system("cls");
    print_maze(maze);
    int x = getch();
    if (x == 'w')//上
    {
        if (maze[start_y - 1][start_x] != 1)
        {
            maze[start_y][start_x] = 0;
            start_y--;
            maze[start_y][start_x] = 2;
        }
    }
    if (x == 'a')//左
    {
        if (maze[start_y][start_x - 1] != 1)
        {
            maze[start_y][start_x] = 0;
            start_x--;
            maze[start_y][start_x] = 2;
        }
    }
    if (x == 's')//下
    {
        if (maze[start_y + 1][start_x] != 1)
        {
            maze[start_y][start_x] = 0;
            start_y++;
            maze[start_y][start_x] = 2;
        }
    }
    if (x == 'd')//右
    {
        if (maze[start_y][start_x + 1] != 1)
        {
            maze[start_y][start_x] = 0;
            start_x++;
            maze[start_y][start_x] = 2;
        }
    }
    if (maze[end_y][end_x] == 2)
    {
        printf("恭喜你成功通关!\n");
        break;
    }
} while (1);

 其中system("cls")函数的作用是清屏,它需要使用#icnldue<stdlib.h>进行调用。

完整代码 :

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
#include<conio.h>
#define SIZE 45
//打印迷宫
void print_maze(int maze[SIZE][SIZE])
{
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (maze[i][j] == 1)
            {
                printf("█");
            }
            else if (maze[i][j] == 2)
            {
                printf("S");//入口
            }
            else if (maze[i][j] == 3)
            {
                printf("E");//出口
            }
            else
            {
                printf(" ");
            }
        }
        printf("\n");
    }
    printf("\n");
}

void generate_maze(int maze[SIZE][SIZE])
{
again:
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            maze[i][j] = 0;
        }
    }
    //围墙
    for (int i = 0; i < SIZE; i++)
    {
        maze[0][i] = 1;
        maze[i][0] = 1;
        maze[SIZE - 1][i] = 1;
        maze[i][SIZE - 1] = 1;
    }
    //设置入口与出口
     int start_x = rand() % SIZE;
     int start_y = rand() % SIZE;
     maze[start_y][start_x] = 2;

     int end_x = rand() % SIZE;
     int end_y = rand() % SIZE;
     maze[end_y][end_x] = 3;
     //防止入口或出口出现在围墙上
     if (start_x == 0 || start_x == SIZE - 1 || start_y == 0 || start_y == SIZE - 1
         || end_x == 0 || end_x == SIZE - 1 || end_y == 0 || end_y == SIZE - 1)
     {
         goto again;
     }
    //设置迷宫
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (maze[i][j] != 2 && maze[i][j] != 3)
            {
                if (rand() % 4 == 0)
                {
                    maze[i][j] = 1;
                }
            }
        }
    }
    //操作S移动
    do
    {
        system("cls");
        print_maze(maze);
        int x = getch();
        if (x == 'w')//上
        {
            if (maze[start_y - 1][start_x] != 1)
            {
                maze[start_y][start_x] = 0;
                start_y--;
                maze[start_y][start_x] = 2;
            }
        }
        if (x == 'a')//左
        {
            if (maze[start_y][start_x - 1] != 1)
            {
                maze[start_y][start_x] = 0;
                start_x--;
                maze[start_y][start_x] = 2;
            }
        }
        if (x == 's')//下
        {
            if (maze[start_y + 1][start_x] != 1)
            {
                maze[start_y][start_x] = 0;
                start_y++;
                maze[start_y][start_x] = 2;
            }
        }
        if (x == 'd')//右
        {
            if (maze[start_y][start_x + 1] != 1)
            {
                maze[start_y][start_x] = 0;
                start_x++;
                maze[start_y][start_x] = 2;
            }
        }
        if (maze[end_y][end_x] == 2)
        {
            printf("恭喜你成功通关!\n");
            break;
        }
    } while (1);
}
void menu()
{
    printf("|---------------------------------------|\n");
    printf("|                                       |\n");
    printf("|                走迷宫                 |\n");
    printf("|                1.play                 |\n");
    printf("|                2.exit                 |\n");
    printf("|                                       |\n");
    printf("|---------------------------------------|\n");
}



void game()
{
    srand(time(NULL));
    int maze[SIZE][SIZE];
    //打印迷宫
    generate_maze(maze);
}

int main()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏!\n");
            break;
        default:
            printf("选择有误,请重新选择!\a\n");
        }
    } while (input);
}

效果图: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/501944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Go】三、Go指针

文章目录 1、指针2、说明 1、指针 &符号变量 就可以获取这个变量内存的地址*int 是一个指针类型 &#xff08;可以理解为 指向int类型的指针&#xff09; package main import("fmt" ) func main(){var age int 18//&符号变量 就可以获取这个变量内存的地…

武汉星起航:一站式跨境电商服务,助力企业扬帆远航

武汉星起航电子商务有限公司&#xff0c;作为业界知名的自营亚马逊跨境电商与孵化服务提供商&#xff0c;凭借优质的服务和卓越的口碑&#xff0c;赢得了众多企业的信赖与青睐。公司以其独特的一站式跨境电商服务优势&#xff0c;为合作伙伴提供了全方位、个性化的解决方案&…

[RAM] 3D RAM 能否复制 3D NAND 神话?

主页&#xff1a; 元存储博客 文章目录 前言挑战Lam Research 3D RAMNeo 3D X-RAM展望 前言 人工智能时代&#xff0c;DRAM的容量扩展受到限制&#xff0c; 需要迫切解决&#xff0c;以满足应用的要求[2]。 3D DRAM是指以垂直方向存储位的体系结构&#xff0c;类似于3D NAND[…

Python环境下一种改进小波分解方法-用于多分量信号的分解

小波通俗的讲就是一种振幅表现为在正负之间震荡的波形。小波变换在基于短时傅立叶变换的前提下&#xff0c;又加入了其所没有的可随频率变化的“时间-频率”窗口&#xff0c;其能对时间、频率进行局部化分析&#xff0c;并且对待处理信号通过多尺度处理使其表现为时-频细分的特…

【详细讲解MNN介绍,安装和编译】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

26. UE5 RPG同步面板属性(二)

在上一篇&#xff0c;我们解析了UI属性面板的实现步骤&#xff1a; 首先我们需要通过c去实现创建GameplayTag&#xff0c;这样可以在c和UE里同时获取到Tag创建一个DataAsset类&#xff0c;用于设置tag对应的属性和显示内容创建AttributeMenuWidgetController实现对应逻辑 并且…

【C++STL详解(二)】——string类模拟实现

目录 前言 一、接口总览 二、默认成员函数 1.构造函数 2.拷贝构造 写法一&#xff1a;传统写法 写法二&#xff1a;现代写法&#xff08;复用构造函数&#xff09; 3.赋值构造 写法一&#xff1a;传统写法 写法二&#xff1a;现代写法(复用拷贝构造) 4.析构函数 三、…

Linu修改端口号和密码

Linu修改端口号和密码 修改端口号 vim /etc/my.cnf 在数据库外修改密码 mysqladmin -u root -p旧密码 password 新密码&#xff1b; mysqladmin -u用户名 -p旧密码 password 新密码 数据库内修改密码 新建用户设置密码 create user root‘localhost或者%’ identified by ‘密…

Linux安装python3

Linux安装python3 本文章中使用的安装包等相关文件&#xff1a; 链接: https://pan.baidu.com/s/1C4PTB6IqXtHM6XSOEMkefg 提取码: wyeq 1.编译环境安装 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc mak…

【Linux】图文详解Xshell远程连接服务器:以Amazon EC2 VPS为例

文章目录 问题描述解决方案Q&A 问题描述 本地cmd或powershell使用ssh -i “your.pem” user_nameip_address是可以登录Amazon EC2云服务器的。 然而&#xff0c;当使用XShell以SSH加载PEM文件方式登录亚马逊EC2云服务器&#xff0c;一直出现输入密码的问题&#xff0c;如…

0101模板生成任务与shell命令执行任务-datax-python工具

文章目录 一、前言二、分析2.1 mysql工具2.2 模板2.2 执行shell命令 三、代码实现四、演示五、待优化结语 一、前言 最近在学习数仓相关内容&#xff0c;需要把mysql业务数据库gmall中的数据全量同步到hdfs中。使用的工具是datax&#xff0c;虽然datax可以在一个job内放置多个…

【实现报告】学生信息管理系统(链表实现)

目录 实验一 线性表的基本操作 一、实验目的 二、实验内容 三、实验提示 四、实验要求 五、实验代码如下&#xff1a; &#xff08;一&#xff09;链表的构建及初始化 学生信息结构体定义 定义元素类型 链表节点结构体定义 初始化链表 &#xff08;二&#xff09;…

C++编译过程

C编译过程分为四个步骤&#xff1a;分别是预处理(Prepressing) 、编译(Compilation) 、汇编(Assembly) 和链接(Linking)&#xff0c;如下图所示&#xff1a; 假如一个文件名为hello.cpp 预编译后的文件 1、预编译 将源代码文件hello.cpp和源文件中使用到的头文件&#xff0c…

WEB自动化测试,一定得掌握的8个核心知识点

写在前面 使用 cypress 进行端对端测试&#xff0c;和其他的一些框架有一个显著不同的地方&#xff0c;它使用 JavaScript 作为编程语言。 传统主流的 selenium 框架是支持多语言的&#xff0c;大多数 QA 会的 python 和 Java 语言都可以编写 selenium 代码&#xff0c;遇到需…

Adaboost集成学习 | Matlab实现基于RF-Adaboost随机森林结合Adaboost集成学习时间序列预测

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 Matlab实现基于RF-Adaboost随机森林结合Adaboost集成学习时间序列预测。基于RF-Adaboost(随机森林结合Adaboost集成学习)的时间序列预测方法结合了随机森林在处理高维数据和复杂关系方面的优势,以及Adaboos…

vue源码解析—— watch/computed的实现逻辑和区别

watch 和 computed 是 Vue 中的两个重要的响应式属性&#xff0c;它们在实现机制和使用上存在一些区别。 watch&#xff1a;用于监听数据的变化&#xff0c;并在数据变化时执行回调函数。可以使用 deep 配置项来开启深度监听&#xff0c;监听数据的子属性变化。可以使用 immedi…

QT 最近使用的项目配置文件

目录 1 QT 最近使用的项目配置文件所在路径 2 QtCreator.ini 1 QT 最近使用的项目配置文件所在路径 C:\Users\your username\AppData\Roaming\QtProject QtCreator.ini最好先备份一份 2 QtCreator.ini ProjectExplorer 下面的 RecentProjects\FileNames RecentProjects\…

希尔排序

文章目录 前言一.直接插入排序(时间复杂度N^2)二.希尔排序时间复杂度 前言 今天我们来讲一下排序算法中的插入排序中的希尔排序,插入排序分为两种&#xff0c;一种是直接插入排序&#xff0c;另一种就是希尔排序 一.直接插入排序(时间复杂度N^2) 我们这个排序&#xff0c;我们…

Day26 手撕各种集合底层源码(一)

Day26 手撕各种集合底层源码&#xff08;一&#xff09; 一、手撕ArrayList底层源码 1、概念&#xff1a; ArrayList的底层实现是基于数组的动态扩容结构。 2、思路&#xff1a; 1.研究继承关系 2.研究属性 3.理解创建集合的过程 – 构造方法的底层原理 4.研究添加元素的过程…

微机原理-基于8086倒计时多路抢答器系统

**单片机设计介绍&#xff0c;微机原理-基于8086倒计时多路抢答器系统 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 微机原理-基于8086倒计时多路抢答器系统概要主要关注于利用8086微处理器设计和实现一个具有倒计时功能的多路抢答器系统…