% % Code to check for a win in a connect4 board. % % % valpos(X,Y,B,W,M1,M2) := M1 represents a sum so far. M2 represents sum % after checking position (X,Y). M2 is reset to 0 % if (X,Y) is not on board or not of type W and % M1 is less than 4. Otherwise if it is of type W % M2:=M1+1. else if M1 >=4 then M2:=M1. % valpos(X,Y,B,_,M1,M2) :-ith(X,B,Col), llength(Col,N), N =4 -> M2 is M1; M2 is 0). valpos(X,Y,B,W,M1,M2) :- ith(X,B,Col), ith(Y,Col,W), M2 is M1+1. valpos(_,_,_,_,M1,M2) :- (M1 >=4 -> M2 is M1; M2 is 0). % % psum(I,Pos,Sgn,B,W,PSum,Sum) := % Sum along a line of slope Sgn through the point (Pos,N) in board B % where W's are being check for four in a row. PSum % is the accumulating value. Sum is the final value. % psum(8,_,_,_,_,_,Sum,Sum). psum(I,Pos,Sgn,N,B,W,PSum,Sum) :- Z is I-Pos, Y is Sgn*Z+N, ((Y =<6, Y>0) -> valpos(I,Y,B,W,PSum,PSum2) ;PSum2 is PSum), J is I+1, psum(J,Pos,Sgn,N,B,W,PSum2,Sum). % % winvert(Pos,B,W) := checks if move Pos in board B produces a win vertically % winvert(Pos,B,W) :- !, ith(Pos,B,Col), llength(Col,N), N >= 4, N1 is N-1, ith(N1,Col,W), N2 is N-2, ith(N2,Col,W), N3 is N-3, ith(N3,Col,W). % % winhorurdr(Pos,B,W) := % check if there is a win horizontally, or up to the right, or up to the % left in board B at position Pos playing W. % winhorurdr(Pos,B,W) :- ith(Pos,B,Col), llength(Col,N), psum(1,1,0,N,B,W,0,Sumh), %compute horizontal sum psum(1,Pos,-1,N,B,W,0,Sumdr), %downright diagonal sum psum(1,Pos,1,N,B,W,0,Sumur), %upright diagonal sum !, (Sumh >= 4 ; Sumdr >= 4 ; Sumur >=4 ). % The following code checks for a win win(Pos,B,c,W,winc) :- winvert(Pos,B,W). win(Pos,B,c,W,winc) :- winhorurdr(Pos,B,W). win(Pos,B,p,W,winp) :- winvert(Pos,B,W). win(Pos,B,p,W,winp) :- winhorurdr(Pos,B,W). % if no win then continue win(_,_,_,_,cont).