データファイルを手作業で一行一リストにしてから読み込み。
地道に全部の役とユニフィケーションして役のスコアは1000点単位、その後ろに役を構成するカードの数字を大きい順にセット。
後はisV述語で勝敗判定。
なんかポーカーの役判定は有名で賢い方法があるらしいけれど素朴に書いてみた。
toNum(84,10):-!.
toNum(74,11):-!.
toNum(81,12):-!.
toNum(75,13):-!.
toNum(65,14):-!.
toNum(N,N1):-!,N1 is N-48.
change([],[]):-!.
change([[Num,S]|Rest],[[Num1,S]|Result]):-
toNum(Num,Num1),
change(Rest,Result).
yaku1([[N1,A],[N2,A],[N3,A],[N4,A],[N5,A]],[8000,N5,N4,N3,N2,N1]):-
N1+1=:=N2,
N2+1=:=N3,
N3+1=:=N4,
N4+1=:=N5.
yaku1([[N1,A],[N2,A],[N3,A],[N4,A],[N5,A]],[5000,N5,N4,N3,N2,N1]).
yaku1([[N1,_],[N2,_],[N3,_],[N4,_],[N5,_]],[4000,N5,N4,N3,N2,N1]):-
N1+1=:=N2,
N2+1=:=N3,
N3+1=:=N4,
N4+1=:=N5.
yaku2([[4,N1]],[7000,N1]):-!.
yaku2([[3,N1],[2,N2]],[6000,N3,N4]):-
sort([N1,N2],[N4,N3]).
yaku2([[3,N1]|_],[3000,N1]).
yaku2([[2,N1],[2,N2]|_],[2000,N1,N2]).
yaku2([[2,N1]|_],[1000,N1]).
yaku2([[1,N1],[1,N2],[1,N3],[1,N4],[1,N5]],[0,N1,N2,N3,N4,N5]).
count([],[C,N],[[C,N]]):-!.
count([[N,_]|Rest],[C,N],Result):-
!,
C1 is C+1,
count(Rest,[C1,N],Result).
count([[N,_]|Rest],[C1,N1],[[C1,N1]|Result]):-
count(Rest,[1,N],Result).
score(Cards,Score):-
yaku1(Cards,Score).
score([[N,_]|Cards],Score):-
count(Cards,[1,N],Count),
sort(Count,Count1),
reverse(Count1,Count2),
yaku2(Count2,Score).
scoreW(Cards,Last):-
findall(E,score(Cards,E),Es),
sort(Es,Es1),
reverse(Es1,[Last|_]).
nums([],[]):-!.
nums([[N,_]|Rest],[N|Result]):-
nums(Rest,Result).
isV(C1,C2,V,V1):-
sort(C1,C11),
sort(C2,C22),
scoreW(C11,S11),
scoreW(C22,S22),
nums(C11,C11A),
nums(C22,C22A),
write([C11A,C22A]),nl,
reverse(C11A,C11B),
reverse(C22A,C22B),
(sort([S11,S22],[S22,S11])->V1 is V+1;
S11=S22,C11B\=C22B,sort([C11B,C22B],[C22B,C11B])->V1 is V+1;
V1 is V).
myread(IS,V):-at_end_of_stream(IS),!,close(IS),write(V).
myread(IS,V):-
read_term(IS,Cards,[]),
change(Cards,Cards1),
[A1,A2,A3,A4,A5,B1,B2,B3,B4,B5]=Cards1,
isV([A1,A2,A3,A4,A5],[B1,B2,B3,B4,B5],V,V1),
myread(IS,V1).
main:-
open('pe54.txt',read,IS),
myread(IS,0).
最終更新:2014年12月08日 19:37