本来是想用esayx写的 发现好像用不着,直接改的窗口背景颜色做的,后来还改进了鼠标绘制地图 ,地图大小可以设置,寻路的过程也可以设置放慢的速度,作为大一的一个实践小项目,第一次发csdn,和大家一起分享。

#include<cstdio>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>#define RED  1
#define YELLOW  21
#define HYELLOW 22
#define GREEN   3
#define HGREEN  32
#define BLUE    4
#define PURPLE  5
#define GRAY    6
#define BLACK   7
#define WHITE   8#define START  1
#define END     -2
#define WALL    -1
#define WAY     0 #define YES       1
#define NO      0
#define SLEEPTIME 0
struct Size{//尺寸 int width;int height;
};
struct MazeMap{//地图 Size size;short** EachLine;//该数组存放每一行的头指针
};
struct NodeIndex{//作为坐标标记出入队列 int X;int Y;NodeIndex* nextnode;
};
struct Queue{//链队列 NodeIndex* head;NodeIndex* tail;int num;
};
void InitDataQueue(Queue &indexqueue){//初始化队列 indexqueue.head = NULL;indexqueue.tail = NULL;indexqueue.num = 0;
}
NodeIndex OutputData(Queue &indexqueue){NodeIndex nodeindex;NodeIndex* p;nodeindex.nextnode = NULL;nodeindex.X = -1;nodeindex.Y = -1;if(indexqueue.num == 0){return nodeindex;}nodeindex = *indexqueue.head;p = indexqueue.head->nextnode;free(indexqueue.head);indexqueue.head = p;indexqueue.num--;return nodeindex;
}
void InputData(Queue &indexqueue,NodeIndex nodeindex){//尾插法直接数据入队 NodeIndex* p;p = (NodeIndex*)malloc(sizeof(NodeIndex));if(p == NULL){printf("系统忙,无法运行\n"); exit(-1);}*p = nodeindex;p->nextnode = NULL;if(indexqueue.num == 0){indexqueue.tail = p;indexqueue.head = indexqueue.tail;}else{indexqueue.tail->nextnode = p;indexqueue.tail = p;}indexqueue.num++;
}
void InitMazeMap(MazeMap &mazemap,Size size){//初始化地图数据 mazemap.size = size;mazemap.EachLine = (short**)malloc(sizeof(short*)*size.height);if(mazemap.EachLine == NULL){printf("系统忙,无法运行\n"); exit(-1);}short** p,start;p = mazemap.EachLine; for(int i=0;i<size.height;i++){*p = (short*)malloc(sizeof(short)*size.width);if(p == NULL){printf("系统忙,无法运行\n"); exit(-1);}p++;}short* to_p;p = mazemap.EachLine;to_p = *p;for(int i=0;i<size.height;i++){for(int j=0;j<size.width;j++){if(i==0 || i==size.height-1 ||j==0 || j==size.width-1){*to_p = WALL;}else{*to_p = WAY;   }//printf("%d ",*to_p);//调试用于查看数据和数据内存地址 to_p++;}//printf("\n");p++;to_p = *p;}
}
void GoTo_XY(int x,int y){//移动光标的函数 HANDLE handle_out;handle_out = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = {x*2,y};SetConsoleCursorPosition(handle_out,pos);
}
void Color(int color,HANDLE handle_out){//切换颜色函数 switch (color){case RED:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_INTENSITY ); break;}case GREEN:{SetConsoleTextAttribute(handle_out,BACKGROUND_GREEN); break;}case HGREEN:{SetConsoleTextAttribute(handle_out,BACKGROUND_GREEN|BACKGROUND_INTENSITY); break;}case BLUE:{SetConsoleTextAttribute(handle_out,BACKGROUND_BLUE); break;}case GRAY:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE);break;}case PURPLE:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_BLUE);break;}case YELLOW:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_GREEN);break;}case HYELLOW:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_INTENSITY);break;}case BLACK:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|COMMON_LVB_REVERSE_VIDEO);break;}case WHITE:{SetConsoleTextAttribute(handle_out,BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY);break;}}
}
POINT GetPosition(){//获取鼠标位置函数 POINT pxy ={0,0};LPPOINT pxyf = &pxy;GetCursorPos(pxyf);return pxy;
}
void SetTheWall(MazeMap &mazemap,Size size,HANDLE handle_out,POINT &start,POINT &end){int key = 0,Sset = 0,Eset = 0,statue = 1;int Rx = 0,Ry = 0;GoTo_XY(0,size.height+2);Color(WHITE,handle_out);printf("操作说明:                       \n");printf("1.按下空格的同时移动鼠标绘制地图 \n");printf("2.按下P键可以重新定位画笔位置    \n");printf("3.按下Enter键结束当前地图绘制    \n");printf("4.按下S键设置鼠标当前位置为起点  \n"); printf("5.按下E键设置鼠标当前位置为终点  \n"); POINT pxy ={0,0};GoTo_XY(0,0);Color(WHITE,handle_out);printf("[]<——将鼠标放到框内,双击键盘P键定位鼠标"); fflush(stdin);while(_getch() != 112){GoTo_XY(0,0);printf("[]<——放到这里哦,双击P键定位鼠标               "); }while(statue){key = _getch();pxy = GetPosition();switch (key){case 32:{//绘制墙体pxy.x = (pxy.x-Rx)/16;pxy.y = (pxy.y-Ry)/16;if(pxy.x<size.width && pxy.y<size.height){GoTo_XY(pxy.x,pxy.y);mazemap.EachLine[pxy.y][pxy.x] = -1;printf("  ");}break;}case 114:{//擦除pxy.x = (pxy.x-Rx)/16;pxy.y = (pxy.y-Ry)/16;if(pxy.x>0 && pxy.x<size.width && pxy.y<size.height && pxy.y>0){if(mazemap.EachLine[pxy.y][pxy.x] == START){Sset = 0;}else if(mazemap.EachLine[pxy.y][pxy.x] == END){Eset = 0;}mazemap.EachLine[pxy.y][pxy.x] = 0;GoTo_XY(pxy.x,pxy.y);Color(GRAY,handle_out);printf("  ");Color(WHITE,handle_out);}break;}case 112:{//鼠标定位 Rx = pxy.x;Ry = pxy.y;break;}case 115:{//起点绘制 if(Sset == 1){break;}pxy.x = (pxy.x-Rx)/16;pxy.y = (pxy.y-Ry)/16;if(pxy.x<size.width && pxy.y<size.height){start.x = pxy.x;start.y = pxy.y;mazemap.EachLine[pxy.y][pxy.x] = START;Color(BLUE,handle_out);GoTo_XY(pxy.x,pxy.y);printf(" S");Color(WHITE,handle_out);Sset = 1;}break;}case 101:{//终点绘制 if(Eset == 1){break;}pxy.x = (pxy.x-Rx)/16;pxy.y = (pxy.y-Ry)/16;if(pxy.x<size.width && pxy.y<size.height){end.x = pxy.x;end.y = pxy.y;mazemap.EachLine[pxy.y][pxy.x] = END;Color(YELLOW,handle_out);GoTo_XY(pxy.x,pxy.y);printf(" E");Color(WHITE,handle_out);Eset = 1;}break;}case 13:{if(Sset && Eset){statue = 0;}else{Color(WHITE,handle_out);GoTo_XY(0,0);printf("请设置起点终点!");Color(WHITE,handle_out);_getch(); }break;}} GoTo_XY(0,0);printf("[]当前位置:X:%d Y:%d key:%d(画笔不准可放到左边方框重定位)         ",pxy.x,pxy.y,key);}
}void PrintMap(MazeMap mazemap,HANDLE handle_out){//显示地图函数 Size size = mazemap.size;short** p;short* to_p;p = mazemap.EachLine;to_p = *p;for(int i=0;i<size.height;i++){GoTo_XY(0,i);for(int j=0;j<size.width;j++){if(*to_p == WAY){Color(GRAY,handle_out); printf("  ");}else{Color(WHITE,handle_out); printf("  ");}to_p++;}p++;to_p = *p;}
}
void HideCursor(){//隐藏光标 CONSOLE_CURSOR_INFO cursor_info = {1,0};//第二个值为零隐藏SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
void SetHandle(HANDLE &handle_out,HANDLE &handle_in,Size size){//获取并设置窗口句柄 handle_out = GetStdHandle(STD_OUTPUT_HANDLE);//获得标准输出设备句柄handle_in = GetStdHandle(STD_INPUT_HANDLE);SMALL_RECT rc = {1,1,size.width*2,size.height+5};//设置窗口位置和大小 SetConsoleWindowInfo(handle_out,true,&rc);  //设置窗口信息,第二个参数为设置参数是否执行
}
void SetStartEnd(MazeMap &mazemap,POINT start,POINT end,HANDLE &handle_out){//设置出发点和终点 mazemap.EachLine[start.y][start.x] = START;Color(BLUE,handle_out);GoTo_XY(start.x,start.y);printf("S ");mazemap.EachLine[end.y][end.x] = END;Color(YELLOW,handle_out);GoTo_XY(end.x,end.y);printf("E ");
}
int SrcMethod(MazeMap &mazemap,NodeIndex nodeindex,Queue &indexqueue,int drie){//找路的方法 int nodevalue = 0;                      //Bug(1) [&]NodeIndex fblr[4] = {{0,1},{-1,0},{1,0},{0,-1}}; //分别对应上下左右 if(mazemap.EachLine[nodeindex.Y+(fblr[drie].Y)][nodeindex.X+(fblr[drie].X)] == END){return YES; }if(mazemap.EachLine[nodeindex.Y+(fblr[drie].Y)][nodeindex.X+(fblr[drie].X)] == WAY ){mazemap.EachLine[nodeindex.Y+(fblr[drie].Y)][nodeindex.X+(fblr[drie].X)] = mazemap.EachLine[nodeindex.Y][nodeindex.X]+1;nodeindex.X = nodeindex.X+(fblr[drie].X);nodeindex.Y = nodeindex.Y+(fblr[drie].Y);GoTo_XY(nodeindex.X,nodeindex.Y);printf("  ");InputData(indexqueue,nodeindex);Sleep(SLEEPTIME);}return NO;
}
int FindThePeth(MazeMap mazemap,NodeIndex &endindex,NodeIndex &startindex,HANDLE &handle_out){int value[4] = {0};int i ,min,mark = 0;while(true){i=0;//(bug_2)注意每次归零,否则有情况不可达 value[0] = mazemap.EachLine[endindex.Y][endindex.X+1];//Rvalue[1] = mazemap.EachLine[endindex.Y][endindex.X-1];//Lvalue[2] = mazemap.EachLine[endindex.Y+1][endindex.X];//Fvalue[3] = mazemap.EachLine[endindex.Y-1][endindex.X];//Bwhile(value[i]<=0){//既然能够到达,必然有一个可走的(值大于0的点) i++;}mark = i;min = value[i];for(i=0;i<4;i++){if(value[i] >0 && value[i]<min){mark = i;min = value[i];}}switch(mark){case 0:{endindex.X = endindex.X+1;break;}case 1:{endindex.X = endindex.X-1;break;}case 2:{endindex.Y = endindex.Y+1;break;}case 3:{endindex.Y = endindex.Y-1;break;}}if(endindex.X == startindex.X && endindex.Y == startindex.Y){return YES;}GoTo_XY(endindex.X,endindex.Y);Color(RED,handle_out);printf("  ");Sleep(SLEEPTIME);}
}
void DrawMap(MazeMap &mazemap){//测试用地图绘制 }
int main(){HANDLE handle_out,handle_in;MazeMap mazemap;Queue indexqueue; Size map_size; printf("请输入要生成的地图尺寸:\n");printf("宽度(10--50较为适宜):");scanf("%d",&map_size.width); while(map_size.width<10 || map_size.width>50){printf("输入数据超出限制,请重新输入");scanf("%d",&map_size.width); } printf("高度度(10--50较为适宜):");scanf("%d",&map_size.height ); while(map_size.height<10 || map_size.height>50){printf("输入数据超出限制,请重新输入");scanf("%d",&map_size.height); }POINT start = {0,0};POINT end = {0,0}; int srcstatue = NO,nodevalue = 0;SetHandle(handle_out,handle_in,map_size);HideCursor();InitMazeMap(mazemap,map_size);//初始化操作 InitDataQueue(indexqueue);for(int i=0;i<map_size.height+2;i++){//输出字符固定布局位置,否则拖动窗口大小会被刷新排版 GoTo_XY(map_size.width,i);Color(BLACK,handle_out);printf("|");}PrintMap(mazemap,handle_out);SetTheWall(mazemap,map_size,handle_out,start,end);NodeIndex nodeindex,startindex,endindex;nodeindex.X = start.x;nodeindex.Y = start.y; startindex.X = nodeindex.X;startindex.Y = nodeindex.Y;endindex.X = end.x;endindex.Y = end.y;InputData(indexqueue,nodeindex);while(indexqueue.num != 0){nodeindex = OutputData(indexqueue);if(nodeindex.X != start.x || nodeindex.Y != start.y){Color(HYELLOW,handle_out);GoTo_XY(nodeindex.X,nodeindex.Y);printf("  ");Color(HGREEN,handle_out); }if(SrcMethod(mazemap,nodeindex,indexqueue,0) == YES ){srcstatue = YES;break;}if(SrcMethod(mazemap,nodeindex,indexqueue,3) == YES ){srcstatue = YES;break;}if(SrcMethod(mazemap,nodeindex,indexqueue,2) == YES ){srcstatue = YES;break;}if(SrcMethod(mazemap,nodeindex,indexqueue,1) == YES ){srcstatue = YES;break;}GoTo_XY(0,map_size.height);Color(GREEN,handle_out);printf("当前可走节点个数:%d      ",indexqueue.num);}if(srcstatue==YES){FindThePeth(mazemap,endindex,startindex,handle_out);GoTo_XY(0,map_size.height+1);printf("路径已找到           ");}else{GoTo_XY(0,map_size.height+1);printf("出口不可达         ");} /*for(int i=0;i<map_size.height;i++){for(int j=0;j<map_size.width;j++){printf("%2d ",mazemap.EachLine[i][j]);//调试用于查看数据和数据内存地址 }printf("\n");}*/GoTo_XY(0,map_size.height+5);//运行结束以后恢复位置以及背景 Color(BLACK,handle_out);CloseHandle(handle_in);CloseHandle(handle_out); return 0;
}

C语言 迷宫问题 (广度优先算法)相关推荐

  1. c语言bfs算法走迷宫,使用广度优先算法(BFS)走迷宫

    前面介绍广度优先算法的时候提及了多次走迷宫,我们就真正的走一次迷宫试试! 要求如下: 输入给出迷宫矩阵的行数和列数,并给出迷宫(使用点 (.) 表示路,使用星 (*) 表示障碍物,使用S表示起点,T表 ...

  2. c语言 迷宫深度遍历 算法,图的遍历迷宫生成算法浅析

    1. 引言 在平常的游戏中,我们常常会碰到随机生成的地图.这里我们就来看看一个简单的随机迷宫是如何生成. 2. 迷宫描述随机生成一个m * n的迷宫,可用一个矩阵maze[m][n]来表示,如图:   ...

  3. Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS、深度优先DFS,最短路径SPF、带负权的最短路径Bellman-ford、拓扑排序)

    Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS.深度优先DFS,最短路径SPF.带负权的最短路径Bellman-ford.拓扑排序) 目录 一.图的搜索 1.BFS (Brea ...

  4. 刷题 BFS 广度优先算法 : 大胖子走迷宫 (python, java)

    刷题 BFS 广度优先算法 : 大胖子走迷宫 (python, java) https://www.lanqiao.cn/problems/234/learning/ http://lx.lanqia ...

  5. 利用广度优先和深度优先算法解决迷宫问题【算法设计与分析】<图搜索问题>

    实验问题: 给定一个n*n的迷宫,要求利用广度优先和深度优先算法解决迷宫问题 问题分析: 对于此问题首先要明确搜索顺序 可以分为两种方法求解问题:1.广度优先算法2.深度优先算法 (1)对于深度优先算 ...

  6. C语言老鼠走迷宫(单路径)算法详细讲解

    最近在学习C语言的一些经典算法,其中遇到了一点困难,导致卡进度了.琢磨了很久,在绘制流程图时,突然灵感大开理解了,老鼠走迷宫算法的奇妙.所以写了这个,一来是方便以后右和我类似的同学自学时,遇到这个问题 ...

  7. 猎人抓兔子 - (广度优先算法)

    题目描述: 假设有一只兔子,有4个排成一排的洞,编号为1和4.兔子每天晚上跳到相邻的一个洞里住,2号洞可以跳1号和3号洞,4号洞只能跳3号洞.而猎人每天白天检查其中的一个洞.猎人告诉你每天检查的洞的编 ...

  8. 13:Scala语言的数据结构和算法

    第十九章 Scala语言的数据结构和算法 19.1 数据结构(算法)的介绍 数据结构的介绍   1.数据结构是一门研究算法的学科,只从有了编程语言也就有了数据结构.学好数据结构可以编写出更加漂亮.更加 ...

  9. 大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作

    大数据技术之_16_Scala学习_13 第十九章 Scala语言的数据结构和算法 19.1 数据结构(算法)的介绍 19.2 看几个实际编程中遇到的问题 19.2.1 一个五子棋程序 19.2.2 ...

  10. 一笔画完C语言程序寻找路径算法

    过年这几天疫情严重,哈哈,想必各位在家也是闲得慌. 于是,玩了一款叫 "一笔画完" 的游戏打发时间,要求从起点一笔连接所有格子,不能重复,不能空格. 有些关卡还真是意想不到,于是想 ...

最新文章

  1. 配置Keil C51配置开发 STC51单片机过程
  2. golangsha1解码_golang中几种加密方式的处理
  3. Linuc C 编程实例1
  4. 据说这是史上最牛逼的可视化神器
  5. [python3.3]Python异步Socket编程【TCP】
  6. idea中代码能够运行,但是显示类找不到
  7. efcore 实体配置_创建并配置模型
  8. 【Elasticsearch】需要监控的 10 大 Elasticsearch 指标
  9. 高级Blazor:从Edge共享程序集和调试
  10. ZooKeeper 了解
  11. android 富文本编辑器_富文本编辑器,还是Tinymce好一点?Angular/Vue集成最新版
  12. 进入android数据可视化,Android中的实时数据可视化
  13. 顶级数据团队建设全景报告_从蚂蚁金服的BI和大数据团队建设,看透BI发展,再不懂就落伍了...
  14. html继承有哪几种方式,JS实现继承的几种常用方式示例
  15. ps 毛发 边缘,抠图技巧,抠图后头发边缘的颜色怎处理
  16. 中信银行总行信息科技部的面试(校招)
  17. 常见机器视觉软件OpenCV/Halcon/VisionPro/MIL的区别
  18. 夏季繁华系列||妆面照欣赏
  19. DCC - Photoshop - Nvidia NormalMapFilter - 法线生成工具 - 顺便测试 Unity URP 12.1 中的 Decal System
  20. 转载:Ceph论文译文

热门文章

  1. 【JS】每日一题:模块化
  2. 关于个人网贷查询系统网贷信用查询,公司开发图片整合技术
  3. 数据库事务ACID四大特性:原子性、一致性, 隔离性, 持久性
  4. 1034-乘积小于 K 的子数组
  5. SpringCloud(part10)Spring Data 与JPA,MongoDB,Redis
  6. 图片标注软件labelImg使用指南
  7. 机器学习中的概率分布
  8. vue中你真的理解v-modle基础理解和使用吗?
  9. 餐厅点菜c语言程序代码,C语言编程——餐馆点菜
  10. 海洋cms宝塔定时linux,海洋cms设置宝塔自动采集教程