【高质量代码实践】【栈】迷宫游戏

/*
                    三江学院 电子信息工程
文件名:use.c
摘要:经典的迷宫问题,通过数据结构————“栈”和回朔思想,解决迷宫问题。
完成日期:2012-7-1  23:55
作者:黄路
当前版本:1.2
*/
#include <stdio.h>
#include "stack.h"

//定义一个迷宫数组,1代表障碍,0代表畅通
int maze[M][N] = {  0, 0, 0, 1, 1, 1,
                    0, 1, 0, 0, 1, 1,
                    1, 0, 1, 0, 0, 0,
                    1, 0, 1, 0, 1, 0,
                    1, 1, 1, 1, 1, 0,
                    1, 1, 1, 1, 1, 0};

seqstack seq;//栈
seqstack *s; //栈指针
datatype temp; //当前数据结点

int main()
{
     //int i = 0;
     //int j = 0;
     int r = 0;

     //每次移动的方向    x, y, d
                    //   j, i
     datatype move[4] = {0, 1, 0, "RIGHT",
                         1, 0, 1, "DOWN",
                         0, -1, 2, "LEFT",
                         -1, 0, 3, "UP"};
     s = &seq;


     r = mazepath(maze, move);//找迷宫的一条有效路径

     if(r == 1)
     {
          printf("the valid paht is (step from exit to entry):\n");
          while(!empty_stack(s))
          {
               pop_stack(s, &temp);//将出栈值放入temp中,并打印内容
               printf("<%d, %2d>, %s\n", temp.x, temp.y, move[temp.d].dir);
          }
     }
     else
     {
          printf("there is not a valid path!\n");
     }
     return 0;
}

/*
                    三江学院 电子信息工程
文件名:stack.h
摘要:全局变量定义,函数声明,栈结构定义,数据元素定义
完成日期:2012-7-1  23:55
作者:黄路
当前版本:1.2
*/
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#define M 6//迷宫实际的行数
#define N 6 // 迷宫实际的列数
#define MAXSIZE 2000//栈最大的深度

/*
数据元素
x,y描述它的位置;
d描述它的前行方向 ;
dir对d的文字表述
*/
typedef struct datatype
{
     int x;
     int y;
     int d;
     char dir[6];
}datatype;

/*
data[]是栈元素;
top是栈序号,即某个元素在栈中的位置!
*/
typedef struct seqstack
{
     datatype data[MAXSIZE];
     int top;
}seqstack;


//寻找迷宫的一条路径
int mazepath(int maze[][N], datatype *move);
//进栈
int push_stack(seqstack *s, datatype x);
//判断栈是否为空
int empty_stack(seqstack *s);
//出栈
int pop_stack(seqstack *s, datatype *x);
#endif // STACK_H_INCLUDED

/*
                    三江学院 电子信息工程
文件名:stack.c
摘要:函数定义,包括路径查找,入栈,出栈,空栈判断
完成日期:2012-7-1  23:55
作者:黄路
当前版本:1.2
*/
#include <stdio.h>
#include "stack.h"
//方向定义
#define RIGHT 0
#define DOWN 1
#define LEFT 2
#define UP   3
#define DIRECTIONS 4

seqstack seq;
seqstack *s;
datatype temp;

/*
设计思路——回朔:
如果当前结点可走,标记走过的方向,入栈,进入下一结点,且每个结点都是依据右,下, 左,上的次序
来遍历的,如果当前结点不可走,出栈,遍历,直到找到出口,或者栈空为止。
*/
int mazepath(int maze[][N], datatype move[])
{
     //表示当前的横纵坐标
     int x = 0;
     int y = 0;
     //i , j 表示下一个可走的坐biao; 表示方向
     int d = -1;
     int i = 0;
     int j = 0;
     //初始化入口
     temp.x = 0;
     temp.y = 0;
     temp.d = -1;
     maze[0][0] = -1; //标识已走过的路径

     push_stack(s, temp);// 将temp之压入栈

     while(!empty_stack(s))
     {
          pop_stack(s, &temp);//将出栈值存入temp,进行处理
          x = temp.x;
          y = temp.y;
          d = temp.d + 1;     //变向

          while(d < DIRECTIONS)//依次遍历4个方向寻找可以走通的路径
          {
               /*
               funtions:for location
               if it reaches the boundary, it will change directions in the order of RIGHT, DOWN, LEFT,UP.
               otherwise,
               go right, j + 1;
               go left,  j - 1;
               go up, i - 1;
               go down, i + 1;
               */
               switch(d)
               {
                    case RIGHT : if (y == N - 1) //纵坐标,N代表列数
                                 {
                                      d++;   //右边到达边界了
                                 }
                                 else
                                 {
                                      j = y + move[d].y;   //j = 1
                                 }
                                 i = x + move[d].x;        //i = 0
                                 break;
                    case DOWN : if (x == M - 1)  //下边界了
                                {
                                     d++;
                                }
                                else
                                {
                                     i = x + move[d].x;    //i = 1
                                }
                                j = y + move[d].y;         //j = 0
                                break;
                   case LEFT : if (x == 0)      //左边界了
                               {
                                    d++;
                               }
                               else
                               {
                                   i = x + move[d].x;      //i = -1
                               }
                               j = y + move[d].y;          //j = 0
                               break;
                   case UP : if (y == 0)        //上边界了
                             {
                                  d++;
                             }
                             else
                             {
                                  j = y + move[d].y;        //j = -1
                             }
                             i = x + move[d].x;             //i = 0
                             break;

                   default : printf("direction error!\n");
                            break;
               }

               if (maze[i][j] == 0)     //next direction is securable
               {
                    //保存当前位置,入栈
                    temp.x = x;
                    temp.y = y;
                    temp.d = d;
                    maze[x][y] = -1;  //mark visitd position
                    push_stack(s, temp); //push temp into stack

                    //进入下一个位置
                    x = i;
                    y = j;
                    //判断是否找到出口?
                    if ((x + 1) == M && (y + 1) == N) //find one pace
                    {
                         return 1;
                    }
                    else
                    {
                         d = 0;//重新开始遍历
                    }
               }
               else
               {
                    d++;    //当前方向没有找到可以走的点,于是改变方向
               }
          }
     }
     return 0;
}

/*
入栈
输入:栈指针seqstack *s,结点datatype x
输出:1,表示入栈成功,0表示入栈失败;
*/
int push_stack(seqstack *s, datatype x)
{
     //上溢 保护
     if ( MAXSIZE - 1 == s->top )
     {
          return 0;
     }

     else
     {
          s->top++; //栈顶上移
          s->data[s->top] = x;
          return 1;
     }
}
/*
判断栈是否为空 ,目的是防止‘下 溢’
输入:栈指针seqstack *s
返回:1,表示栈空;0,表示栈非空。
*/
int empty_stack(seqstack *s)
{
     if (0 == s->top)
     {
          return 1;
     }
     else
     {
          return 0;
     }
}
/*
出栈
输入:栈指针sqstack *s,结点指针datatype *x
*/
int pop_stack(seqstack *s, datatype *x)
{
     if(empty_stack(s))
     {
          return 0;
     }
     else
     {
          *x = s->data[s->top]; //修改了结点指针,它是个全局变量
          s->top--;
          return 1;
     }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值