栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现的小迷宫

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现的小迷宫

数据结构课程写的迷宫

以前把代码上传过,通过上传资源,后来才发现上传的资源CSDN收费下载……
现在放到文章里
去年,2020年写的代码
记忆中,accessMazePrime和move函数是在网上搜的代码

生成随机迷宫,设置迷宫难度,Prim算法查找迷宫出口,用户自己走迷宫这几个功能。

#include 
#include 
#include 	// 用来定位,刷新指定位置 局部刷新 

#define random(x) (rand()%x)                                        // 生成不重复的随机数 

int ** initMaze(int row, int column);	//优雅                      // 分配地址,初始化迷宫 
void accessMazePrime(int row, int column, int **maze);              // 生成随机迷宫 
void printMaze(int row, int column, int **maze);                    // 打印整个迷宫,局部刷新前调用用来初始化 
void freeMaze(int **maze, int row);                                 // 释放二维迷宫数组空间 
void move(int row, int column, int **maze);	//迷宫移动              // 用户控制迷宫移动 wasd 
void showMain();                                                    // 显示主函数界面 
int ** initVisited(int **visited, int row, int column);             // 初始化一个二维数组,元素值为0或1,标记是否访问过该结点 
void pathFind(int **visited, int **maze, int x, int y, int *DA_x, int *SW_y, int row, int column, int *pFindExitFlag); // 查找迷宫路径,寻找出口 
int selectOption(int smaller, int bigger);                          // 两个参数表示范围,要求:smaller < 返回值 < bigger
void mazeGameDescription();                                         // 游戏说明 
void mazeGame();                                                    // 系统创建迷宫,集成了初始化迷宫,生成迷宫,寻找迷宫出口等功能,在主函数中调用 
int selectSize();                                                   // 选择迷宫尺寸 -- 难度 
void showSelectSizeMenu();                                          // 显示难度菜单 
void showUserOrSystemPathFindMenu();                                // 显示开始游戏的方式,计算机进行游戏,用户进行游戏,在选定难度之后调用 
void systemFindMazeExit(int row, int column, int **maze);           // 计算机查找迷宫出口 
void setMazeBeginAndEnd(int row, int column, int **maze);           // 设置迷宫的起点和终点 
void gotoxy(int x, int y);                                          // 定位指定位置,坐标从(0,0)开始 
void putcharMaze (int mazeNum);                                     // 根据二位数组元素的值打印指定的字符 
void gotoxyAndPutchar (int x, int y, int **maze);                   // 定位指定的坐标(x,y),并根据maze[y][x]的值打印指定的字符,用于局部刷新,gotoxy()和putcharMaze()的集成 
// 猜测不malloc,地址不变   
// malloc 本质上是重新分配了地址空间,所以指针变量指向的地址空间会改变,所以要return 地址给指针变量
// 而其他情况,例如对分配好地址空间的变量,用指针在函数之间传递,改变指针指向的变量的值,其地址不变,不需要return返回变量地址,因为地址并没有改变
// 对指针在函数间传递有了更深的理解,不再是简单的 传递指针,修改变量的值,指针指向的变量不变,有了更深层次的理解,又回归了概念。收获满满。 
int main(void)
{
	int option;                                 // 选项 
	while (1) {
		showMain();                             // 调用主函数菜单 
		option = selectOption(0,2);             // 获取用户选择 
		switch (option) {
			case 1:mazeGame();break;    // 迷宫游戏 
			case 2:mazeGameDescription();break; // 游戏说明 
			case 0:return 0;                    // 退出程序 
			default:; 
		}
		printf("按任意键继续");
		getch();
	}
}

void gotoxyAndPutchar (int x, int y, int **maze)
{   // 局部刷新 
	gotoxy(x,y);               // 调用函数定位,坐标为(x,y),(0,0)开始 
	putcharMaze(maze[y][x]);   // 根据(x,y)位置对应的maze[y][x]值,输出对应的字符 
}

void gotoxy(int x, int y)
{
    //COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标
    COORD cor;
    //句柄 
    HANDLE hout;

    //设定我们要定位到的坐标 
    cor.X = x;
    cor.Y = y;
    //GetStdHandle函数获取一个指向特定标准设备的句柄,包括标准输入,标准输出和标准错误。
    //STD_OUTPUT_HANDLE正是代表标准输出(也就是显示屏)的宏 
    hout = GetStdHandle(STD_OUTPUT_HANDLE);
    //SetConsoleCursorPosition函数用于设置控制台光标的位置
    SetConsoleCursorPosition(hout, cor);
}

void mazeGame()
{
	int size;                                                       // 迷宫尺寸 迷宫难度 
	int endFlag = 0;
	while (1) {
		showSelectSizeMenu();
		size = selectSize();
		if (size != 0) {                                            // 判断是否进行游戏,是,选择难度;否,返回主菜单 
			int row, column;
			int **maze;
			int option;
			switch(size){                                           // 设置迷宫的尺寸 --难度 
				case 1: row=10;column=20;break;
				case 2: row=15;column=30;break;
				case 3: row=20;column=40;break;
			}
		    maze = initMaze(row, column);                           // 分配地址,迷宫数组初始化 
		    accessMazePrime(row, column, maze);                     // 随机生成迷宫 
		    setMazeBeginAndEnd(row, column, maze);                  // 设置迷宫起点和终点 
		    showUserOrSystemPathFindMenu();                         // 显示菜单 
			option = selectOption(0,3);
		    switch(option) {
		    	case 1:move(row, column, maze);break;               // 用户操作闯关 
		    	case 2:systemFindMazeExit(row, column, maze);break; // 计算机查找迷宫路径 
		    	case 3:break;	                                    // 返回上一级菜单 
		    	case 0:endFlag=1;break;                             // 返回主菜单 
		    	default :;
			}
		    freeMaze(maze, row);                                    // 释放资源 
		    if (endFlag == 1) {                                     // 返回主菜单 
		    	break;
			}
		} else {                                                    // 返回主菜单 
			break;
		}
	}
}

void setMazeBeginAndEnd(int row, int column, int **maze)
{
	maze[1][1]=3;               // 设置起点 
    maze[row*2-1][column*2]=0;  // 设置终点
}

void showUserOrSystemPathFindMenu()
{   
	int i; 
	printf("n     -- 1. 开始游戏  2. 计算机寻找迷宫出口  3. 返回上一级  0. 返回主菜单 --n"); 
	for (i=0; i<80; i++)
	{
		printf ("-");
	}
	printf("n");
}

void systemFindMazeExit(int row, int column, int **maze)
{
    int SW_y[] = { 0, 1, 0, -1 };                                           // 该数组定义四个元素,分别对应 右、下、左、上四个方向。例如向下移动,则y+SW_y[1]。 
    int DA_x[] = { 1, 0, -1, 0 };                                           // 该数组同上一个数组类似,x+DA_x[i] 
    int **visited;															// 指针,一个二维数组的指针,用于标记结点是否访问过,访问为1,未访问为0 
    int findExitFlag = 0;                                                   // 标记是否找到迷宫出口,找到为1 
    int *pFindExitFlag = &findExitFlag;                                     // 指针指向findExitFlag,确保参数传递时可以修改值 
	visited = initVisited(visited, row, column);                            // 初始化visited数组,赋地址 
	// 初始化迷宫 
	system("cls");
	printMaze(row,column,maze);
	pathFind(visited, maze, 1, 1, DA_x, SW_y, row, column, pFindExitFlag);	// 递归,计算机递归的查找迷宫出口 
	
	freeMaze(visited, row);                                                 // 释放 
}

int selectSize()
{   // 选择难度 
	int size;
	size = selectOption(0,3);
	return size;
}
void showSelectSizeMenu()
{
	int i;
    printf ("nttt  -- 迷  宫  难  度  选  择 --nn");
	printf("n");
	printf("tt      -- 1.初级  2.中级  3.高级  0.退出 -- n");
	for (i=0; i<80; i++)
	{
		printf ("-");
	}
	printf("n");
}

void mazeGameDescription()
{
    printf("nttt -- 迷 宫 游 戏 说 明 --n");
    printf("t--操作说明:请切换为英文输入法,按w(上↑),a(左←),s(下↓),d(右→)移动n");
    printf("t--开始高级迷宫时,建议全屏开始游戏nn");
}

int ** initVisited(int **visited, int row, int column)
{   // 分配地址空间,初始化 
	int i, j;
	int r=row*2+1, c=column*2+1;
	visited = (int**)malloc(r*sizeof(int*));      // 存行地址 
 	for(i=0; i -1 && move_x > -1 && move_x < row && move_y < column && repos >= 0 && repos < count && noacc[repos] != 0)
            {
                noacc[repos] = 0;		 // 访问过结点,在未访问结点中取出
                acc[++accsize] = repos;	 // 第二个结点,新的结点,迷宫路径  添加结点到已访问队列
                pos = repos;			 // pos指向新的结点
                offpos = point;			 // 偏移量
                //相邻的格子中间的位置放1 
                maze[2 * x + 1 + offR[point]][ 2 * y + 1 + offC[point]] = 0;	//将新结点对应的迷宫位置的墙破开,因为初始化时奇数位LabId[奇数][奇数]=0,是路径,没有墙,起点不是墙,上下左右偏移一位都会是墙
                break;

            }
            else
            {
                if (accsize == count - 1)// 是否到达最大的路径结点数,是就结束,不是就进行下一次循环
					return ;	         // 此处也不需要返回指针值了,因为指针指向的变量地址没有改变,函数改成void即可 
                continue;
            }

        }

        if (offpos < 0)	// 四个方向都已经访问过一次或是边界,找不到路
        {// 周边没有找到能走的路了   从走过的路里重新找个起点 
            pos = acc[random(accsize + 1)];
        }
	}
}

int **initMaze(int row, int column)
{
    int r = 2 * row + 1, c = 2 * column + 1;
 	int i, j;
 	int **maze;
	maze = (int**)malloc(r*sizeof(int*));
 	for(i=0; ibigger)		// 当输入的选择不在smaller到bigger时,重新选择 
	{
		printf ("该选项不存在,请重新输入:");
		scanf ("%d", &option);					//输入选项 
		getchar();
	}
	
	return option;
}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/588628.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号