Chess960 castling check

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
leanchess
Posts: 181
Joined: Sun Dec 08, 2019 8:16 pm
Full name: Dmitry Shechtman

Chess960 castling check

Post by leanchess »

I apologise for the newbie question, but am I correct to assume that:

1. Chess960 requires an additional check iff the castling is A-side AND the rook is on the B square and
2. checking for enemy R or Q on the A square will suffice?

My current implementation uses the upper 4 bits of the castle flags as follows:

Code: Select all

bool check_castle_mask(const board_t* b, uint16_t i) {
	return b->castle & (0x10 << i)
		&& (b->mbox[(i & 2) ? 0x30 : 0x00].v & 0xB0) == ((i & 2) ? 0xA0 : 0xB0);
}
(0xA0/0xB0 are white and black rooks, and 0xE0/0xF0 are white and black queens, respectively).

Thanks in advance!
User avatar
leanchess
Posts: 181
Joined: Sun Dec 08, 2019 8:16 pm
Full name: Dmitry Shechtman

Re: Chess960 castling check

Post by leanchess »

A (hopefully) optimised function using a single 64-bit value for all castlings:

Code: Select all

bool check_castle_rook(const board_t* b, uint16_t i) {
	piece_square_t rook = {b->crooks.v >> (i << 4)};
	return (b->mbox[rook.square].v & (PS_SQUARE | PS_ROOK)) == rook.v;
}
Mask generation function:

Code: Select all

piece_square_t get_castle_rook(piece_square_t rook, uint16_t i) {
	return ((i & 1) && (rook.square & 7) == FILE_B)
		? (piece_square_t){
			.type   = (i & 2) ? TYPE_ROOK_WHITE : TYPE_ROOK_BLACK,
			.square = (i & 2) ? A8 : A1}
		: (piece_square_t){
			.type   = TYPE_NONE,
			.square = SQ_NONE
		};
}
Perhaps this more readable version will elicit some replies :wink:
User avatar
leanchess
Posts: 181
Joined: Sun Dec 08, 2019 8:16 pm
Full name: Dmitry Shechtman

Re: Chess960 castling check

Post by leanchess »

As it turns out, CPW is quite helpful if read carefully:
url=https://www.chessprogramming.org/Legal_Move#Not_in_Check wrote:
  • While castling, rook is not pinned horizontally in Chess960
This is much simpler:

Code: Select all

bool check_castle_rook(const board_t* b, uint16_t i, pins_t pins) {
	return b->castles[i].rook & pins.horiz;
}
although it requires 4x8=32 bytes added to board_t.

However, every uint64_t in castle_t could be turned into uint16_t courtesy of pext:

Code: Select all

bool check_castle_rook(const board_t* b, uint16_t i, pins_t pins) {
	return _pext_u64(b->castles[i].rook, 0xFF000000000000FF) & pins.horiz;
}
User avatar
leanchess
Posts: 181
Joined: Sun Dec 08, 2019 8:16 pm
Full name: Dmitry Shechtman

Re: Chess960 castling check

Post by leanchess »

Correction: _pdep_u64 instead of _pext_u64.