#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<graphics.h>//如果运行不了,看编译器是否安装Easyx库,如果没有安装可以去Easyx官网安装
typedef struct Queue
{
int *Buff;
int MAX;
int front;
int rear;
}Queue;
typedef struct Stack
{
int* Buff;
int Max;
int top;
}Stack;
typedef struct Aim
{
int x;
int y;
}Aim;
enum MyEnum
{
UP,
DOWN,
LEFT,
RIGHT,
UP_LEFT,
UP_RIGHT,
DOWN_LEFT,
DOWN_RIGHT
};
Queue *Init_Queue(int Max)
{
Queue* Temp = (Queue*)malloc(sizeof(Queue));
if (!Temp)
return NULL;
Temp->MAX = Max;
Temp->Buff = (int*)malloc(sizeof(int)*Max);
if (Temp->Buff == NULL)
{
free(Temp);
return NULL;
}
Temp->front = -1;
Temp->rear = -1;
return Temp;
}
Stack* Init_Stack(int Length)
{
Stack* Temp = (Stack*)malloc(sizeof(Stack));
if (Temp == NULL)
return NULL;
Temp->Buff = (int*)malloc(Length*sizeof(int));
if (Temp->Buff == NULL)
{
free(Temp);
return NULL;
}
Temp->Max = Length - 1;
Temp->top = -1;
}
bool Empty_Stack(Stack* Temp)
{
if (Temp->top == -1)
return false;
return true;
}
bool Push_Stack(Stack*Temp,int data)
{
if (Temp->top == Temp->Max)
return false;
Temp->top++;
Temp->Buff[Temp->top] = data;
return true;
}
bool Pop_Stack(Stack*Temp,int *data)
{
if (!Empty_Stack(Temp))
return false;
*data = Temp->Buff[Temp->top];
Temp->top--;
return true;
}
void Destroy_Stack(Stack*stack)
{
free(stack->Buff);
free(stack);
}
bool Empty_Queue(Queue*que)
{
if (que == NULL)
return false;
if (que->front == que->rear)
return false;
return true;
}
bool Push_Queue(Queue* que,int data)
{
if (que == NULL)
return false;
if ((que->rear+1)==que->front)
return false;
que->rear = (que->rear+1)%que->MAX;
que->Buff[que->rear] = data;
return true;
}
bool Pop_Queue(Queue* que, int *data)
{
if (que == NULL)
return false;
if (!Empty_Queue(que))
return false;
que->front = (que->front + 1) % que->MAX;
*data = que->Buff[que->front];
return true;
}
void Destroy_Queue(Queue*que)
{
free(que->Buff);
free(que);
}
int *Map=NULL;
int Width = 0;
int Heigh = 0;
int size = 5;
inline bool Init_Map()
{
Map = (int*)malloc(Width*Heigh*sizeof(int));
if (Map == NULL)
return false;
return true;
}
inline bool Path(int y,int x,int Map[])
{
if (Map[y* Width +x] == -1|| Map[y * Width + x] == -3)
return true;
return false;
}
//自动寻路
bool Find(Aim s,Aim e)
{
int temp = 0;
int Max_index = Heigh * Width-1;
Queue* que = Init_Queue(Heigh * Width);
if (que == NULL)
return false;
Push_Queue(que,s.y* Width +s.x);
while (Pop_Queue(que, &temp))
{
int Sec = temp;
//对上下左右进行寻路
for (int i = 0; i < 8; i++)
{
switch (i)
{
case UP:
Sec = temp - Width;
break;
case DOWN:
Sec = temp + Width;
break;
case LEFT:
if(temp% Width !=0)//防止位置越界
Sec = temp - 1;
break;
case RIGHT:
if (temp % Width != (Width - 1))//防止位置越界
Sec = temp + 1;
break;
case UP_LEFT:
if (temp % Width != 0)//防止位置越界
Sec = (temp - 1) - Width;
break;
case UP_RIGHT:
if (temp % Width != 0)//防止位置越界
Sec = (temp - 1) + Width;
break;
case DOWN_LEFT:
if (temp % Width != (Width - 1))//防止位置越界
Sec = (temp + 1)-Width;
break;
case DOWN_RIGHT:
if (temp % Width != (Width - 1))//防止位置越界
Sec = (temp + 1) + Width;
break;
}
//不是正常路径跳过
if (Sec < 0 || Sec>Max_index)
continue;
//判断路径是否可以通过
if (Path(Sec / Width, Sec % Width,Map))
{//记录路径
Map [Sec] = temp;
Push_Queue(que,Sec);
//判断是否是终点
if (e.y == Sec / Width && e.x == Sec % Width)
{
Destroy_Queue(que);
return true;
}
}
}
}
Destroy_Queue(que);
return false;
}
inline void SetColor_XY(unsigned int color,int x,int y)
{
setfillcolor(color);//设置边框颜色
fillrectangle(x * size, y * size, x * size + size, y * size + size);
}
//图像输出函数+控制台输出
void Prinf_Path(Aim s,Aim e)
{
int temp = Map[e.y*Width+e.x];
Stack* Temp_Stack = Init_Stack(Heigh * Width);
Push_Stack(Temp_Stack, temp);
printf("回溯顺序:\n");
printf("[%d] [%d]\n", temp / Width, temp % Width);
while(temp/ Width !=s.y||temp% Width !=s.x)
{
temp = Map[temp];
Push_Stack(Temp_Stack, temp);
printf("[%d] [%d]\n", temp / Width, temp % Width);
}
printf("出栈顺序:\n");
int index = 0;
while (Empty_Stack(Temp_Stack))
{
if (Pop_Stack(Temp_Stack, &index))
{
printf("[%d] [%d]\n", index / Width, index % Width);
SetColor_XY(WHITE, index % Width, index / Width);
Sleep(100);
}
}
Destroy_Stack(Temp_Stack);
}
//图像输出函数
void DrawPath(int array[],int len)
{
unsigned int color=0;
BeginBatchDraw();
for (int i=0;i<len;i++)
{
setlinecolor(BLUE);//设置边框颜色
if (array[i] == -1)
color = 0x00CD66;
else
color = RED;
SetColor_XY(color,i%Width, i / Width);
}
EndBatchDraw();
}
//输入判断
void Scanf_Path(Aim *s,Aim *e)
{
MOUSEMSG mouse;
int index = 0;
int x, y;
DrawPath(Map, Width*Heigh);
while (index<2)
{
mouse = GetMouseMsg();
setlinecolor(BLUE);//设置边框颜色
switch (mouse.uMsg)
{
case WM_LBUTTONDOWN:
x = mouse.x / size;
y = mouse.y / size;
if(index==0)
{
if (Map[y * Width + x] == -1)
{
s->x = x;
s->y = y;
index++;
Map[y * Width + x] = -2;
printf("起点:[%d][%d]\n",y,x);
SetColor_XY(0x065695, x, y);
}
}
else if (index == 1)
{
if (Map[y * Width + x] == -1)
{
e->x = x;
e->y = y;
index++;
Map[y * Width + x] = -3;
printf("终点:[%d][%d]\n",y,x);
SetColor_XY(WHITE, x, y);
}
}
break;
case WM_RBUTTONDOWN:
unsigned int color = 0;
x = mouse.x / size;
y = mouse.y / size;
if (Map [y*Width+x] == -1)
{
Map[y * Width + x] = 0;
color = RED;
}
else if(Map[y * Width + x] == 0)
{
Map[y * Width + x] = -1;
color = 0x00CD66;
}
if(color!=0)
SetColor_XY(color,x,y);
break;
}
}
}
void Find_Path()
{
Aim s = { 0,0 };
Aim e = { 0,0 };
initgraph(Width* size, Heigh* size);
Scanf_Path(&s, &e);
if (Find(s, e))
{
printf("Finish\n");
Prinf_Path(s, e);
}
else
printf("Error\n");
printf("数组元素:\n");
for (int i = 0; i < Heigh; i++)
{
for (int j = 0; j < Width; j++)
printf(" %4d", Map[i*Width+j]);
printf("\n\n");
}
}
int main()
{
printf("请输入Width,Heigh,size:\n");
while (scanf("%d %d %d", &Width, &Heigh,&size) == 0)
char a=getchar();
//数组初始化
if(Init_Map())
{
while (1)
{
for (int i = 0; i < Heigh; i++)
for (int j = 0; j < Width; j++)
Map[i * Width + j] = -1;
Find_Path();
system("pause");
//数组复位
}
}
free(Map);
return 0;
}
利用广度优先遍历实现寻路
于 2024-05-01 22:36:35 首次发布