我试着穿越迷宫。实验室的长度。是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).
但是当我使用它时,它会失败。有人能告诉我,我该怎样才能让它发挥作用呢?
答案 0 :(得分:2)
目前还不清楚你的模型是如何运作的。例如,
east/2
?entrance1/2
或entrance2/2
?exit1/2
或exit2/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 ) .