Prolog中的矩形钉接龙?

时间:2012-10-10 18:41:46

标签: recursion prolog counter

这是可能的快速问题,因为我是Prolog的新手。我正在尝试将这个代码转换成解决一个三角形的peg单人拼图来解决一个矩形的peg单人拼图。我认为我面临的问题是试图弄清楚如何让程序知道它完成了这个难题。这就是我目前所拥有的:

% 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处停止的计数器。任何建议?

1 个答案:

答案 0 :(得分:0)

我认为你可以计算钉子,或者更好,在至少有2个时失败。

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

finished(L) :-
   \+ call_nth(find_peg(L), 2).
find_peg(L) :-
   member(R, L),
   memberchk(R, x).
this answer中所定义的,

call_nth / 2需要内置nb_setval。这可以在SWI-Prolog或Yap中找到。