2016-11-04 43 views
2

寻路问题,所以我这里有一个序言程序,需要输入这样的:在序言

mazepath(X,Y,Maze,Path,Score) 
mazepath(1, 1, [[ o, e, j, p, o], 
    [ o, j, o, o, o], 
    [ o, j, mt, j, o], 
    [ o, o, e, o, o], 
    [ p, o, j, mb, o]], Path, Score). 

当几乎所有你需要知道的是J的是墙壁基本相符。我需要做的是从地图右上角开始(1,1)我需要找到p,e,然后找到mb,然后按照这个顺序找到mt。这里是我当前的代码:

mazePath(X,Y,Maze,Path,Score) :- 
    curVal(X,Y,Maze,V0), %Get the value of the starting point 
    findMasterball(X,Y,V0,Maze,Path,PathMB), %Find a path to the Masterball. 
    nth1(1,PathMB,Room0), %Use the path generated by findMasterball to get the starting point for findMewtoo 
    nth1(1,Room0,Xk), 
    nth1(1,Room0,Yk), 
    curVal(Xk,Yk,Maze,V1), %Get the value of the Masterball point 
    findMewtoo(Xk,Yk,V1,Maze,[[Xk,Yk]],PathM), %Found masterball, starting for Mewtoo 
    nth1(1,PathM,Room1), %Now find pika 
    nth1(1,Room1,Xs), 
    nth1(1,Room1,Ys), 
    curVal(Xs,Ys,Maze,V2), %Get the value of the 
    findPika(Xs,Ys,V2,Maze,[[Xs,Ys]]). %Find pika 

% findMasterball - recursive predicate that searches for the Masterball 
% X,Y - current location 
% Val - current value of location 
% PathMB - Path traveled so far 
% newPath - Path returned 
% 
%Base Case 
findMasterball(_,_,Val,_,PathMB,PathMB) :- 
    Val == 'mb', 
    length(PathK,L), 
    format('~w ~w',['\nPATH TO THE Masterball: ', PathK]), 
    format('~w ~w',['\nLENGTH OF PATH: ', L]). 

%Recursive Case 
findMasterball(X,Y,_,Maze,PathMB,newPath) :- 
    nth1(1,Maze,R), %Get width and height of the maze 
    length(R,W), 
    length(Maze,H), 
    nextMove(X,Y,Xn,Yn,Maze,W,H), %Find the next legal move 
    curVal(Xn,Yn,Maze,NVal), %Get the value of the next location 
    \+ memberchk([Xn,Yn],PathMB), %Make sure we have not traveled to this location before 


findMewtoo(_,_,Val,_,PathM,PathM) :- 
    Val == 'mt', 
    length(PathM,L), 
    format('~w ~w',['\n\nPATH TO THE SWORD: ', PathM]), 
    format('~w ~w',['\nLENGTH OF PATH: ', L]). 

%Recursive Case 
findMewtoo(X,Y,_,Maze,PathM,rPathM) :- 
    nth1(1,Maze,R), %Get width and height of the maze 
    length(R,W), 
    length(Maze,H), 
    nextMove(X,Y,Xn,Yn,Maze,W,H), %Find the next legal move 
    curVal(Xn,Yn,Maze,NVal), %Get the value of the next location 
    \+ memberchk([Xn,Yn],PathM), %Make sure we have not traveled to this location before 
    findMewtoo(Xn,Yn,NVal,Maze,[[Xn,Yn]|PathM],rPathM). %Recursive call with the next location/value 

% findPika - recursive predicate that searches for Pikachoo 
% X,Y - current location 
% Val - current value of location 
% PathPika - Path traveled so far 
% 
%Base Case 
findPika(_,_,Val,_,PikaPath) :- 
    Val == 'p', 
    length(PikaPath,L), 
    format('~w ~w',['\n\nPATH TO THE DUNGEON LORD: ', PikaPath]), 
    format('~w ~w',['\nLENGTH OF PATH: ', L]). 

%Recursive Case 
findPika(X,Y,_,Maze,PikaPath) :- 
    nth1(1,Maze,R), %Get width and height of the maze 
    length(R,W), 
    length(Maze,H), 
    nextMove(X,Y,Xn,Yn,Maze,W,H), %Find the next legal move. Doors are walkable. 
    curVal(Xn,Yn,Maze,NVal), %Get the value of the next location 
    \+ memberchk([Xn,Yn],PikaPath), %Make sure we have not traveled to this location before 


% X0, Y0 - Current Location 
% X, Y - Variables - Next move will be bound to these variables 
% Maze 
% W, H - Width and height of the maze 
nextMove(X0,Y0,X,Y,Maze,W,H) :- 
    adj(X0,Y0,X,Y), 
    inBounds(X,Y,W,H). 


% Up 
adj(X0,Y0,X0,Y) :- 
    Y is Y0+1. 

% Down 
adj(X0,Y0,X0,Y) :- 
    Y is Y0-1. 

% Right 
adj(X0,Y0,X,Y0) :- 
    X is X0+1. 

% Left 
adj(X0,Y0,X,Y0) :- 
    X is X0-1. 

% Is X,Y within the bounds of the maze 
inBounds(X,Y,W,H) :- 
    X >= 1, 
    Y >= 1, 
    X =< W, 
    Y =< H. 

% Open space. 
roomOpen(X,Y,Maze) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,'o'). 

% This is an egg, pick it up 
roomOpen(X,Y,Maze) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,'e'). 

% Here's pikachoo 
roomOpen(X,Y,Maze) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,'p'). 

% Is the masterball there? Pick it up & go catch mewtoo! 
roomOpen(X,Y,Maze) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,'mb'). 

% Is the mewtoo there? Catch it if you have the masterball!! 
roomOpen(X,Y,Maze) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,'mt'). 


%Binds the value of the location of X,Y to Val 
curVal(X,Y,Maze,Val) :- 
    nth1(Y,Maze,R), 
    nth1(X,R,Val). 

现在,当我将其加载到SWI,但只要我打电话mazepath上面一些奇怪的试验正在发生的事情我的代码“规定”罚款。当我追踪它时,它正在看相邻的方格,看看我们是否可以走到一个方格。它从(1,1)开始,所以(1,0)和(0,1)在试图走到那里时会失败。好吧,但是当我的程序看起来(0,1),inBounds失败时,整个程序返回false而不是继续并找到路径。我不明白为什么它只是看着(1,1)周围的空间,而不是转向开放的空间并再次寻找高手球。有任何想法吗?

+0

*“我的代码在我将它加载到SWI时符合要求”*是否?当我加载你的代码时,我得到了两个'运算符优先级冲突错误',一个单例变量和'nextmove/7'的警告没有被定义。 – Fatalize

回答

4

有编译问题与您的代码:

  • findMasterball/6递归情况:你有最后条款\+ memberchk([Xn,Yn],PathMB),而不是一段时间后一个逗号。
  • findPika/5的递归大小写:在最后一个子句\+ memberchk([Xn,Yn],PikaPath)后面有一个逗号,而不是一个句点。

也有语义的问题与您的代码:

  • findMewtoo/6,最后一个参数是在头rPathM和递归调用:这是一个原子,而不是一个变量,这几乎是当然不是你想要的。将r更改为R

  • findMasterball/6中存在相同的问题,头部的参数newPath

修复这一切之后,你仍然会发现SWI-Prolog的告诉你:

Warning: c:/test.pl:1: 
     Singleton variables: [Score] 
Warning: c:/test.pl:29: 
     Singleton variables: [NewPath,NVal] 
Warning: c:/test.pl:67: 
     Singleton variables: [NVal] 
Warning: c:/test.pl:80: 
     Singleton variables: [Maze] 

这意味着在那些线(对应于治头)这些变量只能使用一次在整个规则中,这几乎肯定意味着这是一个错误:因为Prolog是关于变量之间的关系的,所以几乎总是没有意义,变量只会出现一次。这意味着我们不关心该变量的值(在这种情况下用_将其匿名),或者您的程序错误,因为某些变量使用不当。