このディレクトリの索引
#  出典: プログラミングのお題スレ Part3 #729
#  
#  お題:○×ゲームで○が勝つ局面までの手順を深さ優先探索ですべて探し出して出力。手順の重複は認めない。
#  
#  列者臨
#  在皆兵
#  前陣闘
#  

勝ち(列者臨).
勝ち(在皆兵).
勝ち(前陣闘).
勝ち(列在前).
勝ち(者皆陣).
勝ち(臨兵闘).
勝ち(列皆闘).
勝ち(臨皆前).

'○×ゲーム'(_勝ち,_着手ならび) :-
        交互着手(臨兵闘者皆陣列在前,○,×,[],[],_勝ち,_着手ならび).

交互着手(_,_,_手番,_,_手番の着手点ならび,_手番,[]) :-
        勝ち(_手番の着手点ならび),!.
交互着手(_着手可能点文字列,_手番,_次の手番,_手番の着手点ならび,_次の手番の着手点ならび,_勝ち,[_着手|_着手ならび]) :-
        選択(_着手可能点文字列,_着手,_残り着手可能点文字列),
        交互着手(_残り着手可能点文字列,_次の手番,_手番,_次の手番の着手点ならび,[_着手|_手番の着手点ならび],_勝ち,_着手ならび).

選択(_着手可能点文字列,_着手,_残り着手可能点文字列) :-
        副文字列(_着手可能点文字列,_開始位置,1,_残り文字数,_着手),
        着手以外の文字列を残り着手可能点とする(_着手可能点文字列,_開始位置,_残り文字数,_残り着手可能点文字列).

着手以外の文字列を残り着手可能点文字列とする(_着手可能点文字列,_前文字列長,_後文字列長,_残り着手可能点文字列) :-
        副文字列(_着手可能点文字列,0,_前文字列長,_,_前文字列),
        副文字列(_着手可能点文字列,_,_後文字列長,0,_後文字列),
        二つの文字列の結合(_前文字列,_後文字列,_残り着手可能点文字列).

勝ち(_着手ならび) :-
        勝ち(_文字列),
        全ての文字列の構成文字は着手ならびに含まれる(_文字列,_着手ならび).

全ての文字列の構成文字は着手ならびに含まれる(_文字列,_着手ならび) :-
        全ての第一引数の実行に対して第二引数の実行が必ず成立する(副文字列(_文字列,_,1,_,文字),含まれる(_文字,_着手ならび)).



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

副文字列(_文字列,_副文字列の開始位置,_文字列長,_残り文字列長,_副文字列) :-
        sub_atom(_文字列,_副文字列の開始位置,_文字列長,_残り文字列長,_副文字列).

二つの文字列の結合(_文字列_1,_文字列_2,_結合した文字列) :-
        atom_concat(_文字列_1,_文字列_2,_結合した文字列).

含まれる(_要素,_ならび) :-
        member(_要素,_ならび).

全ての第一引数の実行に対して第二引数の実行が必ず成立する(_第一引数,_第二引数) :-
        forall(_第一引数,_第二引数).