因为我是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停止。有什么建议吗?
发布于 2012-10-11 15:05:10
我认为你可以数一下钉子,或者更好的是,当至少有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中可用。
https://stackoverflow.com/questions/12826174
复制相似问题