1. 程式人生 > >自動尋找走出迷宮的最短路徑

自動尋找走出迷宮的最短路徑

演算法心得:

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");
}