オフラインどう書くE06の解答

問題はこちら->http://mtsmfm.github.io/2016/08/06/doukaku-e06.html
comb/2で対戦の組み合わせ、ply/3で試合を、bat/3で各戦闘を扱います。
combの[H1|T1]はプレイヤーのリスト、[V|R2]は対応する勝ち数のリストです。
ホゲモンのデータはタイプ:レベル:体力(M:L:P)の形で保持します。初期状態でL=Pです。
plyでホゲモンを選んでbatを呼び出し、
batではレベルの低いホゲモンの体力をdam/4で減らし、体力が0以下ならplyにもどり、
そうでなければレベルの高いホゲモンの体力を減らし、体力が0以下ならplyにもどり、
そうでなければbatを継続します。
両方のレベルが等しければ、両方の体力を減らし、両方の体力の残りが正ならbat継続、
0以下なら失敗、それ以外はplyに戻ります。
batの戻り値は、勝ったほうの番号:残りの体力　です。
plyではbatが成功すれば勝ったほうのホゲモンが残りの体力で相手の別のホゲモンと対戦、
batが失敗した場合は新しいホゲモンどうしで対戦。
どちらかのホゲモンがなくなったらcombに戻って勝ち数のリストを書き換え、別の相手を選びます。
combの戻り値はプレイヤー順に勝ち数が入ったリストです。
このリストの要素にar1/4で番号を付加し、勝ち数で降順にソートしてar2/2で番号のみ取り出します。
ソートの時の同じ勝ち数の場合の表示順の関係で、ar1のappendの要素の順番を変えています。

```Prolog
%swi-Prolog  version 7.4.2,7.6.4
%:-initialization(start). %ideone
%start.

sup('R','G').
sup('G','B').
sup('B','R').

dam(M1,M2,PF,PA):-
     M1==M2->PA is PF-2;(sup(M1,M2)->PA is PF-4;PA is PF-1).

bat(N1:M1:L1:P1,N2:M2:L2:P2,W):-
     L1>L2,!,dam(M1,M2,P2,P21),
     (P21>0->(dam(M2,M1,P1,P11),
     (P11>0->bat(N1:M1:L1:P11,N2:M2:L2:P21,W);W=N2:P21));W=N1:P1).
bat(N1:M1:L1:P1,N2:M2:L2:P2,W):-
     L1<L2,!,bat(N2:M2:L2:P2,N1:M1:L1:P1,W).
bat(N1:M1:L1:P1,N2:M2:L2:P2,W):-
     dam(M1,M2,P2,P21),dam(M2,M1,P1,P11),
     (P11>0->(P21>0->bat(N1:M1:L1:P11,N2:M2:L2:P21,W);W=N1:P11);(P21>0->W=N2:P21)).

ply([],[],0):-!.
ply([],_,2):-!.
ply(_,[],1):-!.
ply([H1|T1],[H2|T2],R):-
     bat(1:H1,2:H2,N:P),(N=:=1->
     (H1=M:L:_,ply([M:L:P|T1],T2,R));(H2=M:L:_,ply(T1,[M:L:P|T2],R))).
ply([_|T1],[_|T2],R):-ply(T1,T2,R).

comb([_],[0]).
comb([H1|T1],[V|R2]):-
     comb(T1,R1),comb1(H1,T1,R1,V,R2),!.
comb1(_,[],_,0,[]).
comb1(X,[Y|T],[YV1|TV],XV,R):-
     comb1(X,T,TV,XV1,R1),ply(X,Y,D),(D=:=0->(XV=XV1,YV=YV1);
     (D=:=1->(XV is XV1+1,YV=YV1);(XV=XV1,YV is YV1+1))),R=[YV|R1].

ar1([],_,R,R).
ar1([H|T],N,R1,R):-N1 is N+1,append(R1,[H:N1],R2),ar1(T,N1,R2,R).

ar2([],[]).
ar2([_:Y|T],R):-ar2(T,R1),R=[Y|R1].

solve(L,R):-comb(L,R2),ar1(R2,0,[],R1),sort(1,@>=,R1,R3),ar2(R3,R),!.

start:-str(S),split_string(S,"\s\n","\s",L),pre(L).

pre([]).
pre([_,B,Q|T]):-
     atomics_to_string(BL,",",B),maplist(atom_chars,BL,L),
     maplist(pair,L,L1),solve(L1,R),disp(R,Q),pre(T).

disp(R,A):-
     atomics_to_string(R,",",S),(S==A->Str=" pass ";Str=" fail "),
     write(Str),writeln(S).

pair([],[]).
pair([A,B|T],R):-pair(T,R1),atom_number(A,N),R=[B:N:N|R1].

str("0  9B,3R2G,1R2B3G  1,3,2
1       1G      1
2       1G,1R,1B        1,2,3
3       8B,3R2G,1R2B3G  3,1,2
4       6G,9R7B7B       2,1
5       5B1B,1G1B2R6G,7B6G4B6B  3,2,1
6       7R,2R9G,6R4B1G6R,5G1G6G 3,1,2,4
7       2B9G8B3R,4R3G,2B,8B     1,2,4,3
8       1B,5G1R1B4R,5R,8B9B4G,7G5R8G    5,4,3,2,1
9       9G5B,6B6R1R5G,7G6G,8B5R,5G7G,2G5B7B     2,1,3,4,5,6
10      5B,1B8R2B,8G6R4B,4B1G6R8G,3B6G6G5R,7B   3,4,5,6,1,2
11      2G2G7G9B,6G5G5R,2G,4G,5R,3G8R,6G9R      1,7,6,2,5,4,3
12      6G7B4R6B,9R4G,6G5B5G3B,6R7G,9B,7G7B8R,5G8G2R,6B8G7B1B   8,1,6,2,3,4,7,5
13      9B8B2G4B,2B1R,7R6G8R,4R,1G7B7R,4B3B4R,4B3R2R4G,4G9R9R   1,3,8,5,6,7,2,4
14      5G,3G,9G7G8B,7B,8G6B1B5G,1G3B,5G8R,6G,7B        3,5,7,8,1,2,4,9,6
15      5B1R5B,6R,7R7R,8B1B,6R1G,7B3R2R,4R3B,6G1R8G,6B4R4R2B,9G5B       10,1,4,6,9,3,8,5,7,2
16      7R4G1G6R,9B3G3R4G,2G7G,5B,5R8R,9G7R9B,8R7R5G,7B9R1R8R,7R,9R1B   6,8,7,2,1,5,4,10,3,9
17      3G8B2B8G,7B7R5G,4B9G2R,4G,1G2R5R8R,1B,8R9G7G,7R6B,6B8B,3G3R,3R2R        2,7,1,3,9,5,8,10,11,4,6
18      5G3B,4B3G,7G8R2B7R,6G,1G,1B,1R9R2R7R,3R4G1R,4B3G2G8G,3B,2B1G,7R 3,7,9,8,1,4,2,12,10,11,5,6
19      4B2B5G1G,2G2B3R,7G4B9R9G,7R9G,5B,5G3G,7R5R,4B,6G3R4G3G,3R9G,8R9G4R,2R   3,11,4,7,10,9,1,5,6,2,8,12
20      8R,9R,5R,4G,3G2G1R,5G,4G5G,2G,6G6B1G,8R2G6B2G,1G5B8B,1G,7R      10,9,2,1,11,13,3,7,6,4,5,8,12
21      2R,4G7G,4R,1G1R7G,5B6G,2G,4B9R,7R2B7R4B,3B1G5G,8B9R,6B1G6R,1R2R,9G2B2R,4R9B     10,11,14,8,13,5,7,2,3,4,9,1,12,6
22      6R3R3B,1R,7R4B4G,7G9B,4G6G8B,4R7R4B,5R3R,3R,5B2G4R,1B,5B,9B2R,5G4R,6R3R3G       4,3,5,12,9,14,6,11,1,13,7,8,2,10
23      5B7B,8G,7G,6R9B3B,2B,3G3B8R7B,7R7G6R,4B6B5G,4R4G9R,4B7G6G5G,3B8B1B1G,5G7G2R,1B,2G6G5B3G,4R4B8B  7,6,9,10,4,12,14,2,8,15,3,1,11,5,13").
```