编写一个Prolog程序来模拟大猩猩在网格上移动
我很少用Prolog编程,到目前为止,我觉得很难 我被问到一个问题:大猩猩沿着8x8网格移动,只能向右或向上移动。它必须保持在网格内,并且必须在(8,8)处结束,从任意位置开始 编写一个描述所有可能移动的移动谓词 我的尝试:编写一个Prolog程序来模拟大猩猩在网格上移动,prolog,Prolog,我很少用Prolog编程,到目前为止,我觉得很难 我被问到一个问题:大猩猩沿着8x8网格移动,只能向右或向上移动。它必须保持在网格内,并且必须在(8,8)处结束,从任意位置开始 编写一个描述所有可能移动的移动谓词 我的尝试: move(X,Y,X+1,Y). move(X,Y,X,Y+1). path('right'):- move(X,Y,X+1,Y). path('up'):- move(X,Y,X,Y+1). 编写一个路径谓词,该谓词使用移动谓词来确定机器人应该选择的路
move(X,Y,X+1,Y).
move(X,Y,X,Y+1).
path('right'):-
move(X,Y,X+1,Y).
path('up'):-
move(X,Y,X,Y+1).
编写一个路径谓词,该谓词使用移动谓词来确定机器人应该选择的路径
我的尝试:
move(X,Y,X+1,Y).
move(X,Y,X,Y+1).
path('right'):-
move(X,Y,X+1,Y).
path('up'):-
move(X,Y,X,Y+1).
编写prolog谓词,对(1,2)、(4,2)和(4,1)处的阻塞进行建模
到目前为止,从我发现的情况来看,我似乎需要建立一个列表,列出所有可能的职位
我写了一份可能的职位清单,但不了解如何实施:
[(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),
(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8),
(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(3,8),
(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8),
(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8),
(6,1),(6,2),(6,3),(6,4),(6,5),(6,6),(6,7),(6,8),
(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7),(7,8),
(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8)]
这似乎是一个简单的程序,但我似乎无法掌握这些概念,或者至少无法将它们组合成一个可行的程序
任何方向上的帮助都将不胜感激。因此,您可能希望在这样做的同时说出您的移动位置。因此,我建议使用如下谓词
move/3
:
% move(From_Position, To_Position, Direction).
move((X,Y),(X,Y1), up) :-
grid(G),
member((X,Y1),G),
Y1 is Y + 1.
move((X,Y),(X1,Y), rigth):-
grid(G),
member((X1,Y),G),
X1 is X + 1.
网格调用用于确保您始终保持在网格上。您还可以在网格中使用更智能的谓词,避免成员调用(这相当耗时)
路径可能应该是一个方向列表:
path((8,8), []).
path(Position, [Direction| Before]):-
\+ Position = (8,8),
move(Position, NewPosition, Direction),
path(NewPosition,Before).
要累积,您可以使用bagof
或setof
all_paths(Position,Paths):-
setof(Path,path(Position,Path),Paths).
所以你可能想说你在做这件事的时候要去哪里。因此,我建议使用如下谓词move/3
:
% move(From_Position, To_Position, Direction).
move((X,Y),(X,Y1), up) :-
grid(G),
member((X,Y1),G),
Y1 is Y + 1.
move((X,Y),(X1,Y), rigth):-
grid(G),
member((X1,Y),G),
X1 is X + 1.
网格调用用于确保您始终保持在网格上。您还可以在网格中使用更智能的谓词,避免成员调用(这相当耗时)
路径可能应该是一个方向列表:
path((8,8), []).
path(Position, [Direction| Before]):-
\+ Position = (8,8),
move(Position, NewPosition, Direction),
path(NewPosition,Before).
要累积,您可以使用bagof
或setof
all_paths(Position,Paths):-
setof(Path,path(Position,Path),Paths).
所以你可能想说你在做这件事的时候要去哪里。因此,我建议使用如下谓词move/3
:
% move(From_Position, To_Position, Direction).
move((X,Y),(X,Y1), up) :-
grid(G),
member((X,Y1),G),
Y1 is Y + 1.
move((X,Y),(X1,Y), rigth):-
grid(G),
member((X1,Y),G),
X1 is X + 1.
网格调用用于确保您始终保持在网格上。您还可以在网格中使用更智能的谓词,避免成员调用(这相当耗时)
路径可能应该是一个方向列表:
path((8,8), []).
path(Position, [Direction| Before]):-
\+ Position = (8,8),
move(Position, NewPosition, Direction),
path(NewPosition,Before).
要累积,您可以使用bagof
或setof
all_paths(Position,Paths):-
setof(Path,path(Position,Path),Paths).
所以你可能想说你在做这件事的时候要去哪里。因此,我建议使用如下谓词move/3
:
% move(From_Position, To_Position, Direction).
move((X,Y),(X,Y1), up) :-
grid(G),
member((X,Y1),G),
Y1 is Y + 1.
move((X,Y),(X1,Y), rigth):-
grid(G),
member((X1,Y),G),
X1 is X + 1.
网格调用用于确保您始终保持在网格上。您还可以在网格中使用更智能的谓词,避免成员调用(这相当耗时)
路径可能应该是一个方向列表:
path((8,8), []).
path(Position, [Direction| Before]):-
\+ Position = (8,8),
move(Position, NewPosition, Direction),
path(NewPosition,Before).
要累积,您可以使用bagof
或setof
all_paths(Position,Paths):-
setof(Path,path(Position,Path),Paths).
你的代码有很多问题。让我们一次看一个
1。可能的职位
虽然你的可能职位列表还可以,但我不会那样硬编码。检查位置是否在网格上非常容易:
grid_position(X, Y) :-
X >= 1,
X =< 8,
Y >= 1,
Y =< 8.
使用这个,我们可以确定大猩猩允许的位置:网格上的任何位置,但没有被阻止
allowed_position(X, Y) :-
grid_position(X, Y),
\+blocked(X, Y).
3。移动
这里的主要问题是,在子句的开头写入X+1
,并不像您认为的那样。要计算算术表达式,需要使用is
谓词
此外,我只允许在允许下一个位置的情况下移动。因为大猩猩已经在当前位置,所以我不包括检查这个位置是否被允许
move(X, Y, X2, Y) :-
X2 is X + 1,
allowed_position(X2, Y).
move(X, Y, X, Y2) :-
Y2 is Y + 1,
allowed_position(X, Y2).
4。路径
以下是我对需求的解释:给定开始位置,返回用于到达结束位置的移动列表
path(X, Y, [(X,Y)|Ps]) :-
move(X, Y, X2, Y2),
path(X1, Y1, Ps).
为此,我们需要3个参数:X和Y位置,以及输出。这里的输出将是一个位置列表,而不是一个移动列表,如果需要的话,我将把它留给您来更改
那么,是什么组成了我们的道路?首先你移动一步,然后从下一个位置找到剩下的路径
path(X, Y, [(X,Y)|Ps]) :-
move(X, Y, X2, Y2),
path(X1, Y1, Ps).
当然,我们必须确保这在目标位置结束,因此对于基本情况,我们可以使用:
path(8, 8, (8, 8)).
您可能还需要验证初始位置是否为允许的位置,我已经忽略了这一点
组合所有内容,您将得到如下输出
?- path(5,6,L).
L = [(5,6),(6,6),(7,6),(8,6),(8,7)|(8,8)] ? ;
L = [(5,6),(6,6),(7,6),(7,7),(8,7)|(8,8)] ? ;
L = [(5,6),(6,6),(7,6),(7,7),(7,8)|(8,8)] ? ;
...
这可能不是您想要的,但我希望它能帮助您顺利完成任务。您的代码存在一些问题。让我们一次看一个
1。可能的职位
虽然你的可能职位列表还可以,但我不会那样硬编码。检查位置是否在网格上非常容易:
grid_position(X, Y) :-
X >= 1,
X =< 8,
Y >= 1,
Y =< 8.
使用这个,我们可以确定大猩猩允许的位置:网格上的任何位置,但没有被阻止
allowed_position(X, Y) :-
grid_position(X, Y),
\+blocked(X, Y).
3。移动
这里的主要问题是,在子句的开头写入X+1
,并不像您认为的那样。要计算算术表达式,需要使用is
谓词
此外,我只允许在允许下一个位置的情况下移动。因为大猩猩已经在当前位置,所以我不包括检查这个位置是否被允许
move(X, Y, X2, Y) :-
X2 is X + 1,
allowed_position(X2, Y).
move(X, Y, X, Y2) :-
Y2 is Y + 1,
allowed_position(X, Y2).
4。路径
以下是我对需求的解释:给定开始位置,返回用于到达结束位置的移动列表
path(X, Y, [(X,Y)|Ps]) :-
move(X, Y, X2, Y2),
path(X1, Y1, Ps).
为此,我们需要3个参数:X和Y位置,以及输出。这里的输出将是一个位置列表,而不是一个移动列表,如果需要的话,我将把它留给您来更改
那么,是什么组成了我们的道路?好吧,首先你做一个动作,一个动作