迷宫问题的实现

#include <stdio.h>
#define MAX 5
int maze[MAX][MAX]={
{0,0,1,0,0},
{0,0,0,0,1},
{0,0,0,1,1},
{0,0,0,0,1},
{0,0,1,0,0}
};
int inThePath[MAX][MAX];//to indicate wether (x,y) is in the current path, an overhead to enhance efficency

typedef enum Orientation{
    UNKNOWDIRECTION,EAST,SOUTH,WEST,NORTH,NODIRECTION
}Orientation;
/*StepRecord is the path node record type*/
struct StepRecord{
    int x,y;//the position
    Orientation direction;//the last outgoing direction
};

struct StepRecord path[MAX*MAX];//should initilize to 0
int top = -1;

void push(struct StepRecord rec)
{
    path[++top] = rec;
}
struct StepRecord pop()
{
    return path[top--];
}
int isStackEmpty()
{
    return top == -1;
}
/*always point to the current position*/
struct StepRecord *current;
/**
*return true if pos is not int current path. the function is used to avoid infinite loop.
*/
int inPath(struct StepRecord* pos)
{
    return inThePath[pos->x][pos->y];
}
/**
 * return true if pos is inside the maze;
 */
int inMaze(struct StepRecord* pos)
{
    return (pos->x < MAX) && (pos->y < MAX) && (pos->x >= 0) && (pos->y >= 0);
}
/**
 * test maze matrix,return true if pos is blocked.
 * pos->y means which row, pos->x means which column
 */
int isNotBlocked(struct StepRecord* pos)
{
    return maze[pos->y][pos->x] == 0;
}
/**
  *test if direction of current is walkable, which means the next position indicated by direct
  *is inside the maze matrix and not in the current path (to avoid infinite loop).
*/
int testForDirection(Orientation direct)
{
    struct StepRecord tmp = *current;
    switch(direct){
        case EAST:
            tmp.x += 1;
            break;
        case SOUTH:
            tmp.y += 1;
            break;
        case WEST:
            tmp.x -= 1;
            break;
        case NORTH:
            tmp.y -= 1;
            break;
        default:
        break;
    }
    if(!inPath(&tmp) && inMaze(&tmp) && isNotBlocked(&tmp))
        return 1;
    return 0;
}
/**
 *continues to test from the next direction from last direction to NODIRECTION,return the next walkable direction of current position
*/
Orientation nextWalkableDirection()
{
    Orientation direct;
    for(direct = (Orientation)(current->direction + 1); direct < NODIRECTION; direct = (Orientation)(direct + 1))
    {
        if(testForDirection(direct)){
            return direct;
        }
    }
    return direct;
}

/**
 *advance to next walkable postion,always call nextWalkableDirection to return a valid direction
 *and pass it to this function as direction
*/
void advanceByDirection(Orientation direction)
{
    struct StepRecord nextPos = *current;
    nextPos.direction = UNKNOWDIRECTION;
    if(direction == EAST){
        nextPos.x += 1;
    }else if(direction == SOUTH){
        nextPos.y += 1;
    }else if(direction == WEST){
        nextPos.x -= 1;
    }else{
        nextPos.y -= 1;
    }
    current->direction = direction;
    push(nextPos);
        printf("(%d,%d,%d) pushed\n",nextPos.x,nextPos.y,nextPos.direction);
    inThePath[nextPos.x][nextPos.y] = 1;
    current ++;
}
/**
  *return true if a position is equal to b position;
*/
int equal(struct StepRecord* a,struct StepRecord* b)
{
    return ((a->x == b->x) && (a->y == b->y));
}
/**
  * print out the successful path
*/
void printPath()
{
    for(int i = 0; i <= top; i++)
        printf("(%d,%d)\n",path[i].x,path[i].y);
}
/**
  * return back to previous position
*/
void stepBack()
{
    struct StepRecord tmp = pop();
    printf("(%d,%d,%d) poped\n",tmp.x,tmp.y,tmp.direction);
    inThePath[tmp.x][tmp.y] = 0;
    current--;
}

int main(void)
{
    struct StepRecord start = {0,0,UNKNOWDIRECTION};
 //   struct StepRecord sentinel = start;
    struct StepRecord final = {4,4,UNKNOWDIRECTION};
    Orientation direction;
 //   push(sentinel);
    push(start);
    current = path;
    while(!equal(current,&final) && !isStackEmpty())
    {
        direction = nextWalkableDirection();
        if(direction == NODIRECTION){
            stepBack();
        }else{
            advanceByDirection(direction);
        }
    }
    if(isStackEmpty()){
        printf("no path to the end");
        return 0;
    }
    printPath();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值