/*--------------------------------------------------------------------*/ /* ■ Prolog によるインベーダゲーム */ /*--------------------------------------------------------------------*/ /* 述語 inv で開始します。inv.[enter] と入力してください。 */ /* 砲台は z で左へ,x で右にシフトします。大文字では動作しませんので */ /* [caps lock]を確認しておいてください。(z または x を押して小文字に */ /* なるかどうか確認します。) */ /* ミサイル発射はスペースキーを押します。連打もできますが、ミサイル */ /* が多いとミサイルの動きが鈍くなります。 */ /*--------------------------------------------------------------------*/ /*■メイン(inv)述語 */ inv:- initInv, repeat, exe. initInv:-d_clear,clearAss(invader(A,B)),delTerm(endflag),clearAss(missile(X, Y)), delAndAss(point(_),point(0)),delAndAss(battery(_),battery(0)),dspBat. delTerm(X):-retract(X). delTerm(_). delAndAss(A,B):-delTerm(A), assert(B). clearAss(X):-retract(X),fail. clearAss(X). /*■実行関係述語 */ exe:-d_keylength(0),!, gencell,invader(X,Y),move(X,Y),!,moveMss, !, endflag,!,d_cursor(1,2),write('ゲームオーバ'). exe:-d_keyin(X),!, exe(X). exe(122):-battery(X), dltBat,leftBat(X),dspBat,!,fail. exe(120):-battery(X), dltBat,rightBat(X),dspBat,!,fail. exe( 32):-battery(X),!,blastoff(X). exe(X):-!,fail. dspBat:-battery(X),dspCH(X,24,'■'). dltBat:-battery(X),dspCH(X,24,' '). leftBat(0). leftBat(X):- XX is X - 1, delAndAss(battery(X),battery(XX)). rightBat(19). rightBat(X):- XX is X + 1, delAndAss(battery(X),battery(XX)). /*■ミサイル発射 */ blastoff(X):-invader(X,23),!,delInv(X,23),!,fail. blastoff(X):-assert(missile(X,23)),!,fail. /*■ミサイル移動 */ moveMss:-retract(missile(X,Y)),!, dspCH(X,Y,' '),moveMss(X,Y). moveMss. moveMss(X,1):-!. moveMss(X,Y):-invader(X,Y),!,delInv(X,Y). moveMss(X,Y):-YY is Y-1, invader(X,YY),!, delInv(X,YY). moveMss(X,Y):-YY is Y-1, assert(missile(X,YY)),dspCH(X,YY,'Δ') . moveMss(X,Y). /*■敵爆破 */ delInv(X,YY):-retract(invader(X,YY)), dspCH(X,YY,'☆'),s_sleep(50), retract(point(N)),NN is N+1,assert(point(NN)), d_cursor(2,1), write('得点 : '), write(NN), dspCH(X,YY,' '). /*■敵移動 */ move(X,Y):-dspCH(X,Y,' '),move1(X,Y). move(X,Y). move1(X,24):-!,retract(invader(X,24)). move1(X,Y ):-!,retract(invader(X, Y)),YY is Y+1, setInv(X, YY). move1(X,Y ). setInv(X,24):-battery(X),!,stopGame(X). setInv(X, YY):- assert(invader(X,YY)), dspCH(X,YY,'Ж'), gencell, clause(invader,2,N), !, N=/=0, NN is integer(500/N), s_sleep(NN). setInv(_,_). stopGame(X):-dspCH(X,24,'☆'),assert(endflag). /*■共通的な処理 */ gencell:-clause(invader,2,5),!. gencell:-s_random(20,N), gencell(N). gencell(1):-!,s_random(20,X),assert(invader(X,1)). gencell(_). dspCH(X,Y,C):-XX is X * 2+20, d_cursor(XX,Y), write(C).