通过迷宫20x20的旅程,有2个进入和2个退出

时间:2014-11-06 18:04:24

标签: prolog

我试着穿越迷宫。实验室的长度。是20x20,它有两个入口和两个东。

entrance(1,3).

east(4,5).

enter1(20,8).

enter2(15,4).

exit1(14,2).

exit2(2,8).

wall(1,1).
wall(1,2).
wall(1,4).
wall(1,5).
wall(2,2).
wall(2,2).
wall(2,4).
wall(2,5).
wall(3,1).
wall(3,2).
wall(3,5).
wall(4,1).
wall(4,2).
wall(4,3).
wall(5,1).
wall(5,2).
wall(5,3).
wall(5,4).
wall(4,5).

member(X,[X|_]).
member(X,[_|T]) :- member(X,T) .

go(ZX,ZY,CZ,ZY) :- CX is ZX + 1, not(wall(CX,ZY)), CX < 21, CX > 0.
go(ZX,ZY,CZ,ZY) :- CX is ZX - 1, not(wall(CX,ZY)), CX < 21, CX > 0.
go(ZX,ZY,ZX,CY) :- CY is ZY + 1, not(wall(ZX,CY)), CY < 21, CY > 0.
go(ZX,ZY,ZX,CY) :- CY is ZY - 1, not(wall(ZX,CY)), CY < 21, CY > 0.

find_way( a(X,Y)  , a(X,Y) , P ) :-
  write(P).
find_way( a(X,JY) , a(I,J) , P ) :-
  go(X,Y,NI,NJ) ,
  not( member(a(NI, NJ) , P ) ,
  find_way( a(NI,NJ) , a(I,J) , [a(NI,NJ),P] ).

way :-
  entrance(X,Y) ,
  east(S,K) ,
  find_way( a(X,Y) , a(S,K) , [ ] ) .

我有这个:

find_way(enter1(20,8),exit1(14,2), P).

但是当我使用它时,它会失败。有人能告诉我,我该怎样才能让它发挥作用呢?

1 个答案:

答案 0 :(得分:2)

目前还不清楚你的模型是如何运作的。例如,

  • 什么是east/2
  • 什么是entrance1/2entrance2/2
  • 什么是exit1/2exit2/2

但是,您的模型似乎将迷宫定义为网格,其中某些单元格标记为墙壁,入口或出口。此外,您似乎以负面的术语定义事物,而不是定义每个单元格之间的连接。

但无论如何,通过迷宫找到一条路径只是一种图形遍历,就像这样。

首先,一些定义:

  • 单元格表示为X / Y对,因此:X:Y

  • wall/1
    定义作为墙的单元格。

  • entrance/1
    定义标记为入口的单元格。我在这里放弃了一个明确的出口:一个人可以通过门口任意一个方向。

这两个谓词都将一个X:Y对作为单个参数。

所以,为了找到通过迷宫的路径,我们可以这样做:

find_path_through_maze( P ) :- % to find a path through a maze, 
  entrance(X,Y) ,              % - we first need to find an entrance
  explore( X:Y , [] , V ) ,    % - and then we go exploring, seeding it with an empty list of visited cells
  reverse(V,P)                 % once we're done, we reverse the path we got and unify it with the result
  .                            % Easy!

找到路径很简单:

explore( X:Y , [V|Vs] , [X:Y|V] ) :-  % we can exit the maze via any entrance
  entrance(X:Y) ,                     % - though note the stricture that the visited list has to be non-empty
  .                                   % 
explore( X:Y , V , P ) :-             % otherwise
  adjacent(X:Y,X1:Y1) ,               % - we find an adjacent room
  \+ visited(X1:Y1,V) ,               % - that we haven't yet visited
  explore_maze( X1:Y1 , [X:Y|V] , P ) % - and [recursively explore that
  .                                   % Easy!

确定我们是否访问过一个房间也很简单。它应该是不言自明的:

visited( X:Y , [X:Y|_] ) :- ! .
visited( X:Y , [V|Vs]  ) :-
  V \= X:Y ,
  visited(X:Y,Vs)
  .

确定邻接可能是最复杂的练习:

adjacent( X:Y , X1:Y1 ) :-        % an adjacent room is computed by
  offset( Offset_X , Offset_Y ) , % - getting an pair of offsets
  X1 is X + Offset_X ,            % - incrementing the X value by its offset
  between(1,20,X1) ,              % - the result must be within the valid domain of X
  Y1 is Y + offset_Y ,            % - incrementing the Y value by its offset
  between(1,20,Y1) ,              % - the result must be within the valid domain of Y
  \+ wall(X1,Y1)                  % - Make sure we don't walk into a wall
  .                               %

offset( -1 , -1 ) .
offset( -1 ,  0 ) .
offset( -1 ,  1 ) .
offset(  0 , -1 ) .
offset(  0 ,  1 ) .
offset(  1 , -1 ) .
offset(  1 ,  0 ) .
offset(  1 , -1 ) .