このディレクトリの索引

http://pc12.2ch.net/test/read.cgi/tech/1153585095/904
# [課題]  
# ・23本のマッチ棒からなる山があり,2人のプレーヤが山から交互にマッチ棒を
# 取り除く  
# ・一度に取ることのできるマッチ棒は1から3本  
# ・山を空にしたプレーヤが勝ち  
# 人間2人でこのゲームを行なうプログラムを作成せよ.  
# 
# プログラムでは各プレーヤの手がルールに反していないかどうかのチェックと,
# 勝負がついたかどうかのチェックを行なうこと。 
# また,最初に山にある本数と,各回に取ることができる最大の本数をプログラムの
# 最初に変数にセットしておき,そこを変えるだけで本数の変化に対応できるような
# プログラムにすること。  

プレーヤ(1,山下).
プレーヤ(2,太田).
プレーヤのデバイス(1,入力,'/dev/tty1').
プレーヤのデバイス(2,入力,'/dev/tty2').
プレーヤのデバイス(1,出力,'/var/tmp/player1').
プレーヤのデバイス(2,出力,'/var/tmp/player2').

マッチ棒の山([_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_]).

マッチ棒('|').

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

マッチ棒の山崩し :-
    プレーヤ(1,_プレーヤ1),
    プレーヤ(2,_プレーヤ2),
    マッチ棒の山(L),
    デバイスを開く(Instream1,Instream2,Outstream1,Outstream2),
    ゲームの案内(Outstream1,Outstream2),
    マッチ棒の山崩し(_プレーヤ1,_プレーヤ2,Instream1,Instream2,Outstream1,Outstream2,L),
    デバイスを閉じる(Insteam1,Instream2,Outstream1,Outstream2).

マッチ棒の山崩し(_,_プレーヤ,_,_,OutstreamA,OutstreamB,[]) :-
    concat_atom([_プレーヤ,さんの勝ちです,'\n'],S),
    同報(OutstreamA,OutstreamB,S),!.
マッチ棒の山崩し(_プレーヤA,_プレーヤB,InstreamA,InstreamB,OutstreamA,OutstreamB,L) :-
    取り棒の案内(_マッチ棒,L,_取り棒の案内),
    write_formatted(OutstreamA,'君の番だよ( %t ) : ',[_取り棒の案内]),
    マッチ棒を取る(InstreamA,OutstreamA,L,L1,L2),
    マッチ棒の山の変化を同報する(OutstreamA,OutstreamB,L,L1,L2),
    マッチ棒の山崩し(_プレーヤB,_プレーヤA,InstreamB,InstreamA,OutstreamB,OutstreamA,L2),!.

マッチ棒を取る(Instream,_,L,L1,L2) :-
    get_line(Instream,S),
    変数ならびに変換(S,L1),
    取ったマッチ棒の診断(L,L1,L2),!.
マッチ棒を取る(Instream,Outstream,L,L1,L2) :-
    マッチ棒を取る(Instream,Outstream,L,L1,L2). 

取ったマッチ棒の診断(L,L1,L2) :-
    append(L1,L2,L2),!.
取ったマッチ棒の診断(L,L1,L2) :-
    取り棒の案内(L,_取り棒の案内),    
    write(Outstream,'入力形式が正しくありません。\n'),
    write(Outstream,'(%t) : ',[_取り棒の案内]),
    fail.

変数ならびに変換(S,L) :-
     マッチ棒(_マッチ棒),
     変数ならびに変換(_マッチ棒,Chars,L),
     atom_chars(S,Chars).

変数ならびに変換(_マッチ棒,[_マッチ棒],[_]).
変数ならびに変換(_マッチ棒,[_マッチ棒|R1],[_|R2]) :-
    変数ならびに変換(_マッチ棒,R1,R2).    

取り棒の案内(L,_取り棒の案内) :-
    マッチ棒(_マッチ棒),
    取り棒の案内(_マッチ棒,L,_取り棒の案内).

取り棒の案内(_マッチ棒,[_],_マッチ棒).
取り棒の案内(_マッチ棒,[_,_],S) :-
    concat_atom([_マッチ棒,' or ',_マッチ棒],S).
取り棒の案内(_マッチ棒,[_,_,_|_],S) :-
    concat_atom([_マッチ棒,' or ',_マッチ棒,' or ',_マッチ棒],S).

マッチ棒の山の変化を同報する(Outstream1,Outstream2,L0,L1,L) :-
    マッチ棒(_マッチ棒),
    all(L0,_マッチ棒),concat_atom(L0,' ',S0),
    all(L1,_マッチ棒),concat_atom(L1,' ',S1),
    all(L,_マッチ棒),concat_atom(L,' ',S),
    concat_atom([S1,'\n','↑\n',S,'\n現在の山は ',S,'\n'],S2),
    同報(Outstream1,Outstream2,S2),
    fail.
マッチ棒の山の変化を同報する(_,_,_,_,_).

all([],_).
all([V|R],V) :- all(R,V).

ゲームの案内(Outstream1,Outstream2) :-
    同報(Outstream1,Outstream2,'マッチの本数の入力は\n1本 -> |<改行>\n'),
    同報(Outstream1,Outstream2,'2本 -> ||<改行>\n'),
    同報(Outstream1,Outstream2,'3本 -> |||<改行> という表現でお願いします\n').

同報(Outsteam1,Outstream2,_項) :-
    write(Outstream1,_項),
    write(Outstream2,_項),!.

デバイスを開く(Instream1,Instream2,Outstream1,Outstream2) :-
    プレーヤのデバイス(1,入力,Indevice1),
    プレーヤのデバイス(2,入力,Indevice2),
    プレーヤのデバイス(1,出力,Outdevice1),
    プレーヤのデバイス(2,出力,Outdevice2),
    open(Indevice1,read,Instream1),
    open(Outdevice1,append,Outstream1),
    open(Indevice2,read,Instream2),
    open(Outdevice2,append,Outstream2),!.

デバイスを閉じる(Instream1,Instream2,Outstream1,Outstream2) :-
    close(Insteam1),
    close(Outstream1),
    close(Instream2),
    close(Outstream2),!.

マッチ棒の山の初期状態の設定(N) :-
    integer(N),
    retract(マッチ棒の山(_)),
    length(L,N),
    asserta(マッチ棒の山(L)).

プレーヤの入出力デバイスの設定(_プレーヤ1の入力デバイス,_プレーヤ2の入力デバイス,_プレーヤ1の出力デバイス,_プレーヤ2の出力デバイス) :-
    abolish(プレーヤのデバイス/3),
    assertz(プレーヤのデバイス(1,入力,_プレーヤ1の入力デバイス)),
    assertz(プレーヤのデバイス(2,入力,_プレーヤ2の入力デバイス)),
    assertz(プレーヤのデバイス(1,出力,_プレーヤ1の出力デバイス)),
    assertz(プレーヤのデバイス(2,出力,_プレーヤ2の出力デバイス)),!.

プレーヤの設定(_プレーヤ1,_プレーヤ2) :-
    abolish(プレーヤ/2),
    assertz(プレーヤ(1,_プレーヤ1)),
    assertz(プレーヤ(2,_プレーヤ2)),!.

get_line(Instream,X)
  :-
    get_char(Instream,C),
    get_line_3(Instream,C,Chars),
    atom_chars(X,Chars).

get_line_3(_,'\n',[]) :- !.
get_line_3(Instream,end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !.
get_line_3(Instream,C,[C|R]) :-
    get_char(Instream,C2),
    get_line_3(Instream,C2,R).