%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% reversi.hrf
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

role(blue)
role(red)
base(cell(X,Y,Color)) :- index(X) & index(Y) & role(Color)
base(control(Player)) :- role(Player)
input(Player,move(X,Y)) :- role(Player) & index(X) & index(Y)
input(Player,noop) :- role(Player)

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

init(cell(4,4,blue))
init(cell(4,5,red))
init(cell(5,4,red))
init(cell(5,5,blue))
init(control(blue))

legal(Player,noop) :- true(control(Opponent)) & opponent(Player,Opponent)
legal(Player,move(X,Y)) :- true(control(Player)) & playercanmoveat(Player,X,Y)
legal(Player,noop) :- role(Player) & ~playercanmove(Player)

playercanmove(Player) :- playercanmoveat(Player,Anyx,Anyy)

playercanmoveat(Color,X,Y) :- empty(X,Y) & opponent(Color,Othercolor) & nextcellindir(X,Y,Dir,X2,Y2) & true(cell(X2,Y2,Othercolor)) & hasothercolorindir(X2,Y2,Dir)

nextcellindir(X1,Y1,Dir,X2,Y2) :- index(X1) & index(Y1) & dir(Dir,Xdelta,Ydelta) & add(X1,Xdelta,X2) & add(Y1,Ydelta,Y2)

hasothercolorindir(X1,Y1,Dir) :- true(cell(X1,Y1,Color)) & opponent(Color,Othercolor) & nextcellindir(X1,Y1,Dir,X2,Y2) & true(cell(X2,Y2,Othercolor))
hasothercolorindir(X1,Y1,Dir) :- true(cell(X1,Y1,Color)) & nextcellindir(X1,Y1,Dir,X2,Y2) & true(cell(X2,Y2,Color)) & hasothercolorindir(X2,Y2,Dir)

next(cell(X,Y,Color)) :- does(Color,move(X,Y))
next(cell(X,Y,Color)) :- does(Color,move(Anyx,Anyy)) & affectedcell(X,Y)
next(cell(X,Y,Color)) :- true(cell(X,Y,Color)) & ~affectedcell(X,Y)
next(control(Nextplayer)) :- true(control(Curplayer)) & opponent(Curplayer,Nextplayer)
affectedcell(X,Y) :- affected(X,Y,Anydir,Anycolor)

affected(X2,Y2,Dir,Othercolor) :- does(Player,move(X1,Y1)) & opponent(Player,Othercolor) & nextcellindir(X1,Y1,Dir,X2,Y2) & hasothercolorindir(X2,Y2,Dir) & true(cell(X2,Y2,Othercolor))

affected(X2,Y2,Dir,Color) :- hasothercolorindir(X2,Y2,Dir) & oppdir(Dir,Oppdir) & nextcellindir(X2,Y2,Oppdir,X1,Y1) & affected(X1,Y1,Dir,Color) & true(cell(X2,Y2,Color))

goal(Player,100) :- winner(Player)
goal(Player,0) :- winner(Opponent) & opponent(Player,Opponent)
goal(Player,50) :- role(Player) & ~winner(blue) & ~winner(red)

terminal :- ~playercanmove(blue) & ~playercanmove(red)

empty(X,Y) :- index(X) & index(Y) & ~occupied(X,Y)

occupied(X,Y) :- true(cell(X,Y,Anycolor))

winner(blue) :- totalcount(blue,Bluecount) & totalcount(red,Redcount) & lessthan(Redcount,Bluecount)
winner(red) :- totalcount(blue,Bluecount) & totalcount(red,Redcount) & lessthan(Bluecount,Redcount)

totalcount(Color,N8) :- addrow(Color,1,0,N1) & addrow(Color,2,N1,N2) & addrow(Color,3,N2,N3) & addrow(Color,4,N3,N4) & addrow(Color,5,N4,N5) & addrow(Color,6,N5,N6) & addrow(Color,7,N6,N7) & addrow(Color,8,N7,N8)

addrow(Color,Y,M,N8) :- addcell(Color,1,Y,M,N1) & addcell(Color,2,Y,N1,N2) & addcell(Color,3,Y,N2,N3) & addcell(Color,4,Y,N3,N4) & addcell(Color,5,Y,N4,N5) & addcell(Color,6,Y,N5,N6) & addcell(Color,7,Y,N6,N7) & addcell(Color,8,Y,N7,N8)

addcell(Color,X,Y,M,N) :- true(cell(X,Y,Color)) & succ(M,N)
addcell(Color,X,Y,N,N) :- index(X) & index(Y) & role(Color) & ~true(cell(X,Y,Color)) & succ(N,M)

lessthan(X,Y) :- succ(X,Y)
lessthan(X,Z) :- succ(X,Y) & lessthan(Y,Z)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

opponent(blue,red)
opponent(red,blue)

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

succ(0,1)
succ(1,2)
succ(2,3)
succ(3,4)
succ(4,5)
succ(5,6)
succ(6,7)
succ(7,8)
succ(8,9)
succ(9,10)
succ(10,11)
succ(11,12)
succ(12,13)
succ(13,14)
succ(14,15)
succ(15,16)
succ(16,17)
succ(17,18)
succ(18,19)
succ(19,20)
succ(20,21)
succ(21,22)
succ(22,23)
succ(23,24)
succ(24,25)
succ(25,26)
succ(26,27)
succ(27,28)
succ(28,29)
succ(29,30)
succ(30,31)
succ(31,32)
succ(32,33)
succ(33,34)
succ(34,35)
succ(35,36)
succ(36,37)
succ(37,38)
succ(38,39)
succ(39,40)
succ(40,41)
succ(41,42)
succ(42,43)
succ(43,44)
succ(44,45)
succ(45,46)
succ(46,47)
succ(47,48)
succ(48,49)
succ(49,50)
succ(50,51)
succ(51,52)
succ(52,53)
succ(53,54)
succ(54,55)
succ(55,56)
succ(56,57)
succ(57,58)
succ(58,59)
succ(59,60)
succ(60,61)
succ(61,62)
succ(62,63)
succ(63,64)
succ(64,65)

dir(n,0,p1)
dir(s,0,n1)
dir(e,p1,0)
dir(w,n1,0)
dir(nw,n1,p1)
dir(ne,p1,p1)
dir(se,p1,n1)
dir(sw,n1,n1)

oppdir(nw,se)
oppdir(ne,sw)
oppdir(se,nw)
oppdir(sw,ne)
oppdir(n,s)
oppdir(e,w)
oppdir(s,n)
oppdir(w,e)

add(1,p1,2)
add(2,p1,3)
add(3,p1,4)
add(4,p1,5)
add(5,p1,6)
add(6,p1,7)
add(7,p1,8)
add(1,0,1)
add(2,0,2)
add(3,0,3)
add(4,0,4)
add(5,0,5)
add(6,0,6)
add(7,0,7)
add(8,0,8)
add(8,n1,7)
add(7,n1,6)
add(6,n1,5)
add(5,n1,4)
add(4,n1,3)
add(3,n1,2)
add(2,n1,1)

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