2

因为我是 Prolog 的新手,所以可能会在这里快速提问。我正在尝试将此用于解决三角形钉接龙拼图的代码转换为解决矩形钉接龙拼图。我认为我面临的问题是试图弄清楚如何让程序知道它完成了这个难题。这是我目前所拥有的:

% Legal jumps along a line.
linjmp([x, x, o | T], [o, o, x | T]).
linjmp([o, x, x | T], [x, o, o | T]).
linjmp([H|T1], [H|T2]) :- linjmp(T1,T2).

% Rotate the board
rotate([[A, B, C, D, E, F],
        [G, H, I, J, K, L],
        [M, N, O, P, Q, R],
        [S, T, U, V, W, X]],
        [[S, M, G, A],
        [T, N, H, B],
        [U, O, I, C],
        [V, P, J, D],
        [W, Q, K, E],
        [X, R, L, F]]).

rotateBack([[A, B, C, D],
            [E, F, G, H],
            [I, J, K, L],
            [M, N, O, P],
            [Q, R, S, T],
            [U, V, W, X]],
            [[D, H, L, P, T, X],
            [C, G, K, O, S, W],
            [B, F, J, N, R, V],
            [A, E, I, M, Q, U]]).

% A jump on some line.
horizjmp([A|T],[B|T]) :- linjmp(A,B).
horizjmp([H|T1],[H|T2]) :- horizjmp(T1,T2).

% One legal jump.
jump(B,A) :- horizjmp(B,A).
jump(B,A) :- rotate(B,BR), horizjmp(BR,BRJ), rotateBack(A,BRJ).
%jump(B,A) :- rotate(BR,B), horizjmp(BR,BRJ), rotate(BRJ,A).

% Series of legal boards.
series(From, To, [From, To]) :- jump(From, To).
series(From, To, [From, By | Rest])
       :- jump(From, By),
         series(By, To, [By | Rest]).

% A solution.
solution(L) :- series([[o, x, x, x, x, x],
                       [x, x, x, x, x, x],
                       [x, x, x, x, x, x],
                       [x, x, x, x, x, x]], L).

三角拼图代码要求用户输入结束表格的样子,但我不希望这样。我希望这显示任何可能的解决方案。桌子总是正好是 6x4。我喜欢旋转网格以继续简单地计算水平跳跃的想法,因此我更改了旋转函数以旋转它的侧面,并添加了一个 RotateBack 函数将其放回原位。我想我必须这样做,因为网格不是对称的。由于它总是这个大小,我认为找到结束的最简单方法是设置一个计数器来计算发生了多少次移动。一旦我们达到 22 步(清除除 1 个钉子之外的整个网格的最大可能步数),那么解决方案将是成功的。

换句话说,我认为我需要删除这段代码:

% Series of legal boards.
series(From, To, [From, To]) :- jump(From, To).
series(From, To, [From, By | Rest])
       :- jump(From, By),
         series(By, To, [By | Rest]).

并对其进行更改,使其设置一个在 22 处停止的计数器。有什么建议吗?

4

1 回答 1

0

我认为你可以数数钉子,或者更好的是,当至少有 2 个时失败。

为了有效地做到这一点,应该是(未经测试的代码)

finished(L) :-
   \+ call_nth(find_peg(L), 2).
find_peg(L) :-
   member(R, L),
   memberchk(R, x).

此答案中定义的 call_nth/2需要内置nb_setval。这在 SWI-Prolog 或 Yap 中可用。

于 2012-10-11T07:05:10.450 回答