%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
% CHESS DOMAIN THEORY 
% GENERATES LEGAL MOVES
% Designed by vijay@cs.orst.edu for representation work

%/* This file contains the rules of chess. The following chess rules are
%included :   1. legal_move     _ will perform the legal move in a state.
%             2. possible_move  _ indicates which moves are possible in a %state.
%             3. in_check       _ detects a side in check.
%             4. can_move_piece _ finds locations to move to. called by 2.
%             5. valid_move     _ indicates if can_move_piece is a valid move,
%                                 called by 2.


%STATE REPRESENTATION:
%*********************
%In this domain theory each initial board state is denoted by a constant 
%such as state1.  The squares on the board are also denoted by
%constants, such as a8, and b2. Finally, the pieces are each given names, 
%such as wr for the white rook and bk for the black king.  Note that distinctions
%such as black_rook_1 and black_rook_2 are not made in the representation. Empty  
%squares are represented by an imaginary piece called empty (essentially
%a null value).  With this representation, a board configuration is
%represented by 64 assertions. 

%In addition, the structure of the chess board is represented as the
%topology of the squares via the connected relation given at the end 
%of this file. Examples are given below:

%connected(a7,a8,n).
%connected(a7,b7,e).
%connected(a7,b8,ne).

%The constants n, e, ne, and so on represent the eight directions of 
%the compass points.  In all, 372 connected assertions are needed.

%PIECE REPRESENTATION:
%*********************
%Information about each of the pieces is needed in order to define legal moves. 
%The side and type properties of a piece are encoded through the obj_props relation.

obj_props(black_bishop,black,bishop).
obj_props(black_rook,black,rook).
obj_props(black_queen,black,queen).
obj_props(black_king,black,king).

obj_props(white_bishop,white,bishop).
obj_props(white_rook,white,rook).
obj_props(white_queen,white,queen).
obj_props(white_king,white,king).

%%%%%%%%%%%
%We also include the fact that the two sides black and white are opposite:
opposite_sides(white,black).
opposite_sides(black,white).

%%%%%%%%%%%
%Directions n,s,e,w,ne,se,nw,sw are reorganised along x-y axis and diagonals as
%all pieces essentially along these axes. The following are the clauses:

x_y_axis(e).
x_y_axis(n).
x_y_axis(w).
x_y_axis(s).
diagonals(ne).
diagonals(nw).
diagonals(se).
diagonals(sw).
rt_angle(n,e).
rt_angle(n,w).
rt_angle(s,e).
rt_angle(s,w).
rt_angle(e,s).
rt_angle(e,n).
rt_angle(w,s).
rt_angle(w,n).

%%%%%%%%%%
%Directions along which pieces can move are now encoded as moves along the
%axes encoded above. Pos_move_dirs encodes the move-directions for all pieces
%except pawns. Move-direction for knights only represents the initial direction.
%The subsequent right angled turn is encoded in the code that generates the
%actual squares.

pos_move_dirs(king,Dir):-
	  x_y_axis(Dir).

pos_move_dirs(king,Dir):-
  diagonals(Dir).

pos_move_dirs(rook,Dir):-
	  x_y_axis(Dir).

pos_move_dirs(queen,Dir):-
	   x_y_axis(Dir).

pos_move_dirs(queen,Dir):-
   diagonals(Dir).

pos_move_dirs(bishop,Dir):-
	   diagonals(Dir).

pos_move_dirs(knight,Dir):-
   	x_y_axis(Dir).

%%%%%%%%%%
%LEGAL MOVES
%***********
%We are now ready to declare the rule that generates legal moves:
%A legal move is a possible move which does not result in check for the 
%moving side.

legal_move(S,NS,Side):-
   possible_move(S,NS,Side),
	   \+ in_check(NS,Side).

%possible move
%%%%%%%%%%%%%
%This rule checks to see that the piece to move, Piecem, is located
%on the source square From, that Piecet is located on the destination 
%square To, and that the indicated direction and number of squares is 
%legal for the kind of piece being moved. Moves are considered possible
%only if the To location generated is valid i.e is either empty are contains
%a piece of the opposite side on it. It checks that all intervening squares
%are empty. 

possible_move(S,do(op(FromLoc,ToLoc,ObjM,ObjT),S),Side):-
	  on(S,FromLoc,ObjM), 
  obj_props(ObjM,Side,Obj_Class),
	  can_move_piece(S,Side,Obj_Class,FromLoc,ToLoc),
  on(S,ToLoc,ObjT).

can_move_piece(S,Side,Obj_Class,FromLoc,ToLoc) :-
	  pos_move_dirs(Obj_Class,Dir),
	  move_pattern(S,Obj_Class,FromLoc,Dir,ToLoc),
	  valid_move(S,Side,ToLoc).

%move patterns
%%%%%%%%%%%%%%
%move pattern terminates when the To square generated lies outside the board.
%i.e when no more connected clauses match in the direction of move.

move_pattern(S,king,FromLoc,Dir,ToLoc) :-
	  connected(FromLoc,ToLoc,Dir).

move_pattern(S,knight,FromLoc,Dir,ToLoc) :-
	  connected(FromLoc,X1,Dir),
	  connected(X1,X2,Dir),
	  rt_angle(Dir,Rt_angle_dir),
	  connected(X2,ToLoc,Rt_angle_dir).

move_pattern(S,queen,FromLoc,Dir,ToLoc) :-
	   connected(FromLoc,ToLoc,Dir).

move_pattern(S,queen,FromLoc,Dir,ToLoc) :-
   connected(FromLoc,X1,Dir), 
   on(S,X1,empty),
   move_pattern(S,queen,X1,Dir,ToLoc).

move_pattern(S,bishop,FromLoc,Dir,ToLoc) :-
	   connected(FromLoc,ToLoc,Dir).

move_pattern(S,bishop,FromLoc,Dir,ToLoc) :-
   connected(FromLoc,X1,Dir), 
   on(S,X1,empty),
   move_pattern(S,bishop,X1,Dir,ToLoc).

move_pattern(S,rook,FromLoc,Dir,ToLoc) :-
	   connected(FromLoc,ToLoc,Dir).

move_pattern(S,rook,FromLoc,Dir,ToLoc) :-
   connected(FromLoc,X1,Dir), 
   on(S,X1,empty),
   move_pattern(S,rook,X1,Dir,ToLoc).

%in check
%%%%%%%%%
%The in_check rule tries to find out if there exists a piece of the opponent
%that can make a possible move to the location of the king of side `Side'.
%i.e a check is defined as a possible take move of the king by the opponent.

in_check(S,Side):-
	  opposite_sides(Side,Opp_side),
  obj_props(ObjC,Opp_side,_),
	  on(S,FromLoc,ObjC), 
  obj_props(ObjK,Side,king),
	  on(S,ToLoc,ObjK), 
	  possible_move(S,do(op(FromLoc,ToLoc,ObjC,ObjK),S),Opp_side).

%valid moves
%%%%%%%%%%%%
%A valid move is one in which the To location generated is empty or is occupied
%by an opponent's piece.

valid_move(S,Side,ToLoc):-
	   on(S,ToLoc,empty).

valid_move(S,Side1,ToLoc):-
   on(S,ToLoc,Piece2),
   obj_props(Piece2,Side2,_),
   opposite_sides(Side1,Side2).


%FRAME AXIOMS
%************
%These are written for the square facts that define the initial state:

%when we have just moved into square T:
on(St,T,Pm):-
	   St=do(op(F,T,Pm,Pt),S),
	   on(S,T,Pt).

%when we have just moves out of square F:
on(St,F,P):-
	   St=do(op(F,T,Pm,Pt),S),
	   P=empty,
	   on(S,F,Pm).

%frame all other players forward.
on(St,Sq,Pl):-
	   St=do(op(F,T,Pm,Pt),S),
	   on(S,Sq,Pl),
	   Sq\==F,
	   Sq\==T.


%BOARD TOPOLOGY
%**************

connected(a1,a2,n).
connected(a1,b2,ne).
connected(a1,b1,e).
connected(a2,a3,n).
connected(a2,b3,ne).
connected(a2,b2,e).
connected(a2,b1,se).
connected(a2,a1,s).
connected(a3,a4,n).
connected(a3,b4,ne).
connected(a3,b3,e).
connected(a3,b2,se).
connected(a3,a2,s).
connected(a4,a5,n).
connected(a4,b5,ne).
connected(a4,b4,e).
connected(a4,b3,se).
connected(a4,a3,s).
connected(a5,a6,n).
connected(a5,b6,ne).
connected(a5,b5,e).
connected(a5,b4,se).
connected(a5,a4,s).
connected(a6,a7,n).
connected(a6,b7,ne).
connected(a6,b6,e).
connected(a6,b5,se).
connected(a6,a5,s).
connected(a7,a8,n).
connected(a7,b8,ne).
connected(a7,b7,e).
connected(a7,b6,se).
connected(a7,a6,s).
connected(a8,b8,e).
connected(a8,b7,se).
connected(a8,a7,s).
connected(b1,b2,n).
connected(b1,c2,ne).
connected(b1,c1,e).
connected(b1,a1,w).
connected(b1,a2,nw).
connected(b2,b3,n).
connected(b2,c3,ne).
connected(b2,c2,e).
connected(b2,c1,se).
connected(b2,b1,s).
connected(b2,a1,sw).
connected(b2,a2,w).
connected(b2,a3,nw).
connected(b3,b4,n).
connected(b3,c4,ne).
connected(b3,c3,e).
connected(b3,c2,se).
connected(b3,b2,s).
connected(b3,a2,sw).
connected(b3,a3,w).
connected(b3,a4,nw).
connected(b4,b5,n).
connected(b4,c5,ne).
connected(b4,c4,e).
connected(b4,c3,se).
connected(b4,b3,s).
connected(b4,a3,sw).
connected(b4,a4,w).
connected(b4,a5,nw).
connected(b5,b6,n).
connected(b5,c6,ne).
connected(b5,c5,e).
connected(b5,c4,se).
connected(b5,b4,s).
connected(b5,a4,sw).
connected(b5,a5,w).
connected(b5,a6,nw).
connected(b6,b7,n).
connected(b6,c7,ne).
connected(b6,c6,e).
connected(b6,c5,se).
connected(b6,b5,s).
connected(b6,a5,sw).
connected(b6,a6,w).
connected(b6,a7,nw).
connected(b7,b8,n).
connected(b7,c8,ne).
connected(b7,c7,e).
connected(b7,c6,se).
connected(b7,b6,s).
connected(b7,a6,sw).
connected(b7,a7,w).
connected(b7,a8,nw).
connected(b8,c8,e).
connected(b8,c7,se).
connected(b8,b7,s).
connected(b8,a7,sw).
connected(b8,a8,w).
connected(c1,c2,n).
connected(c1,d2,ne).
connected(c1,d1,e).
connected(c1,b1,w).
connected(c1,b2,nw).
connected(c2,c3,n).
connected(c2,d3,ne).
connected(c2,d2,e).
connected(c2,d1,se).
connected(c2,c1,s).
connected(c2,b1,sw).
connected(c2,b2,w).
connected(c2,b3,nw).
connected(c3,c4,n).
connected(c3,d4,ne).
connected(c3,d3,e).
connected(c3,d2,se).
connected(c3,c2,s).
connected(c3,b2,sw).
connected(c3,b3,w).
connected(c3,b4,nw).
connected(c4,c5,n).
connected(c4,d5,ne).
connected(c4,d4,e).
connected(c4,d3,se).
connected(c4,c3,s).
connected(c4,b3,sw).
connected(c4,b4,w).
connected(c4,b5,nw).
connected(c5,c6,n).
connected(c5,d6,ne).
connected(c5,d5,e).
connected(c5,d4,se).
connected(c5,c4,s).
connected(c5,b4,sw).
connected(c5,b5,w).
connected(c5,b6,nw).
connected(c6,c7,n).
connected(c6,d7,ne).
connected(c6,d6,e).
connected(c6,d5,se).
connected(c6,c5,s).
connected(c6,b5,sw).
connected(c6,b6,w).
connected(c6,b7,nw).
connected(c7,c8,n).
connected(c7,d8,ne).
connected(c7,d7,e).
connected(c7,d6,se).
connected(c7,c6,s).
connected(c7,b6,sw).
connected(c7,b7,w).
connected(c7,b8,nw).
connected(c8,d8,e).
connected(c8,d7,se).
connected(c8,c7,s).
connected(c8,b7,sw).
connected(c8,b8,w).
connected(d1,d2,n).
connected(d1,e2,ne).
connected(d1,e1,e).
connected(d1,c1,w).
connected(d1,c2,nw).
connected(d2,d3,n).
connected(d2,e3,ne).
connected(d2,e2,e).
connected(d2,e1,se).
connected(d2,d1,s).
connected(d2,c1,sw).
connected(d2,c2,w).
connected(d2,c3,nw).
connected(d3,d4,n).
connected(d3,e4,ne).
connected(d3,e3,e).
connected(d3,e2,se).
connected(d3,d2,s).
connected(d3,c2,sw).
connected(d3,c3,w).
connected(d3,c4,nw).
connected(d4,d5,n).
connected(d4,e5,ne).
connected(d4,e4,e).
connected(d4,e3,se).
connected(d4,d3,s).
connected(d4,c3,sw).
connected(d4,c4,w).
connected(d4,c5,nw).
connected(d5,d6,n).
connected(d5,e6,ne).
connected(d5,e5,e).
connected(d5,e4,se).
connected(d5,d4,s).
connected(d5,c4,sw).
connected(d5,c5,w).
connected(d5,c6,nw).
connected(d6,d7,n).
connected(d6,e7,ne).
connected(d6,e6,e).
connected(d6,e5,se).
connected(d6,d5,s).
connected(d6,c5,sw).
connected(d6,c6,w).
connected(d6,c7,nw).
connected(d7,d8,n).
connected(d7,e8,ne).
connected(d7,e7,e).
connected(d7,e6,se).
connected(d7,d6,s).
connected(d7,c6,sw).
connected(d7,c7,w).
connected(d7,c8,nw).
connected(d8,e8,e).
connected(d8,e7,se).
connected(d8,d7,s).
connected(d8,c7,sw).
connected(d8,c8,w).
connected(e1,e2,n).
connected(e1,f2,ne).
connected(e1,f1,e).
connected(e1,d1,w).
connected(e1,d2,nw).
connected(e2,e3,n).
connected(e2,f3,ne).
connected(e2,f2,e).
connected(e2,f1,se).
connected(e2,e1,s).
connected(e2,d1,sw).
connected(e2,d2,w).
connected(e2,d3,nw).
connected(e3,e4,n).
connected(e3,f4,ne).
connected(e3,f3,e).
connected(e3,f2,se).
connected(e3,e2,s).
connected(e3,d2,sw).
connected(e3,d3,w).
connected(e3,d4,nw).
connected(e4,e5,n).
connected(e4,f5,ne).
connected(e4,f4,e).
connected(e4,f3,se).
connected(e4,e3,s).
connected(e4,d3,sw).
connected(e4,d4,w).
connected(e4,d5,nw).
connected(e5,e6,n).
connected(e5,f6,ne).
connected(e5,f5,e).
connected(e5,f4,se).
connected(e5,e4,s).
connected(e5,d4,sw).
connected(e5,d5,w).
connected(e5,d6,nw).
connected(e6,e7,n).
connected(e6,f7,ne).
connected(e6,f6,e).
connected(e6,f5,se).
connected(e6,e5,s).
connected(e6,d5,sw).
connected(e6,d6,w).
connected(e6,d7,nw).
connected(e7,e8,n).
connected(e7,f8,ne).
connected(e7,f7,e).
connected(e7,f6,se).
connected(e7,e6,s).
connected(e7,d6,sw).
connected(e7,d7,w).
connected(e7,d8,nw).
connected(e8,f8,e).
connected(e8,f7,se).
connected(e8,e7,s).
connected(e8,d7,sw).
connected(e8,d8,w).
connected(f1,f2,n).
connected(f1,g2,ne).
connected(f1,g1,e).
connected(f1,e1,w).
connected(f1,e2,nw).
connected(f2,f3,n).
connected(f2,g3,ne).
connected(f2,g2,e).
connected(f2,g1,se).
connected(f2,f1,s).
connected(f2,e1,sw).
connected(f2,e2,w).
connected(f2,e3,nw).
connected(f3,f4,n).
connected(f3,g4,ne).
connected(f3,g3,e).
connected(f3,g2,se).
connected(f3,f2,s).
connected(f3,e2,sw).
connected(f3,e3,w).
connected(f3,e4,nw).
connected(f4,f5,n).
connected(f4,g5,ne).
connected(f4,g4,e).
connected(f4,g3,se).
connected(f4,f3,s).
connected(f4,e3,sw).
connected(f4,e4,w).
connected(f4,e5,nw).
connected(f5,f6,n).
connected(f5,g6,ne).
connected(f5,g5,e).
connected(f5,g4,se).
connected(f5,f4,s).
connected(f5,e4,sw).
connected(f5,e5,w).
connected(f5,e6,nw).
connected(f6,f7,n).
connected(f6,g7,ne).
connected(f6,g6,e).
connected(f6,g5,se).
connected(f6,f5,s).
connected(f6,e5,sw).
connected(f6,e6,w).
connected(f6,e7,nw).
connected(f7,f8,n).
connected(f7,g8,ne).
connected(f7,g7,e).
connected(f7,g6,se).
connected(f7,f6,s).
connected(f7,e6,sw).
connected(f7,e7,w).
connected(f7,e8,nw).
connected(f8,g8,e).
connected(f8,g7,se).
connected(f8,f7,s).
connected(f8,e7,sw).
connected(f8,e8,w).
connected(g1,g2,n).
connected(g1,h2,ne).
connected(g1,h1,e).
connected(g1,f1,w).
connected(g1,f2,nw).
connected(g2,g3,n).
connected(g2,h3,ne).
connected(g2,h2,e).
connected(g2,h1,se).
connected(g2,g1,s).
connected(g2,f1,sw).
connected(g2,f2,w).
connected(g2,f3,nw).
connected(g3,g4,n).
connected(g3,h4,ne).
connected(g3,h3,e).
connected(g3,h2,se).
connected(g3,g2,s).
connected(g3,f2,sw).
connected(g3,f3,w).
connected(g3,f4,nw).
connected(g4,g5,n).
connected(g4,h5,ne).
connected(g4,h4,e).
connected(g4,h3,se).
connected(g4,g3,s).
connected(g4,f3,sw).
connected(g4,f4,w).
connected(g4,f5,nw).
connected(g5,g6,n).
connected(g5,h6,ne).
connected(g5,h5,e).
connected(g5,h4,se).
connected(g5,g4,s).
connected(g5,f4,sw).
connected(g5,f5,w).
connected(g5,f6,nw).
connected(g6,g7,n).
connected(g6,h7,ne).
connected(g6,h6,e).
connected(g6,h5,se).
connected(g6,g5,s).
connected(g6,f5,sw).
connected(g6,f6,w).
connected(g6,f7,nw).
connected(g7,g8,n).
connected(g7,h8,ne).
connected(g7,h7,e).
connected(g7,h6,se).
connected(g7,g6,s).
connected(g7,f6,sw).
connected(g7,f7,w).
connected(g7,f8,nw).
connected(g8,h8,e).
connected(g8,h7,se).
connected(g8,g7,s).
connected(g8,f7,sw).
connected(g8,f8,w).
connected(h1,h2,n).
connected(h1,g1,w).
connected(h1,g2,nw).
connected(h2,h3,n).
connected(h2,h1,s).
connected(h2,g1,sw).
connected(h2,g2,w).
connected(h2,g3,nw).
connected(h3,h4,n).
connected(h3,h2,s).
connected(h3,g2,sw).
connected(h3,g3,w).
connected(h3,g4,nw).
connected(h4,h5,n).
connected(h4,h3,s).
connected(h4,g3,sw).
connected(h4,g4,w).
connected(h4,g5,nw).
connected(h5,h6,n).
connected(h5,h4,s).
connected(h5,g4,sw).
connected(h5,g5,w).
connected(h5,g6,nw).
connected(h6,h7,n).
connected(h6,h5,s).
connected(h6,g5,sw).
connected(h6,g6,w).
connected(h6,g7,nw).
connected(h7,h8,n).
connected(h7,h6,s).
connected(h7,g6,sw).
connected(h7,g7,w).
connected(h7,g8,nw).
connected(h8,h7,s).
connected(h8,g7,sw).
connected(h8,g8,w).

%EXAMPLE STATE
%*********************

%Example of state, called state1 from Flann & Dietterich, 1989 Figure 4(d)

on(state1,a1,white_rook).
on(state1,b1,empty).
on(state1,c1,empty).
on(state1,d1,empty).
on(state1,e1,empty).
on(state1,f1,empty).
on(state1,g1,empty).
on(state1,h1,empty).
on(state1,a2,white_pawn).
on(state1,b2,empty).
on(state1,c2,white_king).
on(state1,d2,empty).
on(state1,e2,empty).
on(state1,f2,white_pawn).
on(state1,g2,empty).
on(state1,h2,empty).
on(state1,a3,empty).
on(state1,b3,white_pawn).
on(state1,c3,empty).
on(state1,d3,empty).
on(state1,e3,white_queen).
on(state1,f3,empty).
on(state1,g3,empty).
on(state1,h3,empty).
on(state1,a4,empty).
on(state1,b4,empty).
on(state1,c4,empty).
on(state1,d4,empty).
on(state1,e4,empty).
on(state1,f4,empty).
on(state1,g4,white_knight).
on(state1,h4,empty).
on(state1,a5,empty).
on(state1,b5,empty).
on(state1,c5,empty).
on(state1,d5,empty).
on(state1,e5,empty).
on(state1,f5,empty).
on(state1,g5,empty).
on(state1,h5,empty).
on(state1,a6,black_pawn).
on(state1,b6,empty).
on(state1,c6,black_rook).
on(state1,d6,empty).
on(state1,e6,empty).
on(state1,f6,empty).
on(state1,g6,empty).
on(state1,h6,empty).
on(state1,a7,empty).
on(state1,b7,empty).
on(state1,c7,empty).
on(state1,d7,empty).
on(state1,e7,empty).
on(state1,f7,empty).
on(state1,g7,black_pawn).
on(state1,h7,empty).
on(state1,a8,black_rook).
on(state1,b8,empty).
on(state1,c8,black_bishop).
on(state1,d8,empty).
on(state1,e8,empty).
on(state1,f8,empty).
on(state1,g8,black_king).
on(state1,h8,empty).
