SebLague / Chess-Challenge

Create your own tiny chess bot!
https://www.youtube.com/watch?v=Ne40a5LkK6A
MIT License
1.78k stars 1.06k forks source link

Feature request: move.IsCheck #392

Open TomaszJaworski777 opened 1 year ago

TomaszJaworski777 commented 1 year ago

would help much with move ordering

hypnotox commented 1 year ago

You can currently use:

board.MakeMove(move);
var moveIsCheck = board.IsInCheck();
board.UndoMove(move);

I'm not sure if they want to introduce QoL methods which help reduce token usage now, but they have added some recently, so we'll see.

TomaszJaworski777 commented 1 year ago

You can currently use:

board.MakeMove(move);
var moveIsCheck = board.IsInCheck();
board.UndoMove(move);

I'm not sure if they want to introduce QoL methods which help reduce token usage now, but they have added some recently, so we'll see.

its not even QoL, this making moves for every move while setting up order will be a huge performance hit

SebLague commented 1 year ago

I agree that this would be useful, but it’s unfortunately a shortcoming of my engine that it currently doesn’t have a way to know if a move gives check without actually making the move.

rowan-mcalpin commented 1 year ago

@SebLague I haven't looked into your engine backend enough to know how reasonable this is, but here is my thought on checking if the move is check without making it.

When a piece moves, it gets a new set of positions it could move to. If it's a knight or a pawn, you just iterate through each place and check if the king is there. If it is, then the move is check.

For bishops, rooks, and queens, you don't need to check all of them, you only need to check the endpoints. This is because the endpoints are either the wall, or a piece that can be captured (or a piece of the same color, which would be treated the same as a wall). It is impossible to have a piece along the line of movement that isn't at the end because they aren't able to jump. Check each of the endpoints of the lines, and if any of them are the opponents king, it is check.

Discovered checks (where a piece moves out of the way and a different piece delivers check) would be more difficult. The best approach I can think of is checking all of the pieces that it is possible to cause discovered checks.

We can immediately rule out knights, kings, and pawns. This is because they either (a) cannot have a piece in between them and the piece they are attacking or (b) cannot be blocked by a piece (knights can jump).

This leaves queens, bishops, and rooks. A total of 5 pieces to check. Once again, we only need to check the 4 (or, in the queens case, 8) endpoints of the lines the pieces can capture. If the piece that was moved was one of those 5 pieces, we don't need to check it again.

Actually implementing it might be a little bit difficult but I think it would be a lot more efficient than making a move, checking if the board is in check, then unmaking it.