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 になります。グリッドを回転させて水平方向のジャンプを単純に把握し続けるというアイデアが気に入ったので、rotate 関数を変更して側面を回転させ、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 に答える