/*===========================================================================*/ /* ■ AZ Prologによるライフゲーム(配列を使わないバージョン) */ /*===========================================================================*/ /*  (1) 実行開始は lifeGame. と入力してください。 */ /* (2) 終わるときは[ctrl] Z を押してください。   */ /* (3) [ctrl] Z 以外の入力で最初からやり直します。 */ /* (4) [ctrl] Z で終わったあと再開するときも lifeGame. と入力して下さい。 */ /*---------------------------------------------------------------------------*/ /* ■メイン述語 */ lifeGame :- setData,repeat, exeLifeGame, endCheck. endCheck :- d_keylength(0),!,fail. endCheck :- d_keyin(X), endCheck(X). endCheck( 26):- d_cursor(on). endCheck( _ ):- lifeGame. /* ■実行制御関連述語 */ setData:- deleteCurState,assert(curState(a,b)), deleteCellSize,assert(cellSize(40,24)), clearCells(a), clearCells(b),genCells(a,100), d_clear,d_cursor(off). exeLifeGame:- curState(A,_), dspCells(A), checkAr, !, changeCurrent, s_sleep(200). changeCurrent :- retract(curState(X,Y)), assert(curState(Y,X)). deleteCurState:- retract(curState(X,Y)),fail. deleteCurState. deleteCellSize:- retract(cellSize(X,Y)),fail. deleteCellSize. /* ■セル設定用述語 */ getCells(A,X,Y,1):- cell(A,X,Y). getCells(A,X,Y,0). setCells(A,X,Y,1):- cell(A,X,Y),!. setCells(A,X,Y,1):- assert(cell(A,X,Y)),!. setCells(A,X,Y,0):- cell(A,X,Y),!,(retract(cell(A,X,Y));true). setCells(A,X,Y,0). clearCells(A) :- retract(cell(A,X,Y)),fail. clearCells(A). /* ■セル生成用熟語 */ genCells(A,MX) :- cellSize(NX,NY),genCells(A,NX,NY,0,MX). genCells(A,NX,NY,MX,MX). genCells(A,NX,NY, I,MX) :- s_random(NX,X),s_random(NY,Y),!, chkCells(A,NX,NY,X,Y,I,MX). chkCells(A,NX,NY,X,Y,I,MX):- cell(A,X,Y),!, genCells(A,NX,NY,I,MX). chkCells(A,NX,NY,X,Y,I,MX):- assert(cell(A,X,Y)),!,II is I+1, genCells(A,NX,NY,II,MX). chkCells(A,NX,NY,X,Y,I,MX):- write('**予想できないエラー:chkCells'). /* ■セル表示述語 */ dspPos(X,Y,V):- DX is X*2+1, DY is Y+1, d_cursor(DX,DY), write(V). dspCells(A) :- cellSize(NX,NY),dspCells(A,0,0,NX,NY). dspCells(A, X,NY,NX,NY):- !. dspCells(A,NX, Y,NX,NY):- !,YY is Y+1,dspCells(A,0,YY,NX,NY). dspCells(A, X, Y,NX,NY):- cell(A,X,Y),!, dspPos(X,Y,'■'), XZ is X+1,dspCells(A,XZ,Y,NX,NY). dspCells(A, X, Y,NX,NY):- dspPos(X,Y,' '), XZ is X+1,dspCells(A,XZ,Y,NX,NY). /* ■周りを取り出してカウント*/ getAround(A,X0,Y0,[V1,V2,V3,V4,V5,V6,V7,V8]):- XB is X0-1, XA is X0+1,YB is Y0-1, YA is Y0+1, getCells(A, XB,YB,V1),getCells(A, X0,YB,V2),getCells(A, XA,YB,V3), getCells(A, XB,Y0,V4) ,getCells(A, XA,Y0,V5), getCells(A, XB,YA,V6),getCells(A, X0,YA,V7),getCells(A, XA,YA,V8). numberAround(A,X,Y,N) :- getAround(A,X,Y,L),countAround(L,0,N). countAround([] ,N ,N):- !. countAround([1|X],NB,N):- NN is NB+1,countAround(X,NN,N). countAround([0|X],NB,N):- countAround(X,NB,N). /* ■生死判定 */ deadAlive(Curr, Next,X,Y):- numberAround(Curr,X,Y,N), getCells(Curr,X,Y,V),judgeDA(V,Next,X,Y,N). setAlive(Next,X,Y) :- setCells(Next,X,Y,1). judgeDA(0, Next,X,Y,3):- !,setAlive(Next,X,Y). judgeDA(1, Next,X,Y,2):- !,setAlive(Next,X,Y). judgeDA(1, Next,X,Y,3):- !,setAlive(Next,X,Y). judgeDA(_, _,_,_,_). /* ■全体の生死判定 */ checkAr:-curState(A,B), clearCells(B), cellSize(NX,NY), checkAr(A,B,0,0,NX,NY). checkAr(A,B, X, NY,NX,NY):-!. checkAr(A,B, NX, Y,NX,NY):-!, YY is Y + 1, checkAr(A,B,0,YY,NX,NY). checkAr(A,B, X, Y,NX,NY):- deadAlive(A,B,X,Y), !, XX is X+1, checkAr(A,B,XX,Y,NX,NY).