For castling moves, checking if the in-between squares are empty can easily be done in the move generator, but what is the best strategy to check if these squares are attacked or not?
It this normally done in the move generator, or in makemove (like checking to see if a move leaves the king in check)?
Castling legality check
Moderators: hgm, Rebel, chrisw
-
- Posts: 1243
- Joined: Sat Dec 13, 2008 7:00 pm
Re: Castling legality check
If you do it in the move generator, you will waste time if you never get to the castling move (i.e. when you get a cutoff).
There are some similar cases (king moved or not) where the history matters, and so you need a separate function anyway to check if a move is legal (for example, if it comes out of the hash).
So I do it in makemove.
There are some similar cases (king moved or not) where the history matters, and so you need a separate function anyway to check if a move is legal (for example, if it comes out of the hash).
So I do it in makemove.
-
- Posts: 2250
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: Castling legality check
Pseudo legal move generating programs usually delay the test until make move, which might be "never" if an other move fails high. Pure legal move generating programs, likely with an incremental updated attack table, can test the square(s) during generation time.sluijten wrote:For castling moves, checking if the in-between squares are empty can easily be done in the move generator, but what is the best strategy to check if these squares are attacked or not?
It this normally done in the move generator, or in makemove (like checking to see if a move leaves the king in check)?
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Castling legality check
Note that for queenside castling the square b1 (b8) must be empty but may be attacked.sluijten wrote:For castling moves, checking if the in-between squares are empty can easily be done in the move generator, but what is the best strategy to check if these squares are attacked or not?
It this normally done in the move generator, or in makemove (like checking to see if a move leaves the king in check)?
Regarding your question, most has already been said by Gian-Carlo and Gerd. I see castling legality check as just one special case of move legality check. The question "was the last move illegal?" can be answered by testing whether one of these conditions is true:
1) the last move left the king in check (classical),
2) the last move was a castling move and the king crossed a square attacked by the opponent.
This avoids overlapping of the king-left-in-check test with the castling legality test by testing only once whether the castling target square g1 (g8) resp. c1 (c8) is attacked (i.e., only within the king-left-in-check test).
Don't forget to test whether the king itself is (was) in check. However, if you have a separate check evasion generator, or if you maintain an "is-in-check" flag that is already defined when entering the move generator, you get this test for free at generation time.
Sven
-
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: Castling legality check
Doing the legality check when the move is made complicates things there, because now you need to check for every move you make whether it was a castling move and then whether it was legal or not. If the test is done in the move generator, the only test you need is whether the king is in check after the last move or not.
I do the test for castling in the move generator, so I only generate castling moves when they are actually legal. This sounds expensive because you're potentially doing that without ever trying the castling move on the board, wasting time. In practice I don't think this is an issue, because more often than not, castling is not possible at all, either because the in-between squares are occupied or because castling rights have been lost already, and you'd use lazy evaluation to find that out. If castling is possible, it's a good candidate for being a good move, so it gets sorted higher in the movelist. That helps to eliminate the potential problem as well.
In short, just do whatever you feel is the easiest way to do it. It's easy to change later if necessary and it's not going to be the deciding factor for your program's playing strength for a while.
I do the test for castling in the move generator, so I only generate castling moves when they are actually legal. This sounds expensive because you're potentially doing that without ever trying the castling move on the board, wasting time. In practice I don't think this is an issue, because more often than not, castling is not possible at all, either because the in-between squares are occupied or because castling rights have been lost already, and you'd use lazy evaluation to find that out. If castling is possible, it's a good candidate for being a good move, so it gets sorted higher in the movelist. That helps to eliminate the potential problem as well.
In short, just do whatever you feel is the easiest way to do it. It's easy to change later if necessary and it's not going to be the deciding factor for your program's playing strength for a while.
-
- Posts: 1243
- Joined: Sat Dec 13, 2008 7:00 pm
Re: Castling legality check
I'd be curious how you manage to handle castling in your makemove routine without having to make a a special case for it, which implies checking for it.Evert wrote:Doing the legality check when the move is made complicates things there, because now you need to check for every move you make whether it was a castling move and then whether it was legal or not. If the test is done in the move generator, the only test you need is whether the king is in check after the last move or not.
-
- Posts: 4185
- Joined: Tue Mar 14, 2006 11:34 am
- Location: Ethiopia
Re: Castling legality check
I did it in move generator for scorpio but moved it to is_legal(),its natural place, for nebiyu. Not much of a difference regarding performance. Crazy castling rules for chess960 and other large board sizes variants needed to be put at one place to handle them.
-
- Posts: 838
- Joined: Thu Jul 05, 2007 5:03 pm
- Location: British Columbia, Canada
Re: Castling legality check
You're probably going to have to check whether its a castling move anyway, as a castling move is sufficiently different from a "normal" move that some extra code is needed to implement it. It does mean that callers to makemove need to check if the move was rejected or not, but at least you only have to check the legality for moves that aren't cut off.Evert wrote:Doing the legality check when the move is made complicates things there, because now you need to check for every move you make whether it was a castling move and then whether it was legal or not. If the test is done in the move generator, the only test you need is whether the king is in check after the last move or not.
About special moves such as castling:
I suggest including 1 bit in your encoding of moves that is set for any "special" move (i.e. castling, promotion, capture+promotion, double pawn push, or enpassant capture) as opposed to a "normal" move (an ordinary noncapture or an ordinary capture). Then in makemove, you can test this bit first and only if it says the move is a "special" move do you need to test for each of those special cases. Most moves will be "normal" moves. If bits are at a premium (e.g. for storing a hash move), 13 bits is enough to describe any move in ordinary chess. For promotions, the "special" flag plus source square on 7th rank and the fact that there's a pawn on that square, tells you that its a promotion move. You can then use the dest square rank bits to represent promotion type, and the dest square file bits to represent the file as usual (to distinguish between promotion and capture+promotion moves). In a move list it might be worth having extra bits to store the moving piece type and captured piece type, if any, but you can still encode promotion moves the same way.
-
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: Castling legality check
Yeah, ok, maybe that wasn't the clearest.
In Jazz, I do (of course) have a line to move the rook in case of a castling move. However, I don't have code to check whether the castling move itself is legal or not (because the move generator only generates it when it is). That would be a seperate test after makemove anyway.
In Sjaak, I actually do not have any special code for making a castling move, because any move is a combination of a number of pickups and drops (2 and 2 in the case of castling). I picked that idea up from a discussion about how ChessV encodes moves.
EDIT: In Sjaak, I also only ever generate castling in the move generator. The reason there is that in general, castling rights can be quite messy and I don't want to duplicate the game rules if I don't have to, so I check in one place.
In Jazz, I do (of course) have a line to move the rook in case of a castling move. However, I don't have code to check whether the castling move itself is legal or not (because the move generator only generates it when it is). That would be a seperate test after makemove anyway.
In Sjaak, I actually do not have any special code for making a castling move, because any move is a combination of a number of pickups and drops (2 and 2 in the case of castling). I picked that idea up from a discussion about how ChessV encodes moves.
EDIT: In Sjaak, I also only ever generate castling in the move generator. The reason there is that in general, castling rights can be quite messy and I don't want to duplicate the game rules if I don't have to, so I check in one place.