迷宫c语言
更新时间:2024-05-30 18:38:01 阅读量: 综合文库 文档下载
迷宫c语言
#include <stdio.h> #include <conio.h> #include <windows.h> #include <time.h>
#define Height 31 //迷宫的高度,必须为奇数 #define Width 25 //迷宫的宽度,必须为奇数 #define Wall 1 #define Road 0 #define Start 2 #define End 3 #define Esc 5 #define Up 1 #define Down 2 #define Left 3 #define Right 4
int map[Height+2][Width+2]; void gotoxy(int x,int y) //移动坐标 {
COORD coord; coord.X=x; coord.Y=y;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord ); }
void hidden()//隐藏光标 {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci); cci.bVisible=0;//赋1为显示,赋0为隐藏 SetConsoleCursorInfo(hOut,&cci); }
void create(int x,int y) //随机生成迷宫 {
int c[4][2]={0,1,1,0,0,-1,-1,0}; //四个方向 int i,j,t; //将方向打乱 for(i=0;i<4;i++) {
j=rand()%4;
t=c[i][0];c[i][0]=c[j][0];c[j][0]=t; t=c[i][1];c[i][1]=c[j][1];c[j][1]=t; }
map[x][y]=Road; for(i=0;i<4;i++)
if(map[x+2*c[i][0]][y+2*c[i][1]]==Wall) {
map[x+c[i][0]][y+c[i][1]]=Road; create(x+2*c[i][0],y+2*c[i][1]); } }
int get_key() //接收按键 { char c; while(c=getch()) {
if(c==27) return Esc; //Esc if(c!=-32)continue; c=getch();
if(c==72) return Up; //上 if(c==80) return Down; //下 if(c==75) return Left; //左
if(c==77) return Right; //右 } return 0; }
void paint(int x,int y) //画迷宫 {
gotoxy(2*y-2,x-1); switch(map[x][y]) { case Start:
printf("入");break; //画入口 case End:
printf("出");break; //画出口 case Wall:
printf("※");break; //画墙 case Road:
printf(" ");break; //画路 } }
void game() {
int x=2,y=1; //玩家当前位置,刚开始在入口处
int c; //用来接收按键 while(1) {
gotoxy(2*y-2,x-1);
printf("☆"); //画出玩家当前位置 if(map[x][y]==End) //判断是否到达出口 {
gotoxy(30,24);
printf("到达终点,按任意键结束"); getch(); break; }
c=get_key(); if(c==Esc) {
gotoxy(0,24); break; } switch(c) {
case Up: //向上走 if(map[x-1][y]!=Wall)
{ paint(x,y); x--; } break;
case Down: //向下走 if(map[x+1][y]!=Wall) { paint(x,y); x++; } break;
case Left: //向左走 if(map[x][y-1]!=Wall) { paint(x,y); y--; } break;
case Right: //向右走 if(map[x][y+1]!=Wall) {
paint(x,y); y++; } break; } } } int main() { int i,j;
srand((unsigned)time(NULL)); //初始化随即种子 hidden(); //隐藏光标 for(i=0;i<=Height+1;i++) for(j=0;j<=Width+1;j++)
if(i==0||i==Height+1||j==0||j==Width+1) //初始化迷宫 map[i][j]=Road; else map[i][j]=Wall;
create(2*(rand()%(Height/2)+1),2*(rand()%(Width/2)+1)); //从随机一个点开始生成迷宫,该点行列都为偶数 for(i=0;i<=Height+1;i++) //边界处理 {
map[i][0]=Wall; map[i][Width+1]=Wall; }
for(j=0;j<=Width+1;j++) //边界处理 {
map[0][j]=Wall; map[Height+1][j]=Wall; }
map[2][1]=Start; //给定入口 map[Height-1][Width]=End; //给定出
口 for(i=1;i<=Height;i++)
for(j=1;j<=Width;j++) //画出迷宫 paint(i,j);
game(); //开始游戏 getch(); return 0; }
首先,先挂上代码。然后说部分废话,读代码好处非常之多,提高技术,增加理解力,以及获得不同思路等。读代码甚至对比写代码来说,学习效率有过之而无不及.文章针对初级又在初级之上,没有一定的基础看不懂,有一定的基础就可以跟着这篇帖子,做出你自己的C语言随机迷宫,这里的做出并不是抄代码,而是变为你真正的知识,在没有参考的时候,也可以流畅的写出你的代码.
然后我们开始分析代码.. 先看头文件。
#include <stdio.h> //包涵标准输入输出函数
#include <conio.h> //控制台输入输出库,非标准库哦
#include <windows.h> //WINDOWS.H是主要的头文件,它包含了其他Windows头文件,这些头文件的某些也包含了其他头文件。 具体包涵了什么。。太多了 自行百度
#include <time.h> //包涵时间和日期处理函数
#define Height 21 //迷宫的高度,必须为奇数
#define Width 21 //迷宫的宽度,必须为奇数
#define Wall 1 //即字面意思 墙 #define Road 0 //即字面意思 路 #define Start 2 //入口 #define End 3 //终点 #define Esc 5 //退出
#define Up 1 //上,下,左,右 #define Down 2 #define Left 3 #define Right 4
这里为什么要用宏,什么情况下使用宏,可能要问为什么不直接用 12345来代替。简单的来说就是提供一个方便,并增加一定的效率。还有重要的一点就是增加代码的可读性。尽量避免用01234这样无意义的数字而使用宏定义能良好的提高开发效率,在小程序中可能不算什么,但是在大程序可就不一样了,然而宏定义也并非只能定义简单的1234 。
接下来我们看一共有几个函数
void gotoxy(int x,int y) //既字面含义 移动坐标 void create(int x,int y) //字面含义 创建迷宫
void hidden() //隐藏光标(注并非鼠标) int get_key() //得到按键 void paint(int x,int y) //绘制迷宫 void game() //游戏相关操作
先不要管main函数里的代码,我们先逐个分析一下函数
先来看看 gotoxy() 接受两个参数, 代码如下 void gotoxy(int x,int y) //移动坐标 {
COORD coord; coord.X=x; coord.Y=y;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord ); }
看到这里可能就有很多人蒙了 COORD是个什么东西? COORD实际上是一个结构体 包括结构体成员SHORT X,SHORT Y;
typedef struct COORD { SHORT X; SHORT Y;} COORD, *PCOORD;暂时先不管他是做什么的,先看看SetConsoleCursorPosition这个API的声明他接受两个参数,作用是定位光标位置,需要配合COORD 使用
BOOL WINAPI SetConsoleCursorPosition( __in HANDLE hConsoleOutput,
//句柄 就不介绍了 __in COORD dwCursorPosition // COORD原来是SetConsoleCursorP
osition的形参之一); GetStdHandle 声明如下:
HANDLE WINAPI GetStdHandle( //获得输入、输出/错误的屏幕缓冲区的句柄。 __in DWORD nStdHandle );
而其参数nStdHandle的值可以为下面几种类型的一种: STD_INPUT_HANDLE 标准输入的句柄 STD_OUTPUT_HANDLE 标准输出的句柄 STD_ERROR_HANDLE 标准错误的句柄 这么说出来其实也并非很容易理解,我们用一个小程序来举例
#include <stdio.h> #include <windows.h> int main(void) {
COORD cod; cod.X=5; cod.Y=4;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ),
cod ); }
编译一下程序,就能理解这两个函数是做什么的了 gotoxy() 就讲到这里 下面讲第二个函数 声明:void create(int x,int y) void create(int x,int y) //随机生成迷宫 {
int c[4][2]={0,1,1,0,0,-1,-1,0}; //四个方向 // 这里的四个方向 乃是0,1 1,0 0,-1 -1,0 代表着上下左右 int i,j,t; //将方向打乱 for(i=0;i<4;i++) {
j=rand()%4;
t=c[0];c[0]=c[j][0];c[j][0]=t; t=c[1];c[1]=c[j][1];c[j][1]=t; }
map[x][y]=Road; for(i=0;i<4;i++)
if(map[x+2*c[0]][y+2*c[1]]==Wall) //
{
map[x+c[0]][y+c[1]]=Road; create(x+2*c[0],y+2*c[1]); } }
这个函数中的算法根据源代码作者所说是从网上找的 .然后搜了搜.我去 略长,略长,转到论坛压力略大略大 还分别有不会离散数学的和使用深度优先遍历..两种版本,最主要的是带图了,推荐亲自前去观看吧http://wenku.http://www.wodefanwen.com//view/f22455126edb6f1aff001f13.html ,带上图理解比较容易..所以想要理解算法部分,还是看连接文章吧
然后我们接着说一下int get_key() 函数如下:
int get_key() //接收按键 { char c; while(c=getch()) {
if(c==27) return Esc; //Esc if(c!=-32)continue; c=getch();
if(c==72) return Up; //上
if(c==80) return Down; //下 if(c==75) return Left; //左 if(c==77) return Right; //右 } return 0; }
其实理解这个函数很容易 getch() 为无回显获取一个字符,什么叫无回显获取一个字符? 写一个小程序来测试一下 #include <conio.h> #include <stdio.h> int main() { char a; a=getch(); putch(a); }
可以发现只会进行输出,而输入时不会显示所输入字符。 可能会有人疑惑ESC的ASCII确实是27 可是其他的是什么呀?ASCII中是没有上下左右的值的,这里的值是键盘控制码,不是ASCII!注意了!关于获取某个按键的值可以用以下程序 #include <conio.h>
#include <stdio.h> int main() { int key; key = getch();
while( key != 27 ) //键入值不为 ESC {
printf("%d\\n", key); key = getch(); } }
继续看看 paint 函数 函数如下
void paint(int x,int y) //画迷宫 {
gotoxy(2*y-2,x-1); switch(map[x][y]) { case Start:
printf("入");break; //画入口
case End:
printf("出");break; //画出口 case Wall:
printf("※");break; //画墙 case Road:
printf(" ");break; //画路 } } 这
个函数实际上比较容易理解,他首先将光标指向入口,然后在main函数中遍历整个map数组,画出地图 。也可以不用 入 出 ※ 空格 这些来做地图 比如改一下
switch(map[x][y]) { case Start:
printf("1");break; //画入口 case End:
printf("2");break; //画出口
case Wall:
printf("3");break; //画墙 case Road:
printf("4");break; //画路 }
然后就应该能理解了这部分是怎么做到的
接下来我们看最后一个函数void game() //游戏相关操作
void game() {
int x=2,y=1; //玩家当前位置,刚开始在入口处 int c; //用来接收按键 while(1) {
gotoxy(2*y-2,x-1); //这里的含义是到达入口处 printf("☆"); //画出玩家当前位置 if(map[x][y]==End) //判断是否到达出口 {
gotoxy(30,24);
printf("到达终点,按任意键结束"); getch();
break; }
c=get_key(); if(c==Esc) {
gotoxy(0,24); break; } switch(c) {
case Up: //向上走 if(map[x-1][y]!=Wall) { paint(x,y); x--; } break;
case Down: //向下走 if(map[x+1][y]!=Wall) { paint(x,y); x++;
} break;
case Left: //向左走 if(map[x][y-1]!=Wall) { paint(x,y); y--; } break;
case Right: //向右走 if(map[x][y+1]!=Wall) { paint(x,y); y++; } break; } } }
事实上这个函数也不是很难理解 所有函数除了算法部分都不难理解,就看用不用心去读代码了
就像注释那样, gotoxy(2*y-2,x-1); 到达入口处 用☆当玩家,然后先
进行判断是否到达终点,如果达到终点或按ESC则结束游戏,负责就开始接受按键,进行移动,说是移动实际上就是不断变化 map[x][y] x和y的值 并进行判断是否到达终点,按下ESC如果没有则根据 x++ x-- y++ y-- 来进行上下左右后改变所在二维数组中的位置 打个比方 a[2][2]
分别有a[0][0]a[0][1] 11
a[1][0]a[1][1] 21 如果处在2的位置 那么按下上 也就是说数组元素a[1][0]变成了a[0][0] 如果用 这里用a[x][y]来进行表示,那么就是等于x--;其他同理
最后我们来看一下main函数 int main() { int i,j;
srand((unsigned)time(NULL)); //初始化随即种子 hidden(); //隐藏光标
for(i=0;i<=Height+1;i++) for(j=0;j<=Width+1;j++)
if(i==0||i==Height+1||j==0||j==Width+1) //初始化迷宫 map[j]=Road; else map[j]=Wall;
create(2*(rand()%(Height/2)+1),2*(rand()%(Width/2)+1)); //从随机一个点开始生成迷宫,该点行列都为偶数
for(i=0;i<=Height+1;i++) //边界处理 {
map[0]=Wall; map[Width+1]=Wall; }
for(j=0;j<=Width+1;j++) //边界处理 {
map[0][j]=Wall; map[Height+1][j]=Wall; }
map[2][1]=Start; //给定入口
map[Height-1][Width]=End; //给定出口
for(i=1;i<=Height;i++)
for(j=1;j<=Width;j++) //画出迷宫 paint(i,j);
game(); //开始游戏 getch(); return 0; }
先是srand来初始化随机种子 为create打下基础
然后给map赋值 输出后成四面全是墙,中间全是路的 也就是000 010 000
//0是墙,1是路 这样
然后用create生成正式的迷宫,根据rand来随机生成路线 之后重新处理边界,以及定义入口点和出口点 ,可以试着删掉 for(i=0;i<=Height+1;i++) //边界处理 {
map[0]=Wall; map[Width+1]=Wall;
}
for(j=0;j<=Width+1;j++) //边界处理 {
map[0][j]=Wall; map[Height+1][j]=Wall; }
这段 如果在入口处按左,你会发现BUG了!! 删掉这两段
map[2][1]=Start; //给定入口
map[Height-1][Width]=End; //给定出口 导致你一旦从入字走出,就再也走出不迷宫 最后使用print函数 根据数组元素的值 画出迷宫. 用game进行游戏循环并判断游戏是否结束
第一次写源码分析..蛋疼..尤其是发帖 发了N次 终于不知道为什么百度不和谐了
最后..我爱C语言 么么哒
正在阅读:
迷宫c语言05-30
高考语文作文典型素材集锦03-08
公文写作作文题04-09
传感器原理及应用课后习题答案(吴建平机械工业出版)01-26
幼儿园教学工作报告02-25
综合性学习 文学部落 学案12-23
我国生物医药产业园区发展现状及模式探讨05-31
愿望作文_愿望初二作文600字优秀8篇03-27
数学建模第二次作业(3)10-09
- 《江苏省环境水质(地表水)自动监测预警系统运行管理办法(试行)》
- 安乐死合法化辩论赛立论稿(浙大新生赛)
- 公共科目模拟试卷公务员考试资料
- 我国固定资产投资FAI对GDP的影响
- 大学生创新创业训练计划项目申请书大创项目申报表
- 完美版—单片机控制步进电机
- 2013资阳中考化学试题
- 18.两位数减一位数退位(397道)
- 工程量计算规则
- 二年级操行评语(下)
- 第3章 流程控制语句
- 浅基桥墩加固技术
- 课题研究的主要方法
- 5100软件说明书 - 图文
- 车间技术员年终总结
- 关于印发《中铁建工集团开展项目管理实验室活动方案》的通知
- 经典诵读结题报告
- 地下水动力学习题答案
- 2018年全国各地高考数学模拟试题平面解析几何试题汇编(含答案解
- 街道办事处主任2018年度述职述廉报告
- 迷宫
- 语言
- 2015-2020年中国壁纸墙布行业发展趋势及投资前景分析报告 - 图文
- 2016大学语文2
- 2015国家公务员考试申论考前必看10个结尾范例
- 关爱单亲家庭留守儿童
- 关于XXX公司货币资金管理的调研报告
- 浅谈“实施定点医疗保险”对军队医院经营面临的影响及对策
- 欢乐农家游 百分数(二)教案 - 图文
- 小学科学三年级下册各课知识点复习汇总
- 南漳县城市规划区房屋征收与补偿暂行办法
- 汽车厚板料零件冲压成形分析及回弹计算(中国一汽)
- 自学考试10月高财计算题及答案
- 双馈风机基础知识学习
- 崂山北九水植物生物学实习报告-4
- LCD的成像原理
- 告警和话统分析指引 - 图文
- 专题组织生活会查摆问题支部整改清单
- 司法实践中“黑社会性质组织”的认定标准20161010(1)
- (最新版)基于JAVA的游戏毕业设计论文
- 淮南艺考文化课补习班哪家好
- 物化题练习题