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