数据结构课设| |迷宫问题

迷宫问题

思想:分成了三大部分,头文件maze.h,函数功能源文件maze.c,测试源文件test.c

1.源文件maze.h

#ifndef __MAZE_H__
#define __MAZE_H__

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

//迷宫的最大行列数
#define MAXSIZE 20

//迷宫起点,终点坐标类型
typedef struct fix
{
 int x;
 int y;
}Pos, *pPos;

//迷宫类型
typedef struct maze
{
 int row;//行
 int col;//列
 int wall;//墙的个数
 int arr_maze[MAXSIZE][MAXSIZE];
}Maze, *pMaze;

//栈类型
typedef struct
{
 int arr_stack[400][2]; //栈数组
 int top; //栈顶指针
}Stack, *pStack;

void ShowMaze(Maze maze, Pos terminal);
void ShowMazeStack(Maze maze, Pos terminal, Stack stack);
void ShowCreateMaze(Maze maze);
void CreatMazeRand(pMaze pmaze);
void CreatMazeMe(pMaze pmaze);
void CreatOrigo(pMaze pmaze, pPos origo);
void CreatTerminal(pMaze pmaze,pPos origo, pPos terminal);
void SolveMazePath(pMaze pmaze, Pos origo, Pos terminal);
void SolveMazePathAllRecursion(pMaze pmaze, Pos origo, Pos terminal);
void SolveMazePathAllStack(pMaze pmaze, Pos origo, Pos terminal, pStack stack);
void PopStack(pStack pstack);
void PushStack(pStack pstack, int x, int y);
void InitMaze(pMaze pmaze);
void InitOrigoTerminal(pMaze pmaze,pPos origo, pPos terminal);



#endif //__MAZE_H__

2.函数功能源文件maze.c

#include "maze.h"

void ShowMaze(Maze maze, Pos terminal)
{
 int i = 0;
 int j = 0;
 for (i = 0; i < maze.row + 2; i++)
 {
  for (j = 0; j < maze.col + 2; j++)
  {
   if (maze.arr_maze[i][j] == 1)
   {
    printf("█");
   }
   else if (maze.arr_maze[i][j] == 2)
   {
    printf("◇");
   }
   else
   {
    printf(" ");
   }
  }
  printf("\n");
 }
 printf("展示完毕!\n");
}

void ShowMazeStack(Maze maze, Pos terminal, Stack stack)
{
 int i = 0;
 int j = 0;
 //次数计数器
 static count = 1;
 printf("方法%d:\n", count++);
 printf("图形展示:\n");
 for (i = 0; i < maze.row + 2; i++)
 {
  for (j = 0; j < maze.col + 2; j++)
  {
   if (maze.arr_maze[i][j] == 1)
   {
    printf("█");
   }
   else if (maze.arr_maze[i][j] == 2)
   {
    printf("◇");
   }
   else
   {
    printf(" ");
   }
  }
  printf("\n");
 }
 printf("坐标展示:\n");
 for (i = 0; i < stack.top; i++)
 {
  if (i != stack.top - 1)
  {
   printf("(%d,%d)-->", stack.arr_stack[i][0], stack.arr_stack[i][1]);
  }
  else
  {
   printf("(%d,%d)", stack.arr_stack[i][0], stack.arr_stack[i][1]);
  }
 }
 printf("展示完毕!\n");
}


void ShowCreateMaze(Maze maze)
{
 int i = 0;
 int j = 0;
 //坐标列
 for (i = 0; i <= maze.col; i++)
 {
  if (i == 0)
  {
   printf("%2d   ", i);
  }
  else
  {
   printf("%2d   ", i);
  }
 }
 printf("\n");
 for (i = 0; i <= maze.col; i++)
 {
  if (i == 0)
  {
   printf("   ");
  }
  else if (i == 1)
  {
   printf("----");
  }
  else
  {
   printf("-----");
  }
 }
 printf("\n");
 for (i = 1; i <= maze.row; i++)
 {
  //坐标行
  printf("%2d |", i);
  for (j = 1; j <= maze.col; j++)
  {
   printf("%2d   ", maze.arr_maze[i][j]);
  }
  printf("\n\n");
 }
}

void CreatMazeRand(pMaze pmaze)
{
 int i = 0;
 int j = 0;
 bool flag = true;
 assert(pmaze != NULL);

 //迷宫大小
 while (flag)
 {
  printf("请输入迷宫的大小(行*列)<(MAXSIZAE * MAXSIZE)(MAXSIZE = %d):", MAXSIZE);
  scanf("%d*%d", &pmaze->row, &pmaze->col);
  if ((pmaze->row > MAXSIZE) || (pmaze->col > MAXSIZE))
  {
   printf("行列超出最大范围,请重新输入!\n");
   flag = true;
  }
  else
  {
   flag = false;
  }
 }

 //墙的个数
 flag = true;
 while (flag)
 {
  printf("请输入墙的个数(墙的个数要小于等于:<行*列>):");
  if (pmaze->wall > (pmaze->row * pmaze->col))
  {
   printf("墙的个数出错,请重新输入!\n");
   flag = true;
  }
  else
  {
   scanf("%d", &pmaze->wall);
   flag = false;
  }
 }
 
 //增加边框,并且全部赋值0
 memset(pmaze->arr_maze, 0, sizeof(pmaze->arr_maze));

 //边框全部变为1
 //第1行和最后1行
 for (i = 0; i < pmaze->col + 2; i++)
 {
  pmaze->arr_maze[0][i] = 1;
  pmaze->arr_maze[pmaze->row + 2 -1][i] = 1;
 }
 //第1列和最后1列
 for (i = 1; i < pmaze->row + 2 - 1; i++)
 {
  pmaze->arr_maze[i][0] = 1;
  pmaze->arr_maze[i][pmaze->col + 2 - 1] = 1;
 }
 //边框内部全部进行随机值赋值
 srand((unsigned int)time(NULL));
 while (pmaze->wall != 0)
 {
  int x = rand() % pmaze->row + 1;
  int y = rand() % pmaze->col + 1;
  if (pmaze->arr_maze[x][y] != 1)
  {
   pmaze->arr_maze[x][y] = 1;
   pmaze->wall--;
  }
 }
}

void CreatMazeMe(pMaze pmaze)
{
 int i = 0;
 int j = 0;
 assert(pmaze != NULL);
 printf("请输入迷宫的大小(行*列)>:");
 scanf("%d*%d", &pmaze->row, &pmaze->col);
 //增加边框,并且全部赋值0
 memset(pmaze->arr_maze, 0, sizeof(pmaze->arr_maze));
 //边框全部变为1
 //第1行和最后1行
 for (i = 0; i < pmaze->col + 2; i++)
 {
  pmaze->arr_maze[0][i] = 1;
  pmaze->arr_maze[pmaze->row + 2 - 1][i] = 1;
 }
 //第1列和最后1列
 for (i = 1; i < pmaze->row + 2 - 1; i++)
 {
  pmaze->arr_maze[i][0] = 1;
  pmaze->arr_maze[i][pmaze->col + 2 - 1] = 1;
 }
 //自己输入要创建的迷宫
 for (i = 1; i < pmaze->row + 2 - 1; i++)
 {
  printf("迷宫第%d行>:", i);
  for (j = 1; j < pmaze->col + 2 - 1; j++)
  {
   scanf("%d", &pmaze->arr_maze[i][j]);
  }
  printf("\n");
 }
}

void CreatOrigo(pMaze pmaze, pPos origo)
{
 bool flag = 0;
 assert(pmaze != NULL);
 flag = true;
 printf("请输入你要选择的入口(x,y)>:");
 while (flag)
 {
  scanf("%d,%d", &origo->x, &origo->y);
  if (pmaze->arr_maze[origo->x][origo->y] != 1)
  {
   //pmaze->arr_maze[origo->x][origo->y] = 6;
   flag = false;
  }
  else
  {
   printf("您创建的入口已被占用,请重新创建:>");
   flag = true;
  }
 }
}

void CreatTerminal(pMaze pmaze, pPos origo, pPos terminal)
{
 bool flag = 0;
 assert(pmaze != NULL);
 flag = true;
 printf("请输入你要选择的出口(x,y)>:");
 //确保创建的出口不是入口,并且出口不是墙
 while (flag)
 {
  scanf("%d,%d", &terminal->x, &terminal->y);
  //终点既不能等于1,也不能等于6
  if (pmaze->arr_maze[terminal->x][terminal->y] != 1) 
  {
   //确保出口不是入口
   if ((terminal->x != origo->x) && (terminal->y != origo->y))
   {
    flag = false;
   }
  }
  else
  {
   printf("您创建的出口已被占用,请重新创建:>");
   flag = true;
  }
 }
}

void recursion_showmaze_all(pMaze pmaze, int x, int y, Pos origo, Pos terminal)
{
 pmaze->arr_maze[x][y] = 2;

 if (x == terminal.x && y == terminal.y)
 {
  ShowMaze(*pmaze, terminal);
 }
 //向下走
 if ((x <= pmaze->row) && (pmaze->arr_maze[x + 1][y]) == 0)
 {
  recursion_showmaze_all(pmaze, x + 1, y, origo, terminal);
 }
 //向右走
 if ((y <= pmaze->col) && (pmaze->arr_maze[x][y + 1]) == 0)
 {
  recursion_showmaze_all(pmaze, x, y + 1, origo, terminal);
 }
 //向左走
 if ((y >= 1) && (pmaze->arr_maze[x][y - 1]) == 0)
 {
  recursion_showmaze_all(pmaze, x, y - 1, origo, terminal);
 }
 //向上走
 if ((x >= 1) && (pmaze->arr_maze[x - 1][y]) == 0)
 {
  recursion_showmaze_all(pmaze, x - 1, y, origo, terminal);
 }


 //如果一个点周围四个方向都走不了,那么就将改点赋值为0
 pmaze->arr_maze[x][y] = 0;
}

void SolveMazePathAllRecursion(pMaze pmaze, Pos origo, Pos terminal)
{
 recursion_showmaze_all(pmaze, origo.x, origo.y, origo, terminal);
}

void PushStack(pStack pstack,int x, int y)
{
 assert(pstack != NULL);
 pstack->arr_stack[pstack->top][0] = x;
 pstack->arr_stack[pstack->top][1] = y;
 pstack->top++;
}

void PopStack(pStack pstack)
{
 assert(pstack != NULL);
 pstack->top--;
}

void showmaze_stack(pMaze pmaze, int x, int y, Pos origo, Pos terminal, pStack pstack)
{
 PushStack(pstack, x, y);
 pmaze->arr_maze[x][y] = 2;
 if (x == terminal.x && y == terminal.y)
 {
  ShowMazeStack(*pmaze, terminal, *pstack);
 }
 //向下走
 if ((x <= pmaze->row) && (pmaze->arr_maze[x + 1][y]) == 0)
 {
  showmaze_stack(pmaze, x + 1, y, origo, terminal, pstack);
 }
 //向右走
 if ((y <= pmaze->col) && (pmaze->arr_maze[x][y + 1]) == 0)
 {
  showmaze_stack(pmaze, x, y + 1, origo, terminal, pstack);
 }
 //向左走
 if ((y >= 1) && (pmaze->arr_maze[x][y - 1]) == 0)
 {
  showmaze_stack(pmaze, x, y - 1, origo, terminal, pstack);
 }
 //向上走
 if ((x >= 1) && (pmaze->arr_maze[x - 1][y]) == 0)
 {
  showmaze_stack(pmaze, x - 1, y, origo, terminal, pstack);
 }

 pmaze->arr_maze[x][y] = 0;
 PopStack(pstack);
}


void SolveMazePathAllStack(pMaze pmaze, Pos origo, Pos terminal, pStack pstack)
{
 showmaze_stack(pmaze, origo.x, origo.y, origo, terminal, pstack);
}

int recursion_showmaze(pMaze pmaze,int x, int y, Pos origo, Pos terminal)
{
 //该点走过,标记为2
 pmaze->arr_maze[x][y] = 2;
 //判断是否成功
 int success = 0;
 //走到终点,成功
 if (x == terminal.x && y == terminal.y)
 {
  ShowMaze(*pmaze, terminal);
  success = 1;
 }
 //向下走
 if ((success != 1) && (pmaze->arr_maze[x + 1][y]) == 0)
 {
  recursion_showmaze(pmaze, x + 1, y, origo, terminal);
 }
 //向右走
 if ((success != 1) && (pmaze->arr_maze[x][y + 1]) == 0) 
 {
  recursion_showmaze(pmaze, x, y + 1, origo, terminal);
 }
 //向左走
 if ((success != 1) && (pmaze->arr_maze[x][y - 1]) == 0)
 {
  recursion_showmaze(pmaze, x, y - 1, origo, terminal);
 }
 //向上走
 if ((success != 1) && (pmaze->arr_maze[x - 1][y]) == 0)
 {
  recursion_showmaze(pmaze, x - 1, y, origo, terminal);
 }
 //该点走过,但没成功,则该点重新置为0
 if (success != 1)
 {
  pmaze->arr_maze[x][y] = 0;
 }
 return success;
}

void SolveMazePath(pMaze pmaze, Pos origo, Pos terminal)
{
 assert(pmaze != NULL);
 recursion_showmaze(pmaze, origo.x, origo.y, origo, terminal);
 pmaze->arr_maze[terminal.x][terminal.y] = 0;
}

void InitMaze(pMaze pmaze)
{
 assert(pmaze != NULL);
 //销毁对其全部都赋0
 memset(pmaze->arr_maze, 0, sizeof(pmaze->arr_maze));
}

void InitOrigoTerminal(pMaze pmaze,pPos origo, pPos terminal)
{
 assert(origo != NULL);
 assert(terminal != NULL);
 assert(terminal != NULL);
 origo->x = 1;
 origo->y = 1;
 terminal->x = pmaze->row;
 terminal->y = pmaze->col;
}

3.测试源文件test.c

#include "maze.h"


void menu()
{
 printf("\t\t\t\t******************************************\n");
 printf("\t\t\t\t*****       迷宫问题               *****\n");
 printf("\t\t\t\t*****     1.系统创建迷宫             *****\n");
 printf("\t\t\t\t*****     2.自己创建迷宫             *****\n");
 printf("\t\t\t\t*****     3.展示创建的迷宫           *****\n");
 printf("\t\t\t\t*****     4.给迷宫入口               *****\n");
 printf("\t\t\t\t*****     5.给迷宫出口               *****\n");
 printf("\t\t\t\t*****     6.求该迷宫的一种路径       *****\n");
 printf("\t\t\t\t*****     7.求该迷宫的所有路径(递归) *****\n");
 printf("\t\t\t\t*****     8.求该迷宫的所有路径(栈)   *****\n");
 printf("\t\t\t\t*****     9.重新开始                 *****\n");
 printf("\t\t\t\t*****     0.退出程序                 *****\n");
 printf("\t\t\t\t******************************************\n");
}

void test()
{
 int input = 1;
 Maze maze = { 0 };
 Pos origo = { 0 };
 Pos terminal = { 0 };
 Stack stack = { 0 };
 menu();
 while (input != 0)
 {
  printf("请选择功能(输入功能序号即可)>:");
  scanf("%d", &input);
  switch (input)
  {
  case 1:
  {
   CreatMazeRand(&maze);
   //默认(1,1)为入口
   origo.x = 1;
   origo.y = 1;
   //默认(maze.row,maze.col)为出口
   terminal.x = maze.row;
   terminal.y = maze.col;
  }
   break;
  case 2:
  {
   CreatMazeMe(&maze);
   //默认(1,1)为入口
   origo.x = 1;
   origo.y = 1;
   //默认(maze.row,maze.col)为出口
   terminal.x = maze.row;
   terminal.y = maze.col;
  }
   break;
  case 3:
  {
   ShowCreateMaze(maze);
  }
   break;
  case 4:
  {
   //起点是4
   CreatOrigo(&maze, &origo);
  }
   break;
  case 5:
  {
   //终点是5
   CreatTerminal(&maze, &origo, &terminal);
  }
   break;
  case 6:
  {
   printf("如果没有给出口与入口的话。默认入口为左上角,出口为右下角!\n");
   SolveMazePath(&maze, origo, terminal);
  }
   break;
  case 7:
  {
   printf("如果没有给出口与入口的话。默认入口为左上角,出口为右下角!\n");
   SolveMazePathAllRecursion(&maze, origo, terminal);
  }
   break;
  case 8:
  {
   printf("如果没有给出口与入口的话。默认入口为左上角,出口为右下角!\n");
   SolveMazePathAllStack(&maze, origo, terminal, &stack);
  }
   break;
  case 9:
  {
   //数组要置为零,并且出口和入口要重置
   InitMaze(&maze);
   InitOrigoTerminal(&maze, &origo, &terminal);
   printf("重置完成!可以重新开始游戏了.\n");
  }
   break;
  case 0:
  {
   printf("程序结束!\n");
  }
   break;
  default:
  {
   printf("功能选择错误!请重新选择!\n");
  }
   break;
  };
 }
}

int main()
{
 test();
 return 0;
}

这就是所有代码了,欢迎观看!

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/qq_40399012/article/details/80827309
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞