Implement unmaking and castle rights
This commit is contained in:
parent
8abb6d46fb
commit
fd808ef5e0
46
Board.h
46
Board.h
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue