用prolog

时间:2016-01-27 17:03:04

标签: prolog

我的作业似乎超出了我的课程范围(我说这是因为他们几乎没有教过我们关于prolog的任何内容),我必须写一个prolog程序来解决游戏" Flow Free"在android上。在赋值中,它被称为Numberlink。我可以在一小时内用C ++解决这个问题但是因为我对prolog不太熟悉它给我带来了麻烦。这就是我想做的事情:

  1. 创建一个包含布尔值的列表,以指示它是否已被访问或使用过。
  2. 递归搜索从给定起点到的所有可能路径 终点使用广度优先搜索来找到最短的 路径。
  3. 我猜是从那里开始。
  4. 我的尝试包括在网上搜索如何制作列表。当然prolog在任何地方都没有记录好,所以我空白并放弃了。一位朋友告诉我使用地图列表,我不知道如何用它来制作一份包含我需要的清单。

    提前致谢。

    编辑: 感谢您的链接,但我希望制作一个2D列表来代表正在播放的电路板。功能看起来像这样:

    makeList(size,list): -

    其中size是一个整数,表示方形列表ex中一个维度的大小。 (7×7)。

2 个答案:

答案 0 :(得分:4)

这是@ CapelliC解决方案的实现。代码不言自明。如果它们相邻并且具有相同的颜色,或者与相同颜色的另一个连接的块相邻,则连接2个块。 (我使用X和Y而不是行和列,这使得在最后编写条件有点令人困惑。)

在SWI-Prolog中解决

enter image description here

https://flowfreesolutions.com/solution/?game=flow&pack=green&set=5&level=1

connected(P1, P2, M, Visited) :-
    adjacent(P1, P2),
    maplist(dif(P2), Visited),
    color(P1, C, M),
    color(P2, C, M).
connected(P1, P2, M, Visited) :-
    adjacent(P1, P3),
    maplist(dif(P3), Visited),
    color(P1, C, M),
    color(P3, C, M),
    connected(P3, P2, M, [P3|Visited]).

adjacent(p(X,Y1), p(X,Y2)) :- Y2 is Y1+1.
adjacent(p(X,Y1), p(X,Y2)) :- Y2 is Y1-1.
adjacent(p(X1,Y), p(X2,Y)) :- X2 is X1+1.
adjacent(p(X1,Y), p(X2,Y)) :- X2 is X1-1.

color(p(X,Y), C, M) :-
    nth1(Y, M, R),
    nth1(X, R, C).

sol(M) :-
    M = [[1,_,_,_,1],
         [2,_,_,_,_],
         [3,4,_,4,_],
         [_,_,_,_,_],
         [3,2,5,_,5]],
    connected(p(1,1), p(5,1), M, [p(1,1)]),
    connected(p(1,2), p(2,5), M, [p(1,2)]),
    connected(p(1,3), p(1,5), M, [p(1,3)]),
    connected(p(2,3), p(4,3), M, [p(2,3)]),
    connected(p(3,5), p(5,5), M, [p(3,5)]).

示例查询:

?- sol(M).
M = [[1, 1, 1, 1, 1],
     [2, 2, 2, 2, 2], 
     [3, 4, 4, 4, 2],
     [3, 2, 2, 2, 2], 
     [3, 2, 5, 5, 5]].

答案 1 :(得分:1)

声明性Prolog'运作方式'基于非确定性,由深度优先搜索实现。让我们适用于这个难题:M是游乐场,自由单元格(变量)或整数(颜色)列表的列表

one_step(M) :-
  cell(M, X,Y, C),
  integer(C), % the selected cell is a color
  delta(X,Y,X1,Y1),
  cell(M, X1,Y1, C). % bind adjacent to same color - must be free

cell(M, X,Y, C) :- nth1(Y,M,R), nth1(X,R,C).

% moves
delta(X,Y,X1,Y) :- X1 is X+1. % right
delta(X,Y,X1,Y) :- X1 is X-1. % left
delta(X,Y,X,Y1) :- Y1 is Y-1. % up
delta(X,Y,X,Y1) :- Y1 is Y+1. % down
这是做什么的?让我们试试3x3游乐场

?- M=[[_,9,_],[_,0,_],[_,_,9]],one_step(M).
M = [[_G1824, 9, 9], [_G1836, 0, _G1842], [_G1848, _G1851, 9]] ;
M = [[9, 9, _G1830], [_G1836, 0, _G1842], [_G1848, _G1851, 9]] ;
M = [[_G1824, 9, _G1830], [_G1836, 0, 0], [_G1848, _G1851, 9]] ;
M = [[_G1824, 9, _G1830], [0, 0, _G1842], [_G1848, _G1851, 9]] ;
M = [[_G1824, 9, _G1830], [_G1836, 0, _G1842], [_G1848, 0, 9]] ;
M = [[_G1824, 9, _G1830], [_G1836, 0, _G1842], [_G1848, 9, 9]] ;
M = [[_G1824, 9, _G1830], [_G1836, 0, 9], [_G1848, _G1851, 9]] ;
false.

无需声明网格大小,检查索引边界等...当one_step / 1成功时,实例化一个空闲单元格到相邻的相同颜色...