2012-10-10 40 views
2

因为我是Prolog的新手,因此可能很快出现问题。我试图将这个代码解决一个三角形peg单粒宝石拼图解决一个矩形peg纸牌拼图。我认为我面临的问题是试图弄清楚如何让程序知道它完成了这个难题。这里是我目前得到的:Prolog中的矩形Peg Solitaire?

% 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

请注意,你的'rotate/2'和'rotateBack/2'实质上是相同的定义,唯一的区别是参数的顺序。所以你在Prolog中不需要'rotateBack/2'! – false

回答

0

我想你可以算钉,或更好时,至少有2

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

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

call_nth/2,如定义在this answer中,需要内建nb_setval。这在SWI-Prolog或Yap中可用。