簡體   English   中英

用prolog解決Numberlink難題

[英]Solving the Numberlink puzzle with prolog

我的作業似乎超出了我的課程范圍(我說這是因為他們幾乎沒有教我們關於prolog的任何內容),我必須編寫一個prolog程序來解決Android上的游戲“Flow Free”。 在賦值中,它被稱為Numberlink。 我可以在一小時內用C ++解決這個問題,但因為我對prolog不太熟悉它給我帶來了麻煩。 這就是我想做的事情:

  1. 創建一個包含布爾值的列表,以指示它是否已被訪問或使用過。
  2. 使用廣度優先搜索遞歸搜索從給定起點到終點的所有可能路徑以找到最短路徑。
  3. 從那里開始我想。

我的嘗試包括在網上搜索如何制作清單。 當然prolog在任何地方都沒有記錄好,所以我空白並放棄了。 一位朋友告訴我使用maplist,我不明白如何用它來制作一份包含我需要的清單。

提前致謝。

編輯:感謝您的鏈接,但我希望制作一個2D列表來代表正在播放的電路板。 功能看起來像這樣:

makeList(size,list): -

其中size是一個整數,表示方形列表ex中一個維度的大小。 (7×7)。

這是@ CapelliC解決方案的實現。 代碼不言自明。 如果它們相鄰並且具有相同的顏色,或者與相同顏色的另一個連接的塊相鄰,則連接2個塊。 (我使用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)]).

示例查詢:

?- 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]].

聲明性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成功時,它已將一個空閑單元格實例化為相鄰的相同顏色...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM