数据结构-走迷宫游戏

摘  要

迷宫最早出现在古希腊神话中。

据说,半人半神的英雄西修斯 (Theseus) 在克里特的迷宫中勇敢地杀死半人半牛的怪物,并循着绳索 (Ariadne 抓住另一头 ) 逃出迷宫。 希腊史学家希罗多德曾探访过那里。他描述说,整个迷宫由 12 座带顶院落构成,所有院落都由通道连接,形成 3000 个独立的“室”。据说,建造这座迷宫用的人力和财力“超过了希腊所有的建筑”。后来的参观者也说,一旦进入迷宫,如果没向导,根本无望走出。若不是知情人泄露了地图,盗墓者可能永远也无法探明克里特迷宫。

现在,在人们的生活中,迷宫随处可见,它在各个领域被广泛应用。本程序就是利用C语言知识和数据结构算法所做成的简易迷宫。

关键词:迷宫  C语言 数据结构

章  绪  论

1.1 课设主要研究问题

二维数组本质上是以数组作为数组元素的数组,即"数组的数组",类型说明符 数组名[常量表达式][常量表达式]。二维数组又称为矩阵,行列数相等的矩阵称为方阵。对称矩阵a[i][j] = a[j][i],对角矩阵:n阶方阵主对角线外都是零元素。

递归是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象。在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知。

使用递归解决问题,思路清晰,代码少。但是在主流高级语言中(如C语言、Pascal语言等)使用递归算法要耗用更多的栈空间,所以在堆栈尺寸受限制时(如嵌入式系统或者内核态编程),应避免采用。所有的递归算法都可以改写成与之等价的非递归算法。

1.2 课设应用的理论知识

二维数组A[m][n],这是一个m行,n列的二维数组。设a[p][q]为A的第一个元素,即二维数组的行下标从p到m+p,列下标从q到n+q,按"行优先顺序"存储时则元素a[i][j]的地址,按"列优先顺序"存储时的地址。存放该数组至少需要的单元数为(m-p+1) * (n-q+1) * t 个字节。递归,就是在运行的过程中调用自己。而构成递归需具备的条件以函数嵌套调用过程示例:1. 子问题须与原始问题为同样的事,且更为简单;2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。在数学和计算机科学中,递归指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其基本情况。

第二章  课设实现过程

2.1 实现所需算法

2.2 实现具体过程

Maze方法写入迷宫实现创建:

int createMaze();  

int createFreeMaze();  

void createWall();    

int visit(int row2, int col2) ;

int startI = 1, startJ = 1;          

int success = 0;

int maze[100][100];

int row = 0;

int col = 0;

//迷宫矩阵,2代表墙壁,0代表通道

void createWall()   

{

        for(int i = 0; i < col; i++)//行

         maze[0][i] = 2;

    for(int i = 1; i < row; i++)//列

         maze[i][0] = 2;

    for(int i = 1; i < col; i++)//最后一行

         maze[row-1][i] = 2;    

    for(int i = 1; i < row-1; i++)//最后一列

         maze[i][col-1] = 2;

递归方法调用函数(四个方向):

int visit(int row2, int col2)

{

 int endI = row-2, endJ = col-2;     

maze[row2][col2] = 1;

 if(row2 == endI && col2 == endJ)

      success = 1;

    

   if(success != 1 && maze[row2][col2+1] == 0)

          visit(row2, col2+1);

   if(success != 1 && maze[row2+1][col2] == 0)

          visit(row2+1, col2);

   if(success != 1 && maze[row2][col2-1] == 0)

          visit(row2, col2-1);

   if(success != 1 && maze[row2-1][col2] == 0)

          visit(row2-1, col2);

     if(success != 1)

        maze[row2][col2] = 0;

     return success;

}

显示迷宫的界面

int main(void)

{

int i, j;

printf("请输入迷宫行数row(0<row<100):");    

scanf("%d",&row);

printf("请输入迷宫列数col(0<col<100):");

scanf("%d",&col);

 createWall();//创建迷宫外墙

 int choice;

  printf("请选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫):");

    scanf("%d",&choice);

    if(choice == 1)

    {

        createMaze();   //创建迷宫

    }

    else if(choice == 2)

    {

         printf("\n请输入自定义迷宫的墙壁和通道,2代表墙壁,0代表通道\n");

         createFreeMaze();

     }

printf("\n显示迷宫:\n");

    for(i = 0; i < row; i++)

    {

        for(j = 0; j < col; j++)

        {

            if(maze[i][j] == 2)

                printf("█");

            else

                printf("  ");

        }

       printf("\n");

    }

    if(visit(startI, startJ) == 0)

    {

        printf("\n没有找到出口!\n");

    }

   else

   {

        printf("\n显示路径:\n");

        for(i = 0; i < row; i++)

       {

            for(j = 0; j < col; j++)

            {

                if(maze[i][j] == 2)

                    printf("█");

                else if(maze[i][j] == 1)

                    printf("◇");

                else

                    printf("  ");

            }

            printf("\n");

        }

    }

    system("pause");

    return 0;

}

2.3 实现结果

用户首先根据提示输入迷宫行数列数,再选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫)。

如果创建随机迷宫输入1,接下来程序会自动创建随机迷宫,并对迷宫进行寻找出口操作,有出口则显示含有出口路径的迷宫图,没有出口则显示:没有找到出口!

如果创建自定义迷宫,则根据提示输入代表墙壁的2或者代表通道的0组成迷宫,

有出口则显示含有出口路径的迷宫图,没有出口则显示:没有找到出口!

1、有出口的自定义迷宫

2、没有出口的随机迷宫

 3、有出口的随机迷宫

程序代码

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

int createMaze();       //创建随机迷宫
int createFreeMaze();   //创建自定义迷宫
void createWall();      //创建迷宫外墙
int visit(int row2, int col2) ;

int startI = 1, startJ = 1;          // 入口
int success = 0;
//迷宫数组
int maze[100][100];
int row = 0;
int col = 0;
//迷宫矩阵,2代表墙壁,0代表通道

//创建迷宫外墙
void createWall()   
{
    //创建迷宫外墙,第一行、第一列、最后一行、最后一列均为墙壁
    for(int i = 0; i < col; i++)//第一行
         maze[0][i] = 2;
    for(int i = 1; i < row; i++)//第一列
         maze[i][0] = 2;
    for(int i = 1; i < col; i++)//最后一行
         maze[row-1][i] = 2;    
    for(int i = 1; i < row-1; i++)//最后一列
         maze[i][col-1] = 2;
}

//创建随机迷宫
int createMaze()
{
    srand(time(0));
    for(int i = 1; i < row-1; i++)
    {
        for(int j = 1; j < col-1; j++)
        {
             if((rand()%100+1) % 2 == 0)
                maze[i][j] = 0;
             else
                maze[i][j] = 2;
         }
     }
    maze[1][1] = 0;
    maze[row-2][col-2] = 0;
}

//创建自定义迷宫
int createFreeMaze()
{
    for(int i = 1; i < row-1; i++)
    {
        //第一行,第一格为入口
        if(i == 1)
        {
           printf("迷宫第%d行,共%d格:  ",i,col-3);
           for(int j = 2; j < col-1; j++)
              scanf("%d",&maze[i][j]);
        }
        //最后一行,最后一格为出口
        else if(i == row-2)  
        {
            printf("迷宫第%d行,共%d格:",i,col-3);
            for(int j = 1; j < col-2; j++)
               scanf("%d",&maze[i][j]);
        }
        else
        {
            printf("迷宫第%d行,共%d格:",i,col-2);
            for(int j = 1; j < col-1; j++)
                scanf("%d",&maze[i][j]);
         }
     }
    maze[1][1] = 0;           //入口为通道
    maze[row-2][col-2] = 0;   //出口为通道
}

int visit(int row2, int col2) 
{ 
    int endI = row-2, endJ = col-2;      // 出口
    //该点走过,标记为1
    maze[row2][col2] = 1; 
    //走到终点,成功
    if(row2 == endI && col2 == endJ)
        success = 1; 
    //向四个方向递归调用函数visit()
    if(success != 1 && maze[row2][col2+1] == 0) 
          visit(row2, col2+1); 
    if(success != 1 && maze[row2+1][col2] == 0) 
          visit(row2+1, col2); 
    if(success != 1 && maze[row2][col2-1] == 0) 
          visit(row2, col2-1); 
    if(success != 1 && maze[row2-1][col2] == 0) 
          visit(row2-1, col2); 
 
    //该点走过,但没成功,则该点重新置为0
    if(success != 1) 
        maze[row2][col2] = 0; 
    
    return success; 
} 

int main(void) 
{ 
    int i, j;

    printf("请输入迷宫行数row(0<row<100):");    
    scanf("%d",&row);
    printf("请输入迷宫列数col(0<col<100):");
    scanf("%d",&col);

    createWall();//创建迷宫外墙

    int choice;
    printf("请选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫):");
    scanf("%d",&choice);
    if(choice == 1)
    {
        createMaze();   //创建迷宫
    }
    else if(choice == 2)
    {
         printf("\n请输入自定义迷宫的墙壁和通道,2代表墙壁,0代表通道\n");
         createFreeMaze();
     }

    printf("\n显示迷宫:\n"); 
    for(i = 0; i < row; i++)
    { 
        for(j = 0; j < col; j++) 
        {
            if(maze[i][j] == 2) 
                printf("█"); 
            else 
                printf("  "); 
        }
       printf("\n"); 
    }

    if(visit(startI, startJ) == 0)
    {
        printf("\n没有找到出口!\n"); 
    }
   else 
   { 
        printf("\n显示路径:\n"); 
        for(i = 0; i < row; i++) 
       { 
            for(j = 0; j < col; j++)
            { 
                if(maze[i][j] == 2) 
                    printf("█"); 
                else if(maze[i][j] == 1) 
                    printf("◇"); 
                else 
                    printf("  "); 
            } 
            printf("\n"); 
        } 
    }

    system("pause");

    return 0; 
}

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

X-MTing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值