用C语言编写一个迷宫程序,知道出处也行 ~~!

用C语言编写一个迷宫程序,知道出处也行 ~~!,第1张

#include<stdio.h>

#include<stdlib.h>

#define M 15

#define N 15

struct mark //定义迷宫内点的坐标类型

{

int x

int y

}

struct Element //"恋"栈元素,嘿嘿。。

{

int x,y//x行,y列

int d//d下一步的方向

}

typedef struct LStack //链栈

{

Element elem

struct LStack *next

}*PLStack

/*************栈函数****************/

int InitStack(PLStack &S)//构造空栈

{

S=NULL

return 1

}

int StackEmpty(PLStack S)//判断栈是否为空

{

if(S==NULL)

return 1

else

return 0

}

int Push(PLStack &S, Element e)//压入新数据元素

{

PLStack p

p=(PLStack)malloc(sizeof(LStack))

p->elem=e

p->next=S

S=p

return 1

}

int Pop(PLStack &S,Element &e) //栈顶元素出栈

{

PLStack p

if(!StackEmpty(S))

{

e=S->elem

p=S

S=S->next

free(p)

return 1

}

else

return 0

}

/***************求迷宫路径函数***********************/

void MazePath(struct mark start,struct mark end,int maze[M][N],int diradd[4][2])

{

int i,j,dint a,b

Element elem,e

PLStack S1, S2

InitStack(S1)

InitStack(S2)

maze[start.x][start.y]=2//入口点作上标记

elem.x=start.x

elem.y=start.y

elem.d=-1//开始为-1

Push(S1,elem)

while(!StackEmpty(S1)) //栈不为空 有路径可走

{

Pop(S1,elem)

i=elem.x

j=elem.y

d=elem.d+1//下一个方向

while(d<4) //试探东南西北各个方向

{

a=i+diradd[d][0]

b=j+diradd[d][1]

if(a==end.x &&b==end.y &&maze[a][b]==0) //如果到了出口

{

elem.x=i

elem.y=j

elem.d=d

Push(S1,elem)

elem.x=a

elem.y=b

elem.d=886//方向输出为-1 判断是否到了出口

Push(S1,elem)

printf("\n0=东 1=南 2=西 3=北 886为则走出迷宫\n\n通路为:(行坐标,列坐标,方向)\n")

while(S1) //逆置序列 并输出迷宫路径序列

{

Pop(S1,e)

Push(S2,e)

}

while(S2)

{

Pop(S2,e)

printf("-->(%d,%d,%d)",e.x,e.y,e.d)

}

return//跳出两层循环,本来用break,但发现出错,exit又会结束程序,选用return还是不错滴

}

if(maze[a][b]==0) //找到可以前进的非出口的点

{

maze[a][b]=2//标记走过此点

elem.x=i

elem.y=j

elem.d=d

Push(S1,elem)//当前位置入栈

i=a//下一点转化为当前点

j=b

d=-1

}

d++

}

}

printf("没有找到可以走出此迷宫的路径\n")

}

/*************建立迷宫*******************/

void initmaze(int maze[M][N])

{

int i,j

int m,n//迷宫行,列 [/M]

printf("请输入迷宫的行数 m=")

scanf("%d",&m)

printf("请输入迷宫的列数 n=")

scanf("%d",&n)

printf("\n请输入迷宫的各行各列:\n用空格隔开,0代表路,1代表墙\n",m,n)

for(i=1i<=mi++)

for(j=1j<=nj++)

scanf("%d",&maze[i][j])

printf("你建立的迷宫为(最外圈为强)...\n")

for(i=0i<=m+1i++) //加一圈围墙

{

maze[i][0]=1

maze[i][n+1]=1

}

for(j=0j<=n+1j++)

{

maze[0][j]=1

maze[m+1][j]=1

}

for(i=0i<=m+1i++) //输出迷宫

{

for(j=0j<=n+1j++)

printf("%d ",maze[i][j])

printf("\n")

}

}

void main()

{

int sto[M][N]

struct mark start,end//start,end入口和出口的坐标

int add[4][2]={{0,1},{1,0},{0,-1},{-1,0}}//行增量和列增量 方向依次为东西南北 [/M]

initmaze(sto)//建立迷宫

printf("输入入口的横坐标,纵坐标[逗号隔开]\n")

scanf("%d,%d",&start.x,&start.y)

printf("输入出口的横坐标,纵坐标[逗号隔开]\n")

scanf("%d,%d",&end.x,&end.y)

MazePath(start,end,sto,add)//find path

system("PAUSE")

}

下面的代码假定你的迷宫数据一定是合法的 (单一的入口和出口,不会打环,不会无解),如果数据不合法,可能导致死循环,数据合法性的检查你自己实现。

另外,我用 东南西北四个方向来代替所谓的上下左右,因为左右概念是相对的。 用python 2。

puzzle_walk 函数返回一个list, 每个元素是每次移动的路径坐标, 其第一个参数为迷宫的list数据, 第二个参数默认为 True 表示左手抹墙, False 则是右手抹墙。

简单说一下算法:首先找到入口格,设定初始面向 East ( 如果是右手抹墙则是 West),然后重复执行以下 *** 作:

 1. 如果当前格为最后一排且向南可以移动,则说明当前格为终点,结束。

 2. 根据当前格的数据,找到下一步需要面向的方向, 方法是,如果当前方向上有墙,则顺时针(右手抹墙则逆时针)转身,重复这一步骤直到面向的方向上可以行走. 这里可以参考 turn 函数

 3. 沿当前方向走一步, 参考 move 函数

 4. 逆时针(右手抹墙则顺时针)转身一次,使当前面对方向为第3步之后的左手(或右手)方向, 然后回到步骤1

最后, 我的代码假定迷宫入口一定是从第1行的North 方向进入,出口一定是从最后一行的 South 方向出去,如果要支持从第一行的其他方向进(比如从 (0, 0) 的West进) ,最后一行的其他方向出,你需修改查找入口的代码和判断出口的代码,这个很简单, 自己去搞定吧。

N = 0

E = 1

S = 2

W = 3

class Walker(object):

    def __init__(self, x, y, direction):

        # coordinates

        self.x = x

        self.y = y

        self.direction = direction

    def turn(self, clockwise=True):

        if clockwise:

            self.direction = (self.direction + 1) % 4

        else:

            self.direction = (self.direction + 4 - 1) % 4

        

    def move(self):

        if self.direction == N:

            self.x -= 1

        elif self.direction == E:

            self.y += 1

        elif self.direction == S:

            self.x += 1

        elif self.direction == W:

            self.y -= 1

    def get_coords(self):

        return (self.x, self.y)

    def get_direction(self):

        return self.direction

        

            

def puzzle_walk(puzzle, left_touching=True):

    route = []

    rows = len(puzzle)

    columns = len(puzzle[0])

    # locate the entrance

    coords = (-1, -1)

    for y in range(columns):

        cell = puzzle[0][y]

        if cell[N]:

            coords = (0, y)

            break

    assert coords[0] >= 0 and coords[1] >= 0

    walker = Walker(coords[0], coords[1], E if left_touching else W)

    while True:

        x, y = walker.get_coords()

        cell = puzzle[x][y]

        route.append(tuple([x, y]))

        if x == rows-1 and cell[S]:

            # found the exit

            break

        # turn to the direction where no wall blocks

        while not cell[walker.get_direction()]:

            walker.turn(left_touching)

        # move

        walker.move()

        # face to the direction of the hand

        walker.turn(not left_touching)

    return route

        

# 运行结果

>>> p=[[(False, True, True, False), (True, True, False, True), (False, False, True, True)], [(True, False, True, False), (False, True, False, False), (True, False, False, True)]]

# 左手抹墙

>>> puzzle_walk(p)

[(0, 1), (0, 2), (1, 2), (1, 1), (1, 2), (0, 2), (0, 1), (0, 0), (1, 0)]

# 右手抹墙

>>> puzzle_walk(p, False)

[(0, 1), (0, 0), (1, 0)]


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11997392.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存