Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: (pseudo)code for legal-movegenerator

Author: Landon Rabern

Date: 19:43:22 04/13/03

Go up one level in this thread


On April 13, 2003 at 19:19:57, Keith Evans wrote:

>On April 13, 2003 at 18:38:03, Landon Rabern wrote:
>
>>On April 13, 2003 at 12:22:15, Martin Bauer wrote:
>>
>>>Hi all,
>>>
>>>I am looking for an easy to understand code how to generate only legal moves
>>>when king is in check. I think there must be many optimizations when king is in
>>>check...
>>>
>>>Language C, Pascal or Basic like or psedocode. I want to see the principles of
>>>generating legal moves.
>>>
>>>Bye
>>>
>>>Martin
>>
>>This is what I do currently in Betsy when in check to generate moves.
>>
>>First find all the squares the king can move to that are not occupied by your
>>own pieces.  This is quick with bitBoards, just:
>>
>>bitBoard escapeSquares=kingMoves[board->blackKing]&(~board->blackPieces);
>>
>>now see which of these squares are attacked by the enemy, store in bitBoard
>>attacked.
>>
>>Then the legal king moves are:
>>
>>toMap=escapeSquares&(~attacked);
>>
>>If there was more than one enemey checking the king, then these are the only
>>legal moves and we are done.
>>
>>Otherwise there is only one attacker,  we can try to capture it, or if it is a
>>sliding piece we can try to block the attack.
>>
>>First we need to see where the attacker is.  Looks like this for me:
>>
>>int attackerSQ=LSB(attacksW(board->blackKing));
>>
>>now we need all of our pieces that can attack this piece (except our king since
>>we tried this already above):
>>
>>fromMap=notKingAttacksB(attackerSQ);
>>
>>//add in en passant attacks if they exist
>>if(board->ep && board->ep+8==attackerSQ)
>>{
>>  if ( FILE(board->ep)>0 && board->square[board->ep+7]==pawnb )
>>  {
>>    fromMap|=mask[board->ep+7];
>>  }
>>  if ( FILE(board->ep)<7 && board->square[board->ep+9]==pawnb )
>>  {
>>    fromMap|=mask[board->ep+9];
>>  }
>>}
>>
>>now loop over these pieces making sure that moving them to capture the checking
>>piece does not expose another attack:
>>
>>//fromSquare is the square of the piece we are trying to use to capture
>>
>>increment=directionIncrement[fromSquare][board->blackKing];
>>
>>//are we on a file, rank or diagonal of the king?
>>//if we moved in line with the king, then could not have exposed check
>>//if there were pieces between us and king, we could not have exposed check
>>
>>good=1;
>>
>>if(increment && abs(increment)!=abs(directionIncrement[attackerSQ][fromSquare])
>>&& !(obstructed[fromSquare][board->blackKing]&allPieces))
>>{
>>  //so we moved off the line of the king we were on and there are no pieces
>> //between us and the king, was there an enemy piece on the line?
>>
>> //now just check if there was a sliding piece that can move in the direction of
>> //increment in the direction of increment attacking our piece that we aremoving
>> if( was attacker over there)
>>   good=0;
>>}
>>
>>if(good)
>>  addToMoveList;
>>
>>beware that there is an issue with en passant; my code comment:
>>//it is possible that removing the captured attacking pawn exposed an attack
>>//since our pawn does not sit on that square
>>
>>
>>//now we have added all possible legal ways to capture the attacker
>>//need to see if we can block, if the attacker was a knight
>>//or pawn, then done
>>if( board->square[attackerSQ]==pawnw || board->square[attackerSQ]==knightw )
>>  return;
>>
>>
>>so we have a slider, see if we can block the attack with a piece:
>>
>>//get possible block squares
>>toMap=obstructed[board->blackKing][attackerSQ];
>>
>>now loop over these squares and see what we can mvoe there:
>>
>>fromMap=notKingPawnAttacksB(toSquare);
>>
>>//need to add in pawn moves to this square, also an en passant capture can
>>//block a check since its destination is different than capture square
>>fromMap|=(mask[toSquare]<<8)&board->blackPawns;
>>fromMap|=(mask[toSquare]<<16)&board->blackPawns&r[6]&((~allPieces)<<8);
>>
>>//need to make sure this block did not expose another check
>>
>>increment=directionIncrement[fromSquare][board->blackKing];
>>//are we on a file, rank or diagonal of the king?
>>//if there were pieces between us and king, we could not have exposed check
>>
>>...basically same as before.
>>
>>That is it.  I bet it can be done faster, that is on my list of things to look
>>at.
>>
>>Regards,
>>
>>Landon
>
>I'm curious what motivated you to have special code for this case. The reason
>that I ask is that Hsu actually put special circuitry into the Deep Blue chess
>chips to do this. I thought that he would have just used his normal move
>generator circuitry and thrown out illegal moves. Is the increase in performance
>for this case that important?
>
>Thanks,
>Keith

I made this function recently. The main reason was that I am now generating all
legal moves to get out of check while in the quiescence search and with this it
turns out that these types are a good chunk of the nodes.
Also, if you don't generate all the moves at once, like captures first and then
the rest, or something; then when in check you won't know how many legal moves
you have in a position.  This makes it harder to do single-reply-to-check
extensions.

Regards,

Landon




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.