不同等级的迷宫小游戏~

                     迷宫                                                                                                               

                                                                                            

一、简单迷宫        

说明:

        1.      0:墙         1:路        2:走过的路

        2.       探索方向:左->上->右->下

        3.      位置用数组下标来表示 (在这里我们初始位置设置为2,5)

        4.       将走过的路入栈保存 

        5.      无路可走就回溯(出栈)

#pragma once
#include "stack.h"
#include <windows.h>

#define ROWS (6)
#define COLS (6)

//1可以走    0不可以走
int IsAccess(int maze[ROWS][COLS],Position pos)
{
	//判断是否越界
	if (pos.y < 0 || pos.y >= ROWS){
		return 0;
	}
	if (pos.x < 0 || pos.x >= COLS){
		
		return 0;
	}
	return maze[pos.y][pos.x] == 1 ? 1 : 0;
}

//1是    0不是
int IsExit(Position pos)
{
	if (pos.x == COLS - 1)
	{
		return 1;
	}
	else{
		return 0;
	}
}
void PrintfMaze(int maze[ROWS][COLS])
{
	int i, j;
	for (i = 0; i < ROWS; i++)
	{
		for (j = 0; j < COLS; j++){
			printf("%d ", maze[i][j]);
		}
		printf("\n");
	}
}
void GoMaze(int maze[ROWS][COLS], Position entry)
{
	Position pos = entry;  //当前所在位置
	Position nextPos;  //要尝试的位置
	Stack stack;
	StackInit(&stack);

	while (1)
	{
		maze[pos.y][pos.x] = 2;//表示来过
		system("cls");
		PrintfMaze(maze);
		Sleep(500);
		if (IsExit(pos)){
			printf("   你太聪明了~出口就是这儿~\n");
			return;
		}
		//左->上->右->下
		nextPos = pos;
		nextPos.x -= 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.y -= 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.x += 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.y += 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		//回溯
		pos = StackTop(&stack);
			StackPop(&stack);
			maze[pos.y][pos.x] = 3; 
			system("cls");
			PrintfMaze(maze);
			Sleep(500);
	}
}

void TestMaze1()
{
	int maze[ROWS][COLS] = {
		{ 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 1, 0, 0, 0 },
		{ 0, 0, 1, 0, 0, 0 },
		{ 0, 0, 1, 1, 1, 0 },
		{ 0, 0, 1, 0, 1, 1 },
		{ 0, 0, 1, 0, 0, 0 },
	};
	Position enter = { 2, 5 };
	GoMaze(maze, enter);
        PrintfMaze(maze);
}

二、多通路迷宫(不带环)

   和第一个不同的是:在找到第一个出口的时候不要直接退出,应该进行回溯出栈找出第二个..出口,

   循环终止条件:   就是当栈为空时,我们就是已经将所有出口找到了。

回溯的条件有两个:一个是找到出口就回溯

                               一个是无路可走就回溯

void GoMaze(int maze[ROWS][COLS], Position entry)
{
	Position pos = entry;  //当前所在位置
	Position nextPos;  //要尝试的位置
	Stack stack;
	StackInit(&stack);

	while (1)
	{
		maze[pos.y][pos.x] = 2;//表示来过
		system("cls");
		PrintfMaze(maze);
		Sleep(500);
		if (IsExit(pos)){
			//回溯
			pos = StackTop(&stack);
			StackPop(&stack);
			maze[pos.y][pos.x] = 3;
			system("cls");
			printf("   小可爱~找到一个出口啦~\n");
			PrintfMaze(maze);
			Sleep(2000);
			continue;
		}
		//左->上->右->下
		nextPos = pos;
		nextPos.x -= 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.y -= 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.x += 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		nextPos = pos;
		nextPos.y += 1;
		if (IsAccess(maze,nextPos)){
			StackPush(&stack, pos);
			pos = nextPos;
			continue;
		}
		//回溯
		if (StackIsEmpty(&stack))
		{
			printf("   小可爱~你的迷宫探索旅程结束啦~\n");
			return;
		}
		pos = StackTop(&stack);
			StackPop(&stack);
			maze[pos.y][pos.x] = 3;
			system("cls");
			PrintfMaze(maze);
			Sleep(500);
	}
}

void TestMaze1()
{
	int maze[ROWS][COLS] = {
		{ 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 1, 1, 1, 1 },
		{ 0, 0, 1, 0, 0, 0 },
		{ 0, 0, 1, 0, 0, 0 },
		{ 0, 0, 1, 1, 1, 1 },
		{ 0, 0, 1, 0, 0, 0 },
	};
	Position enter = { 2, 5 };
	GoMaze(maze, enter);

	PrintfMaze(maze);
}

三、多通路迷宫(带环)

这里我们采用了递归的方式

这里我们要注意:每次出来的时候要将走过的路在设置成1

void GoMazeRecursion(int maze[ROWS][COLS],Position pos)
{
	maze[pos.y][pos.x] = 2;//表示来过
	system("cls");
	PrintfMaze(maze);
	Sleep(300);
	Position nextPos;
	if (IsExit(pos)){
		printf("     小可爱~ 找到一个出口啦\n");
		maze[pos.y][pos.x] = 1;
		PrintfMaze(maze);
		system("pause");
		return;
	}

	nextPos = pos;
	nextPos.x -= 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(maze,nextPos);
	}
	nextPos = pos;
	nextPos.y -= 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(maze, nextPos);
	}
	nextPos = pos;
	nextPos.x += 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(maze, nextPos);
	}
	nextPos = pos;
	nextPos.y += 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(maze, nextPos);
	}
	maze[pos.y][pos.x] = 1;

}
void TestMaze1()
{
	int maze[ROWS][COLS] = {
		{ 0, 0, 0, 0, 0, 0 },
		{ 0, 1, 1, 1, 0, 0 },
		{ 0, 1, 0, 1, 0, 0 },
		{ 0, 1, 0, 1, 0, 0 },
		{ 0, 1, 1, 1, 1, 1 },
		{ 0, 1, 0, 0, 0, 0 },
	};
	Position enter = { 2, 5 };
	GoMaze(maze, enter);

	PrintfMaze(maze);
}


四、多通路带环迷宫的最短路径

就是将每走的一步都入栈,最后进行比较,短的就为最短路径

void GoMazeRecursion(Stack *pPath,Stack *pShort, int maze[ROWS][COLS],Position pos)
{
	maze[pos.y][pos.x] = 2;//表示来过

	StackPush(pPath, pos);  //每走一步都入栈

	system("cls");
	PrintfMaze(maze);
	Sleep(300);
	Position nextPos;

	if (IsExit(pos)){
		printf("     小可爱找到出口啦~\n");
		maze[pos.y][pos.x] = 1;

		StackPop(pPath);

		if (StackIsEmpty(pShort) || StackSize(pPath )< StackSize(pShort)) //若最短路径栈为空
			                                           //或者path的路径比最短路径小那就更新最短路径
		{
			//找到新的最短路径
			StackCopy(pShort, pPath);
		}
		PrintfMaze(maze);
		system("pause");
		return;
	}

	nextPos = pos;
	nextPos.x -= 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(pPath,pShort,maze, nextPos);
	}
	nextPos = pos;
	nextPos.y -= 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(pPath, pShort,maze, nextPos);
	}
	nextPos = pos;
	nextPos.x += 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(pPath, pShort,maze, nextPos);
	}
	nextPos = pos;
	nextPos.y += 1;
	if (IsAccess(maze, nextPos)){
		GoMazeRecursion(pPath, pShort,maze, nextPos);
	}

	StackPop(pPath);//无路可走就出栈一次

	maze[pos.y][pos.x] = 1;

}
void TestMaze1()
{
	Stack pathStack;
	Stack shortStack;
	int maze[ROWS][COLS] = {
		{ 0, 0, 0, 0, 0, 0 },
		{ 0, 1, 1, 1, 0, 0 },
		{ 0, 1, 0, 1, 0, 0 },
		{ 0, 1, 0, 1, 0, 0 },
		{ 0, 1, 1, 1, 1, 1 },
		{ 0, 1, 0, 0, 0, 0 },
	};
	Position enter = { 1, 5 };
	StackInit(&pathStack); //初始化
	StackInit(&shortStack);

	GoMazeRecursion(&pathStack,&shortStack, maze, enter);

	while (!StackIsEmpty(&shortStack)) {
		Position pos = StackTop(&shortStack);
		StackPop(&shortStack);

		maze[pos.y][pos.x] = 4;  //将最短路径用4表示
	}

	PrintfMaze(maze);
}

这是在里所用到的栈~

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef struct Position {
	int	x;
	int	y;
}	Position;

typedef Position	SDataType;

#define	MAX_SIZE	(100)

typedef struct Stack {
	SDataType	array[MAX_SIZE];
	int			top;	// 含义和顺序表的 size 是一样
						// 1. 表示有效数据个数
						// 2. top 下标表示当前可用位置
}	Stack;


void StackInit(Stack *pS)
{
	assert(pS != NULL);

	pS->top = 0;
}

void StackPush(Stack *pS, SDataType data)
{
	assert(pS != NULL);
	assert(pS->top < MAX_SIZE);

	pS->array[pS->top++] = data;
}

void StackPop(Stack *pS)
{
	assert(pS != NULL);
	assert(pS->top > 0);

	pS->top--;
}

SDataType StackTop(Stack *pS)
{
	assert(pS != NULL);
	assert(pS->top > 0);

	return pS->array[pS->top - 1];
}

// 判断为空, 1 表示空,0 表示非空
int StackIsEmpty(Stack *pS)
{
	return pS->top == 0 ? 1 : 0;
}

int StackSize(Stack *pS)
{
	return pS->top;
}

void StackCopy(Stack *pDest, Stack *pSrc)
{
	pDest->top = pSrc->top;
	memcpy(pDest->array, pSrc->array, sizeof(SDataType)* pSrc->top);
}

void TestStack()
{
	Stack	stack;
	StackInit(&stack);
}
                                      

猜你喜欢

转载自blog.csdn.net/z_juan1/article/details/80877308