%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% skirmish1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% metadata
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

role(white)

base(location(cell(X,Y),piece(R,king,1))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,queen,1))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,bishop,1))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,bishop,2))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,knight,1))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,knight,2))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,rook,1))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,rook,2))) :- file(X) & rank(Y) & role(R)
base(location(cell(X,Y),piece(R,pawn,N))) :- file(X) & rank(Y) & role(R) & rank(N)
base(white(N)) :- num(N)
base(black(N)) :- num(N)
base(control(Role)) :- role(Role)
base(step(N)) :- num(N) & leq(1,N) & leq(N,20)

action(move(P,C)) :- ispiece(P) & iscell(C)
action(leave(P)) :- ispiece(P)
action(capture(Q)) :- ispiece(Q)
action(clean(Y)) :- iscell(Y)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% init
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init(location(cell(a,8),piece(black,rook,1)))
init(location(cell(b,8),piece(black,knight,1)))
init(location(cell(c,8),piece(black,bishop,1)))
init(location(cell(d,8),piece(black,queen,1)))
init(location(cell(e,8),piece(black,king,1)))
init(location(cell(f,8),piece(black,bishop,2)))
init(location(cell(g,8),piece(black,knight,2)))
init(location(cell(h,8),piece(black,rook,2)))

init(location(cell(a,7),piece(black,pawn,1)))
init(location(cell(b,7),piece(black,pawn,2)))
init(location(cell(c,7),piece(black,pawn,3)))
init(location(cell(d,7),piece(black,pawn,4)))
init(location(cell(e,7),piece(black,pawn,5)))
init(location(cell(f,7),piece(black,pawn,6)))
init(location(cell(g,7),piece(black,pawn,7)))
init(location(cell(h,7),piece(black,pawn,8)))

init(location(cell(a,2),piece(white,pawn,1)))
init(location(cell(b,2),piece(white,pawn,2)))
init(location(cell(c,2),piece(white,pawn,3)))
init(location(cell(d,2),piece(white,pawn,4)))
init(location(cell(e,2),piece(white,pawn,5)))
init(location(cell(f,2),piece(white,pawn,6)))
init(location(cell(g,2),piece(white,pawn,7)))
init(location(cell(h,2),piece(white,pawn,8)))

init(location(cell(a,1),piece(white,rook,1)))
init(location(cell(b,1),piece(white,knight,1)))
init(location(cell(c,1),piece(white,bishop,1)))
init(location(cell(d,1),piece(white,queen,1)))
init(location(cell(e,1),piece(white,king,1)))
init(location(cell(f,1),piece(white,bishop,2)))
init(location(cell(g,1),piece(white,knight,2)))
init(location(cell(h,1),piece(white,rook,2)))

init(white(50))
init(control(white))
init(step(1))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% legal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

legal(move(piece(R,P,N),cell(X,Y))) :-
  control(R) &
  location(cell(U,V),piece(R,P,N)) &
  validmove(piece(R,P,N),U,V,X,Y) &
  ~celloccupiedby(X,Y,R)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

move(P,Y) :: location(Y,P) & leave(P) & clean(Y) & kerchunk

leave(P) :: location(X,P) ==> ~location(X,P)
clean(Y) :: location(Y,Q) ==> ~location(Y,Q) & capture(Q)

capture(piece(black,Q,N)) ::
  white(OW) & worth(Q,W) & plus(OW,W,NW) ==> ~white(OW) & white(NW)

capture(piece(black,Q,N)) ::
  black(OB) & worth(Q,W) & minus(OB,W,NB) ==> ~black(OB) & black(NB)

kerchunk :: step(M) & plus(M,1,N) ==> ~step(M) & step(N)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% goal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

goal(white,N) :- white(N)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% terminal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

terminal :- step(20)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% views
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

validmove(piece(white,pawn,N),U,V,X,Y) :- whitepawnmove(U,V,X,Y) & rank(N)
validmove(piece(black,pawn,N),U,V,X,Y) :- blackpawnmove(U,V,X,Y) & rank(N)
validmove(piece(R,rook,1),U,V,X,Y) :- role(R) & rookmove(U,V,X,Y)
validmove(piece(R,rook,2),U,V,X,Y) :- role(R) & rookmove(U,V,X,Y)
validmove(piece(R,knight,1),U,V,X,Y) :- role(R) & knightmove(U,V,X,Y)
validmove(piece(R,knight,2),U,V,X,Y) :- role(R) & knightmove(U,V,X,Y)
validmove(piece(R,bishop,1),U,V,X,Y) :- role(R) & bishopmove(U,V,X,Y)
validmove(piece(R,bishop,2),U,V,X,Y) :- role(R) & bishopmove(U,V,X,Y)
validmove(piece(R,queen,1),U,V,X,Y) :- role(R) & queenmove(U,V,X,Y)
validmove(piece(R,king,1),U,V,X,Y) :- role(R) & kingmove(U,V,X,Y)

whitepawnmove(X,2,X,4) :- cellempty(X,3) & cellempty(X,4)
whitepawnmove(X,Y1,X,Y2) :- nextrank(Y1,Y2) & cellempty(X,Y2)
whitepawnmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y1,Y2) & celloccupiedby(X2,Y2,black)
whitepawnmove(X1,Y1,X2,Y2) :- nextfile(X2,X1) & nextrank(Y1,Y2) & celloccupiedby(X2,Y2,black)

blackpawnmove(X,7,X,5) :- cellempty(X,6) & cellempty(X,5)
blackpawnmove(X,Y1,X,Y2) :- nextrank(Y2,Y1) & cellempty(X,Y2)
blackpawnmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y2,Y1) & celloccupiedby(X2,Y2,white)
blackpawnmove(X1,Y1,X2,Y2) :- nextfile(X2,X1) & nextrank(Y2,Y1) & celloccupiedby(X2,Y2,white)

rookmove(X1,Y1,X2,Y2) :- horizontalmove(X1,Y1,X2,Y2)
rookmove(X1,Y1,X2,Y2) :- horizontalmove(X2,Y2,X1,Y1)
rookmove(X1,Y1,X2,Y2) :- verticalmove(X1,Y1,X2,Y2)
rookmove(X1,Y1,X2,Y2) :- verticalmove(X2,Y2,X1,Y1)

knightmove(X1,Y1,X2,Y2) :- skipfile(X1,X2) & nextrank(Y1,Y2)
knightmove(X1,Y1,X2,Y2) :- skipfile(X1,X2) & nextrank(Y2,Y1)
knightmove(X1,Y1,X2,Y2) :- skipfile(X2,X1) & nextrank(Y1,Y2)
knightmove(X1,Y1,X2,Y2) :- skipfile(X2,X1) & nextrank(Y2,Y1)
knightmove(X1,Y1,X2,Y2) :- skiprank(Y1,Y2) & nextfile(X1,X2)
knightmove(X1,Y1,X2,Y2) :- skiprank(Y1,Y2) & nextfile(X2,X1)
knightmove(X1,Y1,X2,Y2) :- skiprank(Y2,Y1) & nextfile(X1,X2)
knightmove(X1,Y1,X2,Y2) :- skiprank(Y2,Y1) & nextfile(X2,X1)

bishopmove(X1,Y1,X2,Y2) :- northeastmove(X1,Y1,X2,Y2)
bishopmove(X1,Y1,X2,Y2) :- northeastmove(X2,Y2,X1,Y1)
bishopmove(X1,Y1,X2,Y2) :- southeastmove(X1,Y1,X2,Y2)
bishopmove(X1,Y1,X2,Y2) :- southeastmove(X2,Y2,X1,Y1)

queenmove(X1,Y1,X2,Y2) :- rookmove(X1,Y1,X2,Y2)
queenmove(X1,Y1,X2,Y2) :- bishopmove(X1,Y1,X2,Y2)

kingmove(X1,Y,X2,Y) :- nextfile(X1,X2) & rank(Y)
kingmove(X1,Y,X2,Y) :- nextfile(X2,X1) & rank(Y)
kingmove(X,Y1,X,Y2) :- nextrank(Y1,Y2) & file(X)
kingmove(X,Y1,X,Y2) :- nextrank(Y2,Y1) & file(X)
kingmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y1,Y2)
kingmove(X1,Y1,X2,Y2) :- nextfile(X2,X1) & nextrank(Y1,Y2)
kingmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y2,Y1)
kingmove(X1,Y1,X2,Y2) :- nextfile(X2,X1) & nextrank(Y2,Y1)

horizontalmove(X1,Y,X2,Y) :- nextfile(X1,X2) & rank(Y)
horizontalmove(X1,Y,X3,Y) :- nextfile(X1,X2) & cellempty(X2,Y) & horizontalmove(X2,Y,X3,Y)

verticalmove(X,Y1,X,Y2) :- nextrank(Y1,Y2) & file(X)
verticalmove(X,Y1,X,Y3) :- nextrank(Y1,Y2) & cellempty(X,Y2) & verticalmove(X,Y2,X,Y3)

northeastmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y1,Y2)
northeastmove(X1,Y1,X3,Y3) :- nextfile(X1,X2) & nextrank(Y1,Y2) & cellempty(X2,Y2) & northeastmove(X2,Y2,X3,Y3)

southeastmove(X1,Y1,X2,Y2) :- nextfile(X1,X2) & nextrank(Y2,Y1)
southeastmove(X1,Y1,X3,Y3) :- nextfile(X1,X2) & nextrank(Y2,Y1) & cellempty(X2,Y2) & southeastmove(X2,Y2,X3,Y3)

adjacent(cell(X1,Y),cell(X2,Y)) :- nextfile(X1,X2) & rank(Y)
adjacent(cell(X1,Y),cell(X2,Y)) :- nextfile(X2,X1) & rank(Y)
adjacent(cell(X,Y1),cell(X,Y2)) :- file(X) & nextrank(Y1,Y2) 
adjacent(cell(X,Y1),cell(X,Y2)) :- file(X) & nextrank(Y2,Y1)
adjacent(cell(X1,Y1),cell(X2,Y2)) :- nextfile(X1,X2) & nextrank(Y1,Y2)
adjacent(cell(X1,Y1),cell(X2,Y2)) :- nextfile(X2,X1) & nextrank(Y1,Y2)
adjacent(cell(X1,Y1),cell(X2,Y2)) :- nextfile(X1,X2) & nextrank(Y2,Y1)
adjacent(cell(X1,Y1),cell(X2,Y2)) :- nextfile(X2,X1) & nextrank(Y2,Y1)

ispiece(piece(R,king,1)) :- role(R)
ispiece(piece(R,queen,1)) :- role(R)
ispiece(piece(R,bishop,1)) :- role(R)
ispiece(piece(R,bishop,2)) :- role(R)
ispiece(piece(R,knight,1)) :- role(R)
ispiece(piece(R,knight,2)) :- role(R)
ispiece(piece(R,rook,1)) :- role(R)
ispiece(piece(R,rook,2)) :- role(R)
ispiece(piece(R,pawn,N)) :- role(R) & rank(N)

iscell(cell(X,Y)) :- file(X) & rank(Y)

cellempty(X,Y) :- file(X) & rank(Y) & ~celloccupied(X,Y)
celloccupied(X,Y) :- location(cell(X,Y),Piece)
celloccupiedby(X,Y,R) :- location(cell(X,Y),piece(R,P,N))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% facts
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

file(a)
file(b)
file(c)
file(d)
file(e)
file(f)
file(g)
file(h)

rank(1)
rank(2)
rank(3)
rank(4)
rank(5)
rank(6)
rank(7)
rank(8)

nextrank(1,2)
nextrank(2,3)
nextrank(3,4)
nextrank(4,5)
nextrank(5,6)
nextrank(6,7)
nextrank(7,8)

nextfile(a,b)
nextfile(b,c)
nextfile(c,d)
nextfile(d,e)
nextfile(e,f)
nextfile(f,g)
nextfile(g,h)

skiprank(1,3)
skiprank(2,4)
skiprank(3,5)
skiprank(4,6)
skiprank(5,7)
skiprank(6,8)

skipfile(a,c)
skipfile(b,d)
skipfile(c,e)
skipfile(d,f)
skipfile(e,g)
skipfile(f,h)

worth(king,11)
worth(queen,9)
worth(rook,5)
worth(bishop,3)
worth(knight,3)
worth(pawn,1)

num(0)
num(1)
num(2)
num(3)
num(4)
num(5)
num(6)
num(7)
num(8)
num(9)
num(10)
num(11)
num(12)
num(13)
num(14)
num(15)
num(16)
num(17)
num(18)
num(19)
num(20)
num(21)
num(22)
num(23)
num(24)
num(25)
num(26)
num(27)
num(28)
num(29)
num(30)
num(31)
num(32)
num(33)
num(34)
num(35)
num(36)
num(37)
num(38)
num(39)
num(40)
num(41)
num(42)
num(43)
num(44)
num(45)
num(46)
num(47)
num(48)
num(49)
num(50)
num(51)
num(52)
num(53)
num(54)
num(55)
num(56)
num(57)
num(58)
num(59)
num(60)
num(61)
num(62)
num(63)
num(64)
num(65)
num(66)
num(67)
num(68)
num(69)
num(70)
num(71)
num(72)
num(73)
num(74)
num(75)
num(76)
num(77)
num(78)
num(79)
num(80)
num(81)
num(82)
num(83)
num(84)
num(85)
num(86)
num(87)
num(88)
num(89)
num(90)
num(91)
num(92)
num(93)
num(94)
num(95)
num(96)
num(97)
num(98)
num(99)
num(100)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
