問題はこちら
http://nabetani.sakura.ne.jp/hena/1/
勝ちの判定はたかだか八通りなので事実をそのまま書きました。
先手と後手の着手を別のリストに保存することにし、
新しい着手は既存の手との重複がないか調べます。
重複があれば反則負けです。
重複がなければ、勝ちパターンのリストの要素が着手のリストに含まれているか調べます。
含まれていれば、勝ちです。含まれていない場合次の着手に進みます。
九手終了後勝敗が決まっていなければ引き分けです。
%SWI-Prolog version 7.4.2
%start.
%:-initialization(start). %ideone
win([1,2,3]).
win([4,5,6]).
win([7,8,9]).
win([1,4,7]).
win([2,5,8]).
win([3,6,9]).
win([1,5,9]).
win([3,5,7]).
solve(_,9,_,_,'Draw game.'):-!.
solve([H|_],N,W,B,R):-
(member(H,W);member(H,B)),!,(N mod 2 =:= 0->Win='x';Win='o'),concat_atom(['Foul : ',Win,' won.'],R).
solve([H|T],N,W,B,R):-
M is N mod 2,(M=:=0->(W1=[H|W],L1=W1,B1=B,Win='o');(B1=[H|B],L1=B1,W1=W,Win='x')),
((win(L2),subset(L2,L1))->concat_atom([Win,' won.'],R);(N1 is N+1,solve(T,N1,W1,B1,R))).
start:-str(S),split_string(S,"\n","",L),maplist(split,L,L1),pre(L1).
split(S,L):-atomics_to_string(L,",",S).
pre([]).
pre([[_,B,Q]|T]):-atom_chars(B,L),maplist(atom_number,L,L1),solve(L1,0,[],[],R),disp(R,Q),pre(T).
disp(R,A):-(R==A->Str=" pass ";Str=" fail "),write(Str),writeln(R).
str("1,79538246,x won.
2,35497162193,x won.
3,61978543,x won.
4,254961323121,x won.
5,6134278187,x won.
6,4319581,Foul : x won.
7,9625663381,Foul : x won.
8,7975662,Foul : x won.
9,2368799597,Foul : x won.
10,18652368566,Foul : x won.
11,965715,o won.
12,38745796,o won.
13,371929,o won.
14,758698769,o won.
15,42683953,o won.
16,618843927,Foul : o won.
17,36535224,Foul : o won.
18,882973,Foul : o won.
19,653675681,Foul : o won.
20,9729934662,Foul : o won.
21,972651483927,Draw game.
22,5439126787,Draw game.
23,142583697,Draw game.
24,42198637563,Draw game.
25,657391482,Draw game.").