用序言解决Numberlink难题

MrJ*_*thy 4 prolog

我的作业似乎超出了我的课程范围(我之所以这样说是因为他们几乎没有教我们关于序言的任何知识),我必须编写一个序言程序来解决android上的“ Flow Free”游戏。在作业中,它称为Numberlink。我可以在一个小时内用C ++解决这个问题,但是因为我对序言不太熟悉,这给我带来了麻烦。这是我想做的:

  1. 制作一个包含布尔值的列表,以指示它是否已被访问或使用过。
  2. 使用广度优先搜索递归搜索从给定起点到终点的所有可能路径,以找到最短路径。
  3. 我想从那里去。

我的尝试包括在网上搜索如何制作列表。当然,序言在任何地方都没有得到很好的记录,所以我空白了,放弃了。一位朋友告诉我使用maplist,但我不知道该如何使用它来制作包含我需要的列表。

提前致谢。

编辑:感谢您的链接,但我正在寻找一个2D列表来表示正在播放的棋盘。函数如下所示:

makeList(大小,清单):-

其中size是一个整数,表示平方表ex中一维的大小。(7x7)。

Fab*_*tor 5

这是@CapelliC解决方案的实现。该代码是不言自明的。如果两个块相邻并且具有相同的颜色,或者与另一个连接的相同颜色的块相邻,则将其连接。(我用X和Y代替了行和列,这使得在最后写条件变得有些混乱。)

解决SWI-Prolog

在此处输入图片说明

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)]).
Run Code Online (Sandbox Code Playgroud)

查询样例:

?- 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]].
Run Code Online (Sandbox Code Playgroud)