|
Main
Date: 19 Jan 2007 11:34:05
From: Loomis Philanthrope
Subject: efficient in_check routine
|
Hi all, I am trying to write an efficient routine to determine whether the king is in check. Any ideas you know of are welcome. I am using the 0x88 board representation. My current method is to loop over the opponents pieces and use the difference between the king square the the piece square as an index into an array that tells me if the piece could attack the king from that square. Then for sliding pieces I traverse the direction of attack to see if all the squares between are empty. Then I check the two squares where pawns could attack from to see if they're occupied by opponents pawns. Is there a more efficient way to do this? My understanding is that bitboards make this kind of thing faster. I don't have the time to implement a full bitboard representation, but would it be worth it to store a couple bitboards just for this purpose? For example, a bitboard of occupied squares might make checking whether sliding pieces are blocked faster. Thanks, Loomis
|
|
|
Date: 19 Jan 2007 13:45:41
From: Mr. Question
Subject: Re: efficient in_check routine
|
"Loomis Philanthrope" <[email protected] > wrote in message news:[email protected]... > I am using the 0x88 board representation. My current method is to loop > over the opponents pieces and use the difference between the king square > the the piece square as an index into an array that tells me if the piece > could attack the king from that square. Then for sliding pieces I traverse > the direction of attack to see if all the squares between are empty. Then > I check the two squares where pawns could attack from to see if they're > occupied by opponents pawns. That's not too bad of a way, although if you use piece lists, you can cut out some of the board scanning. > Is there a more efficient way to do this? My understanding is that > bitboards make this kind of thing faster. I don't have the time to Yes, this is one area where bitboards can be faster. Notice I said 'can be'... Bit boards can be faster in one area but slower in another. As a whole, they aren't necessarily better, just different. They have different strengths and different weaknesses. There are a lot of very clever advances in bitboards these days. Gerd and some of the others in the TalkChess & WinBoard forums have developed new ways to do attack detection and move generation and so on. Very clever stuff. The days of having to use the 'classic' method or even the 'rotated' methods are over. But it can still be a pain to work with bitboards. > implement a full bitboard representation, but would it be worth it to > store a couple bitboards just for this purpose? For example, a bitboard Probably not. That's just yet more information to update with every move. > of occupied squares might make checking whether sliding pieces are blocked > faster. Some people have done hybrid programs. But it can be tedious to mesh together the two well. If you are going to go bitboards, then it's usually better to just go all the way. Many still have a 64 element mailbox board just so they can easily get a piece type or something, but most prefer to go all the way. But doing bitboards really requires a change in thinking. Now, having said all of that, the reality is that you rarely need to do incheck detection. Only when you generate castling moves (or make them, if you'd rather do it that way), and when there aren't any legal moves, so you can tell the difference between checkmate & stalemate. Most of the time you don't need incheck(). (Note that the infamous perft tests heavily use it, but that's not representative of a real search. Perft behaves very differently and should only be used as a way to check your move logic to make sure things are working.) Most people just generate pseudo-legal moves and let the search figure it out if the move is ever actually made. ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==---- http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
|
| |
Date: 19 Jan 2007 15:31:48
From: Loomis Philanthrope
Subject: Re: efficient in_check routine
|
Mr. Question wrote: > "Loomis Philanthrope" <[email protected]> wrote in message > news:[email protected]... > Now, having said all of that, the reality is that you rarely need to do > incheck detection. > > Most of the time you don't need incheck(). (Note that the infamous perft > tests heavily use it, but that's not representative of a real search. Perft > behaves very differently and should only be used as a way to check your move > logic to make sure things are working.) > > Most people just generate pseudo-legal moves and let the search figure it > out if the move is ever actually made. My move generator doesn't check whether it generates legal moves. But my make_move function will return false for an illegal move (so that I can remove it from the list). I think this is necessary for me. I tried various things allowing illegal moves but making them evaluate as very poor, but nothing quite worked right. I don't like that there is the possibility of illegal moves, inevitably, my engine will try to make one ;-). Loomis
|
| | |
Date: 19 Jan 2007 22:47:02
From: Mr. Question
Subject: Re: efficient in_check routine
|
"Loomis Philanthrope" <[email protected] > wrote in message news:[email protected]... > My move generator doesn't check whether it generates legal moves. But my > make_move function will return false for an illegal move (so that I can Some people do the valid castling incheck stuff there, but I don't think many do. > remove it from the list). I think this is necessary for me. I tried > various things allowing illegal moves but making them evaluate as very > poor, but nothing quite worked right. I don't like that there is the > possibility of illegal moves, inevitably, my engine will try to make one > ;-). I can understand that feeling. I've written a few chess programs over the years and I often included a few extra checking things just to make sure my program wouldn't do something stupid. Basically though, all the search routine has to do is: 1) see if the king is being captured. If it is, then immediately return an 'invalid move' score to the previous level. This can be done either in MakeMove() or the search. Where ever convenient. 2) If the search has returned an 'illegal move' score, then you know that the move you just tried was illegal. 3) If the best score ends up being 'illegal move' (meaning there were no legal moves, else the score would be something else) then you know you are either in stalemate or checkmate. Then you can do InCheck(). There are a few other complications, of course, depending on whether you generate all the moves or just some of them, but the key is that capturing the king will result in an immediately returned absolute worst possible score. Still, there are lots of ways of doing a chess program. Whatever makes you happy is all that really counts. ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==---- http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
|
|
Date: 19 Jan 2007 16:40:50
From: Gian-Carlo Pascutto
Subject: Re: efficient in_check routine
|
Loomis Philanthrope wrote: > Hi all, > > I am trying to write an efficient routine to determine whether the king > is in check. Any ideas you know of are welcome. > > I am using the 0x88 board representation. My current method is to loop > over the opponents pieces and use the difference between the king square > the the piece square as an index into an array that tells me if the > piece could attack the king from that square. Then for sliding pieces I > traverse the direction of attack to see if all the squares between are > empty. Then I check the two squares where pawns could attack from to see > if they're occupied by opponents pawns. > > Is there a more efficient way to do this? Remember what the last move was. Determine whether that move could have put the king in check. No need to look at all pieces. -- GCP
|
| |
Date: 19 Jan 2007 13:32:02
From: Mr. Question
Subject: Re: efficient in_check routine
|
"Gian-Carlo Pascutto" <[email protected] > wrote in message news:[email protected]... > Loomis Philanthrope wrote: >> Hi all, >> >> I am trying to write an efficient routine to determine whether the king >> is in check. Any ideas you know of are welcome. >> >> I am using the 0x88 board representation. My current method is to loop >> over the opponents pieces and use the difference between the king square >> the the piece square as an index into an array that tells me if the >> piece could attack the king from that square. Then for sliding pieces I >> traverse the direction of attack to see if all the squares between are >> empty. Then I check the two squares where pawns could attack from to see >> if they're occupied by opponents pawns. >> >> Is there a more efficient way to do this? > > Remember what the last move was. Determine whether that move could have > put the king in check. No need to look at all pieces. Don't forget about special handling for enpassant & promotion moves. Most people remember the promotions but forget about enpassant, which changes three squares. You'll still need a full, general purpose method for castling and other times. Most 0x88 programs use piece lists, too. That can speed things up a bit. But you'll still need to do some grunt work at times. You'll still have to go through the possible squares and check. ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==---- http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
|
| | |
Date: 19 Jan 2007 15:26:24
From: Loomis Philanthrope
Subject: Re: efficient in_check routine
|
Mr. Question wrote: > "Gian-Carlo Pascutto" <[email protected]> wrote in message > news:[email protected]... > >>Loomis Philanthrope wrote: >> >>>Hi all, >>> >>>I am trying to write an efficient routine to determine whether the king >>>is in check. Any ideas you know of are welcome. >>> >>>I am using the 0x88 board representation. My current method is to loop >>>over the opponents pieces and use the difference between the king square >>>the the piece square as an index into an array that tells me if the >>>piece could attack the king from that square. Then for sliding pieces I >>>traverse the direction of attack to see if all the squares between are >>>empty. Then I check the two squares where pawns could attack from to see >>>if they're occupied by opponents pawns. >>> >>>Is there a more efficient way to do this? >> >>Remember what the last move was. Determine whether that move could have >>put the king in check. No need to look at all pieces. > > > Don't forget about special handling for enpassant & promotion moves. Most > people remember the promotions but forget about enpassant, which changes > three squares. > > You'll still need a full, general purpose method for castling and other > times. > > Most 0x88 programs use piece lists, too. That can speed things up a bit. > But you'll still need to do some grunt work at times. You'll still have to > go through the possible squares and check. I have a general purpose is_attacked() method so that I can check if any particular square is attacked by one side or the other. That is what I am currently using to determine move legality. Thanks for the enpassant reminder! I might have missed that one. In the technique I am planning, checking whether promotions are legal isn't different from any other move. Of course, checking whether they deliver check is. Yes, I use a piece list and the board array contains pointers to the piece addresses. That way I can loop over the piece list instead of the board to do things like generate moves.
|
| |
Date: 19 Jan 2007 14:16:54
From: Loomis Philanthrope
Subject: Re: efficient in_check routine
|
Gian-Carlo Pascutto wrote: > Loomis Philanthrope wrote: > >>Hi all, >> >>I am trying to write an efficient routine to determine whether the king >>is in check. Any ideas you know of are welcome. >> >>I am using the 0x88 board representation. My current method is to loop >>over the opponents pieces and use the difference between the king square >>the the piece square as an index into an array that tells me if the >>piece could attack the king from that square. Then for sliding pieces I >>traverse the direction of attack to see if all the squares between are >>empty. Then I check the two squares where pawns could attack from to see >>if they're occupied by opponents pawns. >> >>Is there a more efficient way to do this? > > > Remember what the last move was. Determine whether that move could have > put the king in check. No need to look at all pieces. > Ok, after reading your source, I have an idea of how to write a more efficient way to determine whether I have moved into check by moving a pinned piece. I will do it a bit different from you just to keep the code simpler (I think I'll sacrifice just a tiny bit of efficiency for that, but it will still be much better than my current approach). My current method of determining move legality was just to check is_attacked() on the king square after every move. If I understand your code, I still have to do this if I move the king, right? But I can be more clever if I have moved another piece. Thanks for your help, this has to be worth at least 3 or 4 ratings points ;-).
|
| |
Date: 19 Jan 2007 13:48:03
From: Loomis Philanthrope
Subject: Re: efficient in_check routine
|
Gian-Carlo Pascutto wrote: > Loomis Philanthrope wrote: > >>Hi all, >> >>I am trying to write an efficient routine to determine whether the king >>is in check. Any ideas you know of are welcome. >> >>I am using the 0x88 board representation. My current method is to loop >>over the opponents pieces and use the difference between the king square >>the the piece square as an index into an array that tells me if the >>piece could attack the king from that square. Then for sliding pieces I >>traverse the direction of attack to see if all the squares between are >>empty. Then I check the two squares where pawns could attack from to see >>if they're occupied by opponents pawns. >> >>Is there a more efficient way to do this? > > > Remember what the last move was. Determine whether that move could have > put the king in check. No need to look at all pieces. > I'm going to try to save you some trouble if I can :-). I did a google search and see that you have written an engine which is now open source. I am reading the source and I see how you would answer some of my questions from my other post. I'll write back if I still have more questions. Thanks for your help, it's much appreciated! Loomis
|
| |
Date: 19 Jan 2007 13:24:30
From: Loomis Philanthrope
Subject: Re: efficient in_check routine
|
Gian-Carlo Pascutto wrote: > Loomis Philanthrope wrote: > >>Hi all, >> >>I am trying to write an efficient routine to determine whether the king >>is in check. Any ideas you know of are welcome. >> >>I am using the 0x88 board representation. My current method is to loop >>over the opponents pieces and use the difference between the king square >>the the piece square as an index into an array that tells me if the >>piece could attack the king from that square. Then for sliding pieces I >>traverse the direction of attack to see if all the squares between are >>empty. Then I check the two squares where pawns could attack from to see >>if they're occupied by opponents pawns. >> >>Is there a more efficient way to do this? > > > Remember what the last move was. Determine whether that move could have > put the king in check. No need to look at all pieces. It sounds nice on the face of it. But you've left out how to determine whether the move could have put the king in check. If all I had to do was check whether the moving piece is now attacking the king, that would be simple, but I have to consider discovered checks. That means I have to determine if the moving piece was between the king and any of the sliding pieces. This doesn't seem any easier than checking all the pieces to begin with (maybe your idea avoids checking the knights and pawns). Most often though I'm using this to determine whether a potential move is legal. I want to make sure I'm not moving into check. Unless I want to keep track of whether or not pieces are pinned, I don't see how to use your idea. And determining for each piece whether it is pinned or not seems less efficient than just checking if the king is attacked. If I've missed something that makes your idea work, please let me know. Loomis
|
|