用c语言生成心形迷宫(代码)

事先说明,文章是从知乎上看到的 用c语言生成心形迷宫,但是作者的代码使用vs2015写的,用普通的vc6行不通,不过机缘巧合的我把所有的文件整合到一个文件里,运行通过了,所以,我再次声明,我只是代码的搬运工!
下边展示一下运行效果:

运行结果就是寻到了尽头咯,下面展示源码,我想这也是作者想要展示的(再次声明,我是代码的搬运工)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>

#define MAXQSIZE 1000
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

#define N 37	
#define M 47
#define DELAY 1

#define MAXQSIZE 1000
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef enum { MASK = 0, ROAD = 1, BACK = 2, INWALL = 3, OUTWALL = 4, EMPTYWALL = 5 } BlockType;
typedef enum { EAST = 6, SOUTH = 7, WEST = 8, NORTH = 9 } Direction;
typedef int Maze;

bool visited[N][M];
bool mask[N][M];
bool area[N][M];
int di[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };

typedef struct
{
	int x;
	int y;
	int di;
}Block;

typedef struct {

	Block *base;
	int front;
	int rear;
}SqQueue;

typedef struct
{
	Block *base;
	Block *top;
	int stacksize;
}SqStack;

void initStack(SqStack &S)
{
	S.base = (Block*)malloc(STACK_INIT_SIZE * sizeof(Block));
	if (!S.base)
		return;
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
}

void push(SqStack &S, Block e)
{
	if (S.top - S.base >= S.stacksize)
	{
		S.base = (Block*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(Block));
		if (!S.base)
			return;
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREMENT;
	}
	*S.top = e;
	S.top++;
}

void pop(SqStack &S, Block&e)
{
	if (S.top == S.base)
		return;
	S.top--;
	e = *S.top;
}

bool isEmpty(SqStack S)
{
	if (S.top == S.base)
		return true;
	else
		return false;
}

void initQueue(SqQueue &Q)
{
	Q.base = (Block*)malloc(MAXQSIZE * sizeof(Block));
	if (!Q.base)
		return;
	Q.front = Q.rear = 0;
}

void enQueue(SqQueue &Q, Block e)
{
	if ((Q.rear + 1) % MAXQSIZE == Q.front)
		return;

	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MAXQSIZE;
}

int getLength(SqQueue Q)
{
	return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

void deQueue(SqQueue &Q, Block &e)
{
	if (Q.front == Q.rear)
		return;
	srand((unsigned)time(NULL));
	int randIdx = rand() % getLength(Q);
	e = Q.base[randIdx];
	Q.base[randIdx] = Q.base[Q.rear - 1];
	Q.base[Q.rear - 1] = e;

	Q.rear = (Q.rear - 1) % MAXQSIZE;
}

bool isEmpty(SqQueue Q)
{
	if (Q.front == Q.rear)
		return true;
	else
		return false;
}

void initMaze(Maze maze[N][M], Block &in, Block &out);
void findPath(Maze maze[N][M], Block in, Block out);
void initBlock(Block &block, int x, int y, int di);
void showBlock(Maze maze[N][M]);
void updateMaze(Maze maze[N][M]);
int nextBlockX(int a, int di);
int nextBlockY(int b, int di);
bool inMaze(int x, int y);
void clearMask(int x, int y);
void gotoxy(int x, int y);
void hideCursor();
void initHeart();

int main()
{
	Maze maze[N][M];
	Block in, out;
	initMaze(maze, in, out);
	findPath(maze, in, out);
	return 0;
}

void initMaze(Maze maze[N][M], Block &in, Block &out)
{
	initHeart();
	srand((unsigned)time(NULL));

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			if (area[i][j] && !(area[i][j - 1] && area[i][j + 1] && area[i - 1][j] && area[i + 1][j]))
				maze[i][j] = OUTWALL;
			else if (area[i][j] && i % 2 == 0 && j % 2 == 0)
				maze[i][j] = ROAD;
			else if (area[i][j])
				maze[i][j] = INWALL;
			else
				maze[i][j] = EMPTYWALL;
			visited[i][j] = false;
			mask[i][j] = true;
		}
	}
	in.x = 1;
	in.y = 6;
	out.x = 27;
	out.y = 36;
	maze[in.x][in.y] = maze[out.x][out.y] = ROAD;
	SqQueue S;
	Block start;
	initQueue(S);
	start.x = 2;
	start.y = 6;
	enQueue(S, start);
	visited[start.x][start.y] = true;
	clearMask(start.x, start.y);
	while (!isEmpty(S))
	{
		Block curBlock;
		deQueue(S, curBlock);
		for (int i = 0; i < 4; i++)
		{
			int nextBlockX = curBlock.x + di[i][0] * 2;
			int nextBlockY = curBlock.y + di[i][1] * 2;
			if (inMaze(nextBlockX, nextBlockY) && maze[nextBlockX][nextBlockY] == ROAD && !visited[nextBlockX][nextBlockY])
			{
				Block nextBlock;
				nextBlock.x = nextBlockX;
				nextBlock.y = nextBlockY;
				enQueue(S, nextBlock);
				maze[curBlock.x + di[i][0]][curBlock.y + di[i][1]] = ROAD;
				visited[nextBlockX][nextBlockY] = true;
				clearMask(nextBlockX, nextBlockY);
				updateMaze(maze);
			}
		}
	}

	for (int ii = 0; ii < N; ii++)
	{
		for (int j = 0; j < M; j++)
		{
			if (maze[ii][j] == OUTWALL)
			{
				mask[ii][j] = false;
				updateMaze(maze);
			}
		}
	}
}

void findPath(Maze maze[N][M], Block in, Block out)
{
	Block block;
	SqStack S;
	initStack(S);
	int curBlockX = in.x;
	int curBlockY = in.y;
	int step = 1;
	do {
		if (inMaze(curBlockX, curBlockY) && maze[curBlockX][curBlockY] == ROAD)
		{
			initBlock(block, curBlockX, curBlockY, EAST);
			push(S, block);

			maze[curBlockX][curBlockY] = block.di;
			updateMaze(maze);

			if (curBlockX == out.x&&curBlockY == out.y)
			{
				printf("\n寻路成功\n共%d步", step);
				Sleep(10000);		//休眠10s
				system("cls");
				return;
			}
			curBlockX = nextBlockX(block.x, block.di);
			curBlockY = nextBlockY(block.y, block.di);
			step++;
		}
		else
		{
			pop(S, block);

			if (block.di < NORTH)
			{
				block.di++;
				maze[block.x][block.y] = block.di;
				push(S, block);
				curBlockX = nextBlockX(block.x, block.di);
				curBlockY = nextBlockY(block.y, block.di);
				updateMaze(maze);
			}
			else
			{
				maze[block.x][block.y] = BACK;
				updateMaze(maze);
				step--;
			}
		}
	} while (!isEmpty(S));
	printf("寻路失败");
}

void initBlock(Block &block, int x, int y, int di)
{
	block.x = x;
	block.y = y;
	block.di = di;
}

void showBlock(Maze maze[N][M])
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			if (mask[i][j] == true)
				printf("  ");
			else if (maze[i][j] == INWALL)
				printf("█");
			else if (maze[i][j] == OUTWALL)
				printf("█");
			else if (maze[i][j] == EMPTYWALL)
				printf("  ");
			else if (maze[i][j] == ROAD)
				printf("  ");
			else if (maze[i][j] == BACK)
				printf("□");
			else if (maze[i][j] == EAST)
				printf("→");
			else if (maze[i][j] == SOUTH)
				printf("↓");
			else if (maze[i][j] == WEST)
				printf("←");
			else if (maze[i][j] == NORTH)
				printf("↑");
			if (j != 0 && j % (M - 1) == 0)
				printf("\n");
		}
	}
}

void updateMaze(Maze maze[N][M])
{
	hideCursor();
	gotoxy(0, 0);
	showBlock(maze);
	Sleep(1);           //此处我个人认为是作者设置的休眠0.001s
}

int nextBlockX(int a, int di)
{
	int x = a;
	switch (di)
	{
		case SOUTH:
			x++;
			break;
		case NORTH:
			x--;
			break;
		default:
			break;
	}
	return x;
}

int nextBlockY(int b, int di)
{
	int y = b;
	switch (di)
	{
		case EAST:
			y++;
			break;

		case WEST:
			y--;
			break;
		default:
			break;
	}
	return y;
}

bool inMaze(int x, int y)
{
	return x >= 0 && x < N&&y >= 0 && y < M;
}

void clearMask(int x, int y)
{
	for (int i = x - 1; i <= x + 1; i++)
		for (int j = y - 1; j <= y + 1; j++)
			if (inMaze(i, j))
				mask[i][j] = false;
}

void gotoxy(int x, int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void hideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void initHeart()
{
	int i = 0, j = 0;
	for (float y = 1.2f; y > -1.0f; y -= 0.06f)
	{
		for (float x = -1.1f; x < 1.2f; x += 0.05f)
		{
			float a = x * x + y * y - 1;
			if (a * a * a - x * x * y * y * y <= 0.0f)
				area[i][j] = true;
			else
				area[i][j] = false;
			j++;
		}
		i++;
		j = 0;
	}
}

猜你喜欢

转载自blog.csdn.net/easy_purple/article/details/80400389