.... %%%%%%%%%%%%%%%%%%%%%%%%%%%%validmove(Plyr,State,Proposed)%%%%%%%%%%%%%%%%%%%% %% %% define validmove(Plyr,State,Proposed). % - true if Proposed move by Plyr is valid at State. % holds if the Proposed position is empty ('.'), and % if in any of the 8 directions % there is a sequence of other player's stones % followed by this player's stone without empty spaces % %north validmove(Plyr,State,Proposed) :- get(State,Proposed,.), northLine(State,Plyr,Proposed,Line), last(Line,LastPoint), north(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %south validmove(Plyr,State,Proposed) :- get(State,Proposed,.), southLine(State,Plyr,Proposed,Line), last(Line,LastPoint), south(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %west validmove(Plyr,State,Proposed) :- get(State,Proposed,.), westLine(State,Plyr,Proposed,Line), last(Line,LastPoint), west(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %east validmove(Plyr,State,Proposed) :- get(State,Proposed,.), eastLine(State,Plyr,Proposed,Line), last(Line,LastPoint), east(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %northWest validmove(Plyr,State,Proposed) :- get(State,Proposed,.), northWestLine(State,Plyr,Proposed,Line), last(Line,LastPoint), northWest(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %northEast validmove(Plyr,State,Proposed) :- get(State,Proposed,.), northEastLine(State,Plyr,Proposed,Line), last(Line,LastPoint), northEast(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %southWest validmove(Plyr,State,Proposed) :- get(State,Proposed,.), southWestLine(State,Plyr,Proposed,Line), last(Line,LastPoint), southWest(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). %southEast validmove(Plyr,State,Proposed) :- get(State,Proposed,.), southEastLine(State,Plyr,Proposed,Line), last(Line,LastPoint), southEast(LastPoint,AfterLastPoint), get(State,AfterLastPoint,Plyr). .... % predicates that return adjacent positions along 4 major directions % and 4 minor, diagonal, directions % % major directions % north(Pos,NorthOfPos) north([X,Y], [X, YN]) :- YN is Y - 1. % south(Pos,SouthOfPos) south([X,Y], [X, YS]) :- YS is Y + 1. % west(Pos,WestOfPos) west([X,Y], [XW, Y]) :- XW is X - 1. % east(Pos,WestOfPos) east([X,Y], [XW, Y]) :- XW is X + 1. % minor, diagonal, directions are obtained from the major predicates % using DCG expansion % northEast(Pos,NorthEastOfPos) northEast --> north,east. % northWest(Pos,NorthWestOfPos) northWest --> north,west. % southEast(Pos,SouthEastOfPos) southEast --> south,east. % southWest(Pos,SouthWestOfPos) southWest --> south,west. % +---------------list of lines-----------------------------------------------+ % | +-------line of positions--------+ | % | | position | | % [ [ [X1, Y1], [X2,Y2], [X3,Y3], ...], [[X4, Y4], [X5,Y5], [X6,Y6], ...], ...] % find a line of positions with other player's stones % followed by this player's stones in the North direction % from the given position % do not check the state of the given position % (it can be empty, or contain either player's stones) % % return a line of consecutive other player's stones % in the 8 directions % % example: % given % S = ([[.,.,.,.,.,.], % [.,.,.,.,.,.], % [.,.,2,1,.,.], % [.,.,1,2,.,.], % [.,.,.,2,.,.], % [.,.,.,x,.,.] ]). % % x is at [3,5] % % northLine(S,1,[3,5],[[3,4],[3,3]]) holds % % logic: % if get holds on the adjacent position % and contents are other player's stone % add this position to the list, % otherwise return an empty list northLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), north(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> northLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). % the following prediates are the same as above except in a different % direction southLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), south(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> southLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). westLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), west(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> westLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). eastLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), east(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> eastLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). northWestLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), northWest(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> northWestLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). northEastLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), northEast(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> northEastLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). southWestLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), southWest(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> southWestLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ). southEastLine(State,Plyr,Pos,LineOfPositions) :- otherPlyr(Plyr,OtherPlyr), southEast(Pos,NextPos), ( get(State,NextPos,OtherPlyr) -> southEastLine(State,Plyr,NextPos,FollowingPositions), LineOfPositions = [NextPos|FollowingPositions] ; LineOfPositions = [] ).