Implement unmaking and castle rights

This commit is contained in:
Quinten Kock 2020-06-18 21:19:20 +02:00
parent 8abb6d46fb
commit fd808ef5e0
1 changed files with 30 additions and 16 deletions

46
Board.h
View File

@ -52,7 +52,7 @@ void board_init() {
struct Unmove {
byte sq_from; // 0b(1unused)(3rank)(1unused)(3file)
byte sq_from; // 0b(1kingside_castle?)(3rank)(1queenside_castle?)(3file)
byte sq_to; // 0b(1promoted?)(3rank)(1ep_capture?)(3file)
byte captured; // 0b(4enpassantinfo)(1color)(3piecetype)
byte revmov; // 8bit integer
@ -136,9 +136,9 @@ void make(Move m) {
byte piece_type = field[m.sq_from] & 0x7;
if(u.captured || piece_type == W_PAWN) {
field[PTR_REVMOV]++;
} else {
field[PTR_REVMOV] = 0;
} else {
field[PTR_REVMOV]++;
}
// Calculate the move 'amount' (unique signature for dx,dy)
@ -162,23 +162,28 @@ void make(Move m) {
}
// Handle castling rights
// First store the current rights in the unmove
byte our_rights = field[PTR_SIDE_AND_CASTLERIGHT] >> (1 + 2*black_moving());
if(our_rights & 0b10) // kingside allowed
u.sq_from |= 0x80;
if(our_rights & 0b01) // queenside allowed
u.sq_from |= 0x08;
// We are doing the simple way:
// unset it any time a move is made from the original position.
// TODO handle castle rights and unmake
if(m.sq_from == 0x00) // white queenside rook
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b00010;
if(m.sq_from == 0x07) // white kingside rook
else if(m.sq_from == 0x07) // white kingside rook
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b00100;
if(m.sq_from == 0x04) // white king
else if(m.sq_from == 0x04) // white king
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b00110;
if(m.sq_from == 0x70) // black queenside rook
else if(m.sq_from == 0x70) // black queenside rook
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b01000;
if(m.sq_from == 0x77) // black kingside rook
else if(m.sq_from == 0x77) // black kingside rook
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b10000;
if(m.sq_from == 0x74) // black king
else if(m.sq_from == 0x74) // black king
field[PTR_SIDE_AND_CASTLERIGHT] &= ~0b11000;
// TODO: test enpassant code more than basics
// handle enpassant capture
@ -233,35 +238,44 @@ void unmake() {
Unmove u = read_unmove();
field[PTR_REVMOV] = u.revmov;
byte sq_from = u.sq_from & 0x77;
byte sq_to = u.sq_to & 0x77;
byte prom_ep_capt = u.sq_to & 0x88;
if(prom_ep_capt == 0) {
// regular move
field[u.sq_from] = field[sq_to];
field[sq_from] = field[sq_to];
} else if (prom_ep_capt == 0x80) {
// piece was promoted
// so the source is a pawn
field[u.sq_from] = W_PAWN | (field[u.sq_to] & 0b1000);
field[sq_from] = W_PAWN | (field[sq_to] & 0b1000);
} else if (prom_ep_capt == 0x08) {
// we did an enpassant capture
byte ep_sq = (u.sq_to & 0x07) | (u.sq_from & 0x70);
byte ep_sq = (sq_to & 0x07) | (sq_from & 0x70);
field[ep_sq] = W_PAWN | black_moving() << 3;
// also undo the regular move
field[u.sq_from] = field[sq_to];
field[sq_from] = field[sq_to];
}
byte castleright_offset = 3 - 2*black_moving();
if(u.sq_from & 0x80) {
// restore king side castling rights
field[PTR_SIDE_AND_CASTLERIGHT] |= 0b10 << castleright_offset;
}
if(u.sq_from & 0x08) {
field[PTR_SIDE_AND_CASTLERIGHT] |= 0b01 << castleright_offset;
}
// TODO handle castling rights
int sq_diff = (int)sq_to - (int)u.sq_from;
int sq_diff_abs = abs(sq_diff);
if((field[u.sq_from] & 0x7) == W_KING && sq_diff_abs == 2) {
if((field[sq_from] & 0x7) == W_KING && sq_diff_abs == 2) {
// we castled
byte castle_source = 0x70*!black_moving();
if(sq_diff == 2) {
castle_source += 0x7;
}
byte castle_target = u.sq_from + (sq_diff/2);
byte castle_target = sq_from + (sq_diff/2);
// move rook back to original position
field[castle_source] = field[castle_target];
// and clear where it was put