1

私の目的は、Skittles に似た「Kayles」というゲームを実行するための簡単なプログラムを開発することです。ボトルの列があり、2 人のプレイヤーが順番にボトルを倒し、最後のボトルを倒したプレイヤーが勝ちです。倒すことができるボトルは 1 つか 2 つだけで、隣同士にある必要があります。

このプログラムの最初の部分は、ボトルと空きスペースを表現する方法を決定することでした。リストを使用することにしました。1 はボトルを表し、0 は空きスペースを表します。

このプログラムの 2 番目の部分は、現在の状態を端末に出力することでした。ここで、ボトルはアスタリスク * で表され、空のスペースはギャップで表されます。

このプログラムの 3 番目の部分は、現在の状態から到達可能なすべての次の状態を一覧表示して出力することでした。たとえば、[1,1,1] のボトルが 3 つある場合、最初のボトルが倒されたため、次の状態は [0,1,1] になります。したがって、この述語は、すべての可能な次の状態のリストを出力することになっています。これも * とスペースで表されます。

上記を正常に実行しました。これまでのコードは次のとおりです。

printstate([]) :- nl.
printstate([B|L]) :- (B=0 -> write(' '); write('*')), printstate(L).

next([1|S], [0|S]).
next([1,1|S], [0,0|S]).
next([0|S], [0|T]) :- next(S,T).
next([1|S], [1|T]) :- next(S,T).

printnextstates(S,T) :- next(S,T), printstate(T), fail.

次のビットは、私が立ち往生しているビットです! したがって、目的は、最初に移動したプレイヤーが強制的に勝利できる場合は状態の値を 1 に定義し、それ以外の場合は 0 に定義することです。ゲーム ツリーの深さ優先探索によって任意のゲーム状態 S の値 X を計算する述語値 (S,X) を記述します。検索で任意の位置を複数回探索することを避けるために、可能であれば assert を使用する必要があります。

これを行う方法がわかりません!

これまでのところ、これは私が思いつくことができるものです:

value(S,X) :- S = 1, ([S,T] = 1); 0.

しかし、それはそれほど単純ではないと確信していますが、この質問をどのように開始すればよいかわかりません! 深さ優先検索について調査しましたが、これを書くのに十分なほど理解していません...この質問を開始する際にどうすればよいか、誰か知っていますか?

どんな助けでも大歓迎です!

4

1 に答える 1

0

プレーヤーは任意の位置で要素を自由に選択できるため、問題を適切にデータ表現することで、驚くほど単純化されます。たとえば、使用可能なボトルのリストを保持しているとします。次に、ロジックを宣言するだけで済みます。

win(P) :-
    move(P, P1),
    \+ win(P1).
win(P) :- move(P, []).

move([_|R], R).
move([_,_|R], R).

ここでは、単純な漸化式が結果を与えることに注意せずに、任意の長さまでのダムテストを行います

?- setof(N, L^(between(1,20,N),length(L,N),win(L)), Wins).
Wins = [1, 2, 4, 5, 7, 8, 10, 11, 13|...].
于 2013-03-07T17:56:25.067 に答える