自动寻找走出迷宫的最短路径

算法心得:

1.利用广度优先遍历(bfs)实现寻找最短路径

2.利用树的思想,将每走一步的终点与它的起点相连接,这样就能在最后把整条最短路径找出来



#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define size 50
void set_map();
void print_map();
void set_startplace();
void set_endplace();
void color(const unsigned short color1);
//void change(int x, int y, int dir);
void gotoxy(int x, int y);
void bfs();
void dfs(int x, int y, int step);
void printline(int x, int y);
void move();
void print_sentence();
void print_loose();
char ch[size][2*size] = { ' ' };
int start_x, start_y;
int end_x, end_y;
int sx, sy;
int min = 9999;
int book[size*size*2][2];
int mark[size][2*size] = { 0 };
int i = 1;
//设置一个结构体,储存坐标
struct note
{
	int x;
	int y;
}que[size*size];
//储存坐标和连接指针
struct tree
{
	int x;
	int y;
	struct tree *next;
}*ans[size][2*size];
int main()
{
	set_map();
	print_map();
	set_startplace();
	set_endplace();
	system("cls");
	print_map();
	bfs();
	move();
	system("pause");
}
//设置地图
void set_map()
{
	int i = 1500, x, y;
	srand(time(0));
	while (i>0)
	{
		x = rand() % size;
		y = rand() % (2*size);
		ch[x][y] = 6;
		i--;
	}
}
//打印地图
void print_map()
{
	int i, j;
	for (i = 0;i < size;i++)
	{
		for (j = 0;j < 2*size;j++)
		{
			if (i == sx && j == sy)
			{
				color(12);
			}
			if (i == end_x && j == end_y)
			{
				color(12);
			}
			else
			{
				color(10);
			}
			printf("%c", ch[i][j]);
		}
		printf("\n");
	}
}
//设置起始位置
void set_startplace()
{
	color(6);
	printf("请输入起始位置\n");
	scanf_s("%d%d", &start_x, &start_y);
	ch[start_x][start_y] = 12;
	sx = start_x;
	sy = start_y;
}
//设置终点
void set_endplace()
{
	color(6);
	printf("请输入终点位置\n");
	scanf_s("%d%d", &end_x, &end_y);
	ch[end_x][end_y] = 3;
}
//控制命令台输出字体颜色函数
void color(const unsigned short color1)
{
	if (color1 >= 0 && color1 <= 15)
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color1);
	else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
//广度搜索和树的结合
void bfs()
{
	int next[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
	int head, tail;
	int k, flag = 0, tx, ty;
	head = 1;
	tail = 1;
	que[tail].x = start_x;
	que[tail].y = start_y;
	mark[start_x][start_y] = 1;
	ans[start_x][start_y] = (struct tree*)malloc(sizeof(struct tree));
	ans[start_x][start_y]->x = start_x;
	ans[start_x][start_y]->y = start_y;
	ans[start_x][start_y]->next = NULL;
	tail++;
	while (head < tail)
	{
		for (k = 0;k < 4;k++)
		{
			tx = que[head].x + next[k][0];
			ty = que[head].y + next[k][1];
			if (tx<0 || tx>size - 1 || ty <0 || ty > 2*size - 1)
			{
				continue;
			}
			if (ch[tx][ty] != 6 && ch[tx][ty] != 3 && mark[tx][ty] == 0)
			{
				que[tail].x = tx;
				que[tail].y = ty;
				mark[tx][ty] = 1;
				ans[tx][ty] = (struct tree*)malloc(sizeof(struct tree));
				ans[tx][ty]->x = tx;
				ans[tx][ty]->y = ty;
				ans[tx][ty]->next = ans[que[head].x][que[head].y];
				tail++;
			}
			if (tx == end_x && ty == end_y)
			{
				flag = 1;
				ans[tx][ty] = (struct tree*)malloc(sizeof(struct tree));
				ans[tx][ty]->x = tx;
				ans[tx][ty]->y = ty;
				ans[tx][ty]->next = ans[que[head].x][que[head].y];
				break;
			}
		}
		if (flag == 1)
		{
			printline(tx, ty);
			break;
		}
		head++;
	}
	if (flag == 0)
	{
		print_loose();
	}
}
//储存路线
void printline(int x, int y)
{
	struct tree *p;
	p = ans[x][y];
	while (p != NULL)
	{
		book[i][0] = p->x;
		book[i][1] = p->y;
		//printf("%d %d\n", p->x, p->y);
		p = p->next;
		i++;
	}
}
//移动函数
void move()
{
	char c = 12;
	//char m=7;
	int k;
	int num = 1;
	gotoxy(start_y, start_x);
	color(6);
	printf("*");
	gotoxy(book[i][1], book[i][0]);
	color(12);
	printf("%c", c);
	for (k = i;k >= 2;k--)
	{
		gotoxy(book[k][1], book[k][0]);
		color(6);
		printf("*");
		gotoxy(book[k - 1][1], book[k - 1][0]);
		color(12);
		printf("%c", c);
		gotoxy(size-2, size+1);
		printf("Coordinate(%d,%d)", book[k][0], book[k][1]);
		gotoxy(size - 2, size + 2);
		printf("Step number %d", num);
		num++;
		Sleep(200);
	}
	print_sentence();
}
//这是移动光标的函数
void gotoxy(int x, int y)
{
	COORD coord = { x, y };
	/*COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标。其定义为:

	typedef struct _COORD {

	SHORT X; // horizontal coordinate

	SHORT Y; // vertical coordinate
	} COORD;*/

	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//结束语
void print_sentence()
{
	int s;
	system("cls");
	color(12);
	gotoxy(size, size / 2);
	printf("恭喜你走出了迷宫\n");
	Sleep(2000);
	system("cls");
	gotoxy(size, size / 2);
	printf("你以为就这样结束了?");
	Sleep(2000);
	system("cls");
	gotoxy(size, size / 2);
	printf("接下来有请陆铭坤给我们演示我们的打地鼠小游戏!!");
	gotoxy(size, size);
}
void print_loose()
{
	/*
	int s;
	system("cls");
	color(12);
	for (s = 1;s<10;s++)
	{
		printf("\n");
	}
	for (s = 1;s<16;s++)
	{
		printf(" ");
	}
	*/
	system("cls");
	gotoxy(size, size / 2);
	printf("对不起,你这个迷宫打死我也走不出来!!\n");
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值