int ReverseSquare[2] = {-8,8};
game* g;
/*
UpdatePiece updates the Hash Table key, the board and the table_score (the incremental
evaluation) whenever a piece moves.
*/
void UpdatePiece(const int s,const int p,const int start,const int dest)
{
AddKey(s,p,start);
AddKey(s,p,dest);
board[dest]=p;
color[dest]=s;
board[start]=EMPTY;
color[start]=EMPTY;
if(p==K)
kingloc[s] = dest;
}
/*
RemovePiece updates the Hash Table key, the board and the table_score (the incremental
evaluation) whenever a piece is removed.
*/
void RemovePiece(const int s,const int p,const int sq)
{
AddKey(s,p,sq);
board[sq]=EMPTY;
color[sq]=EMPTY;
}
/*
AddPiece updates the Hash Table key, the board and the table_score (the incremental
evaluation) whenever a piece is added.
*/
void AddPiece(const int s,const int p,const int sq)
{
AddKey(s,p,sq);
board[sq]=p;
color[sq]=s;
}
/*
MakeMove updates the board whenever a move is made.
If the King moves two squares then it sees if castling is legal.
If a pawn moves and changes file s without making a capture, then its an en passant capture
and the captured pawn is removed.
If the move is a capture then the captured piece is removed from the board.
If castling permissions are effected then they are updated.
If a pawn moves to the last rank then its promoted. The pawn is removed and a queen is added.
If the move leaves the King in check (for example, if a pinned piece moved), then the move is taken back.
*/
int MakeMove(const int start,const int dest)
{
g = &game_list[hply];
if (abs(start - dest) ==2 && board[start] == K)
{
if (Attack(xside,start))
return false;
if(dest==G1)
{
if (Attack(xside,F1))
return false;
UpdatePiece(side,R,H1,F1);
}
else if(dest==C1)
{
if (Attack(xside,D1))
return false;
UpdatePiece(side,R,A1,D1);
}
else if(dest==G8)
{
if (Attack(xside,F8))
return false;
UpdatePiece(side,R,H8,F8);
}
else if(dest==C8)
{
if (Attack(xside,D8))
return false;
UpdatePiece(side,R,A8,D8);
}
}
g->start = start;
g->dest = dest;
g->capture = board[dest];
g->fifty = fifty;
g->hash = currentkey;
g->lock = currentlock;
++ply;
++hply;
game_list[hply].castle_q[0] = game_list[hply-1].castle_q[0];
game_list[hply].castle_q[1] = game_list[hply-1].castle_q[1];
game_list[hply].castle_k[0] = game_list[hply-1].castle_k[0];
game_list[hply].castle_k[1] = game_list[hply-1].castle_k[1];
fifty++;
if (board[start] == P)
{
fifty = 0;
if (board[dest] == EMPTY && col[start] != col[dest])
{
RemovePiece(xside,P,dest + ReverseSquare[side]);
}
}
if(board[dest]<6)
{
fifty = 0;
RemovePiece(xside,board[dest],dest);
}
if (board[start]==P && (row[dest]==0 || row[dest]==7))//promotion
{
RemovePiece(side,P,start);
AddPiece(side,Q,dest);
game_list[hply].promote = Q;
}
else
{
game_list[hply].promote = 0;
UpdatePiece(side,board[start],start,dest);
}
if(dest == A1 || start == A1)
game_list[hply].castle_q[0] = 0;
else if(dest == H1 || start == H1)
game_list[hply].castle_k[0] = 0;
else if(start == E1)
{
game_list[hply].castle_q[0] = 0;
game_list[hply].castle_k[0] = 0;
}
if(dest == A8 || start == A8)
game_list[hply].castle_q[1] = 0;
else if(dest == H8 || start == H8)
game_list[hply].castle_k[1] = 0;
else if(start == E8)
{
game_list[hply].castle_q[1] = 0;
game_list[hply].castle_k[1] = 0;
}
side ^= 1;
xside ^= 1;
if (Attack(side,kingloc[xside]))
{
TakeBack();
return false;
}
return true;
}
/*
TakeBack is the opposite of MakeMove.
*/
void TakeBack()
{
side ^= 1;
xside ^= 1;
ply--;
hply--;
game* m = &game_list[hply];
int start = m->start;
int dest = m->dest;
fifty = m->fifty;
if (board[dest]==P && m->capture == EMPTY && col[start] != col[dest])
{
AddPiece(xside,P,dest + ReverseSquare[side]);
}
if(game_list[hply+1].promote == Q)
{
AddPiece(side,P,start);
RemovePiece(side,board[dest],dest);
}
else
{
UpdatePiece(side,board[dest],dest,start);
}
if (m->capture != EMPTY)
{
AddPiece(xside,m->capture,dest);
}
if (abs(start - dest) == 2 && board[start] == K)
{
if(dest==G1)
UpdatePiece(side,R,F1,H1);
else if(dest==C1)
UpdatePiece(side,R,D1,A1);
else if(dest==G8)
UpdatePiece(side,R,F8,H8);
else if(dest==C8)
UpdatePiece(side,R,D8,A8);
}
}
/*
MakeRecapture is simpler than MakeMove because there is no castling involved and it
doesn't include en passant capture and promotion.
It the capture is illegal it is taken back.
*/
int MakeRecapture(const int start,const int dest)
{
game_list[hply].start = start;
game_list[hply].dest = dest;
game_list[hply].capture = board[dest];
ply ++;
hply ++;
board[dest] = board[start];
color[dest] = color[start];
board[start] = EMPTY;
color[start] = EMPTY;
if(board[dest]==K)
kingloc[side] = dest;
side ^= 1;
xside ^= 1;
if (Attack(side,kingloc[xside]))
{
UnMakeRecapture();
return false;
}
return true;
}
/*
UnMakeRecapture is very similar to MakeRecapture.
*/
void UnMakeRecapture()
{
side ^= 1;
xside ^= 1;
ply--;
hply--;
int start = game_list[hply].start;
int dest = game_list[hply].dest;
board[start] = board[dest];
color[start] = color[dest];
board[dest] = game_list[hply].capture;
color[dest] = xside;
if(board[start]==K)
kingloc[side] = start;
}
/*
GetHistoryStart returns the start square for the move in the game list.
*/
int GetHistoryStart(const int n)
{
return game_list[n].start;
}
/*
GetHistoryDest returns the dest square for the move in the game list.
*/
int GetHistoryDest(const int n)
{
return game_list[n].dest;
}
No comments:
Post a Comment