Исходник:
% This program is created by Hristo Ionchev, Petar Petrov and Mila Kacarova
% from University of Sofia
?-
G_nCols is 6, G_nRows is 7, G_nWin is 4,
G_cellPix is 48,
G_wWidth is G_nCols*G_cellPix+12, G_wHeight is G_nRows*G_cellPix+31,
G_cEMPTY is 0, G_cWHITE is 1, G_cBLACK is 2, G_Winner is G_cEMPTY,
window(_,_,win_func(_),"Game",100,100,G_wWidth,G_wHeight),newGame(_).
newGame(_) :- set(pullsW([])),set(pullsB([])),win_func(paint),
set_text("Your turn!",_).
pullIn([A,B|T],A,B).
pullIn([A,B|T],X,Y) :- pullIn(T,X,Y).
pullIn(X,Y) :- pullsW(L),pullIn(L,X,Y).
pullIn(X,Y) :- pullsB(L),pullIn(L,X,Y).
pullAt(X,Y,G_cWHITE) :- pullsW(L),pullIn(L,X,Y), !.
pullAt(X,Y,G_cBLACK) :- pullsB(L),pullIn(L,X,Y), !.
pullAt(X,Y,G_cEMPTY).
addToList(X,Y,List,[X,Y|List]).
playAt(X,Y) :- pullsW(L),set(pullsW([X,Y|L])).
gameOver :-
pullsW(PW), pullsB(PB), isFinal(PW,PB), set_text("Game over.",_),
(G_Winner=G_cWHITE -> Text is "You win!"),
(G_Winner=G_cBLACK -> Text is "I win!"),
(G_Winner=G_cEMPTY -> Text is "Draw game!"),
(yes_no(Text,"Play again?",!) -> newGame(_) ; !,fail).
playShtaiga :- pullsW(PW), pullsB(PB), not(isFinal(PW.PB)),
set_text("Thinking...",_),
BestValue:=0, BestCol:=1, minimaxB(2,PW,PB,BestValue,BestCol),
makeMove(PB,PW,BestCol,NewPB), set(pullsB(NewPB)), win_func(paint),
set_text("Your turn!",_), (gameOver ;true).
makeMove(PM,PD,Col,NewPM) :- for(Row,G_nRows,1, -1),
not(pullIn(PM,Col,Row) ; pullIn(PD,Col,Row)), addToList(Col,Row,PM,NewPM).
win_func(init) :- window_brush(_,rgb(0,0,0)).
win_func(mouse_click(X,Y)) :-
pullsW(PW),pullsB(PB), not(isFinal(PW,PB)),
Col:=X//G_cellPix+1, Row:=Y//G_cellPix+1,
(Col>G_nCols -> Col:=G_nCols),
(Row>G_nRows -> Row:=G_nRows),
pullAt(Col,1,Value),
(Value=G_cEMPTY -> (
(call(for(I,G_nRows,1, -1),
pullAt(Col,I,Valu),
(Valu=G_cEMPTY -> playAt(Col,I);fail)
);true),
win_func(paint), (gameOver ;true), playShtaiga
) ;true).
win_func(paint) :-
pen(0,rgb(0,0,0)),
call(for(Row,G_nRows,1, -1), for(Col,G_nCols,1, -1),
Parity := Col mod 2,
(Parity=0 -> brush(rgb(0,127,0)) ; brush(rgb(0,127,127))),
X1:= (Col- 1)*G_cellPix, X2:=X1+G_cellPix,
Y1:= (Row- 1)*G_cellPix, Y2:=Y1+G_cellPix,
rect(X1,Y1,X2,Y2),
pullAt(Col,Row,Value),
X1:=X1+ 3, Y1:=Y1+ 3, X2:=X2- 3, Y2:=Y2- 3,
( Value=G_cBLACK ->brush(rgb(0,0,0)),ellipse(X1,Y1,X2,Y2) ;
%X1:=X1+ 1, Y1:=Y1+ 1, X2:=X2- 1, Y2:=Y2- 1,
(Value=G_cWHITE -> brush(rgb(200,200,200)), ellipse(X1,Y1,X2,Y2))),
fail) ;true.
staticEvalCell(PW,PB,X,Y,NW,NB) :-
pullIn(PW,X,Y) -> ++(NW) ; (pullIn(PB,X,Y) -> ++(NB) ).
staticEvalCells(NW,NB,Sum,Final) :- NW=0,NB=0,Sum:=0, !.
staticEvalCells(NW,NB,Sum,Final) :- (NW=0 ->
(Sum:= -1, for(I,1,NB- 1), Sum := Sum * 8, fail;
(NB >= G_nWin -> Final:=1)); fail), !.
staticEvalCells(NW,NB,Sum,Final) :- (NB=0 ->
(Sum:= 1, for(I,1,NW- 1), Sum := Sum * 8, fail;
(NW >= G_nWin -> Final:=1)); fail), !.
staticEvalCells(NW,NB,Sum,Final) :- Sum:=0.
staticEvalRows(PW,PB,Sum,Final) :-
Row1:=1, Row2:=G_nRows- G_nWin+ 1, Col1:=1, Col2:=G_nCols,
call(for(Row,Row1,Row2),for(Col,Col1,Col2),
NW:=0, NB:=0,
X:=Col+0, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+0, Y:=Row+1, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+0, Y:=Row+2, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+0, Y:=Row+3, staticEvalCell(PW,PB,X,Y,NW,NB),
staticEvalCells(NW,NB,Value,Final), Sum := Sum + Value,
fail);true.
staticEvalCols(PW,PB,Sum,Final) :-
Row1:=1, Row2:=G_nRows, Col1:=1, Col2:=G_nCols- G_nWin+ 1,
call(for(Row,Row1,Row2),for(Col,Col1,Col2),
NW:=0, NB:=0,
X:=Col+0, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+1, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+2, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+3, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
staticEvalCells(NW,NB,Value,Final), Sum := Sum + Value,
fail);true.
staticEvalDiagA(PW,PB,Sum,Final) :-
Row1:=1, Row2:=G_nRows- G_nWin+ 1, Col1:=1, Col2:=G_nCols- G_nWin+ 1,
call(for(Row,Row1,Row2),for(Col,Col1,Col2),
NW:=0, NB:=0,
X:=Col+0, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+1, Y:=Row+1, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+2, Y:=Row+2, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col+3, Y:=Row+3, staticEvalCell(PW,PB,X,Y,NW,NB),
staticEvalCells(NW,NB,Value,Final), Sum := Sum + Value,
fail);true.
staticEvalDiagB(PW,PB,Sum,Final) :-
Row1:=1, Row2:=G_nRows- G_nWin+ 1, Col1:=G_nWin, Col2:=G_nCols,
call(for(Row,Row1,Row2),for(Col,Col1,Col2),
NW:=0, NB:=0,
X:=Col- 0, Y:=Row+0, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col- 1, Y:=Row+1, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col- 2, Y:=Row+2, staticEvalCell(PW,PB,X,Y,NW,NB),
X:=Col- 3, Y:=Row+3, staticEvalCell(PW,PB,X,Y,NW,NB),
staticEvalCells(NW,NB,Value,Final), Sum := Sum + Value,
fail);true.
staticEval(PW,PB,Sum,Final) :-
Sum:=0, Final:=0,
staticEvalRows(PW,PB,Sum,Final),
staticEvalCols(PW,PB,Sum,Final),
staticEvalDiagA(PW,PB,Sum,Final),
staticEvalDiagB(PW,PB,Sum,Final).
isFinal(PW,PB) :- not(for(Col,1,G_nCols), ((pullIn(PW,Col,1) ; pullIn(PB,Col,1)) ->
fail; true)), G_Winner:=G_cEMPTY, !.
isFinal(PW,PB) :- Sum:=0, Final:=0, staticEval(PW,PB,Sum,Final), Final=1,
(Sum>0 -> G_Winner:=G_cWHITE ; G_Winner:=G_cBLACK), !.
minimaxW(Depth,PW,PB,BestValue,BestCol) :- (Depth=0 ;isFinal(PW,PB)), !,
BestCol:=1, Final:=0, staticEval(PW,PB,BestValue,Final).
minimaxW(Depth,PW,PB,BestValue,BestCol) :- BestValue:= -30000,
call(for(Col,1,G_nCols), not(pullIn(PW,Col,1) ; pullIn(PB,Col,1)), BackFlag:=0,
makeMove(PW,PB,Col,NewPW), BackFlag=0, NDepth:=Depth- 1, NCol:=0, NValue:=0,
minimaxB(NDepth,NewPW,PB,NValue,NCol),
BackFlag:=1, (NValue>BestValue -> BestValue:=NValue, BestCol:=Col),
fail) ;true.
minimaxB(Depth,PW,PB,BestValue,BestCol) :- ((Depth=0) ;isFinal(PW,PB)), !,
BestCol:=1, Final:=0, staticEval(PW,PB,BestValue,Final).
minimaxB(Depth,PW,PB,BestValue,BestCol) :- BestValue:= 30000,
call(for(Col,1,G_nCols), not(pullIn(PW,Col,1) ; pullIn(PB,Col,1)), BackFlag:=0,
makeMove(PB,PW,Col,NewPB), BackFlag=0, NDepth:=Depth- 1, NCol:=0, NValue:=0,
minimaxW(NDepth,PW,NewPB,NValue,NCol),
BackFlag:=1, (NValue BestValue:=NValue, BestCol:=Col),
fail) ;true.
• |