fastest test if move is checking using bitboards & 8x8bo
Moderator: Ras
-
MahmoudUthman
- Posts: 237
- Joined: Sat Jan 17, 2015 11:54 pm
fastest test if move is checking using bitboards & 8x8bo
What is the fastest way to check if a move is a checking move if I use bit boards & an array of 64 squares indicating piece type on each ?
-
hgm
- Posts: 28483
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: fastest test if move is checking using bitboards & 8
There are two ways a move could deliver check: direct or discovered. If a discovered check is possible, there are usually many moves of the piece that deliver check. So it is most efficient to test that in bulk. Normally one would go through the slider section of the piece list, to test if any slider is aligned with the enemy King, (and usually it stops there, because it is't), and if it is, see if there only is a single piece in between (by a ray scan over the board, or by adding view distances), and if that piece belongs to the side to move. If it does, the intermediate piece can deliver a discovered check with all its move that move off the ray. You could either mark such move already during move generation, and test for the marker. Or you could remember the square the piece is on (setting it to an invalid square number if there is no dicovered check possible), and test the from-square of every move against that to see it it is a potential discovered check. (And then test the direction of the move against the direction of the move against the remembered direction of the check ray.) This assumes only a single piece will be able to deliver a discovered check.
For the direct checks one has to test move by move. First for alignment of the from-square with the enemy King. (And usually it stops there.) When there is, and the moved piece does move in the direction of the alignment, you scan the ray to see if it is empty (and if the piece has only a finite range, to see if the King was in its range).
Testing for alingment is usually done through a lookup table indexed by the board step, aligned[sqr1 - sqr2]. Each element could contain a number of bitflags for the different directions, to indicate whether alignment is through files, ranks, diagonals, hippogonals... This would be ANDed by a 'capture code' for the piece type, which indicates how the piece ca capture, and if the result is non-zero, you have alignment. Another table indexed by the board step could then give you the single board step needed to traverse the ray, starting from sqr2.
Of course all this works pretty crummy if you number the board squares just contiguously, rather than as a 16x8 (0x88) board. Because you would get many false aligment hits, for moves that cross the edges and count on the board wrapping like a cylider. And the ray squares would have to test for crossing the edges. So never use an 8x8 mailbox. If you nevertheless do, the best remedy would be to immediately convert your square numbers to 0x88 numbering before using them as table indexes (sqr0x88 = sqr64 + (sqr64 & 070); ).
For the direct checks one has to test move by move. First for alignment of the from-square with the enemy King. (And usually it stops there.) When there is, and the moved piece does move in the direction of the alignment, you scan the ray to see if it is empty (and if the piece has only a finite range, to see if the King was in its range).
Testing for alingment is usually done through a lookup table indexed by the board step, aligned[sqr1 - sqr2]. Each element could contain a number of bitflags for the different directions, to indicate whether alignment is through files, ranks, diagonals, hippogonals... This would be ANDed by a 'capture code' for the piece type, which indicates how the piece ca capture, and if the result is non-zero, you have alignment. Another table indexed by the board step could then give you the single board step needed to traverse the ray, starting from sqr2.
Of course all this works pretty crummy if you number the board squares just contiguously, rather than as a 16x8 (0x88) board. Because you would get many false aligment hits, for moves that cross the edges and count on the board wrapping like a cylider. And the ray squares would have to test for crossing the edges. So never use an 8x8 mailbox. If you nevertheless do, the best remedy would be to immediately convert your square numbers to 0x88 numbering before using them as table indexes (sqr0x88 = sqr64 + (sqr64 & 070); ).
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: fastest test if move is checking using bitboards & 8
1. Test if the piece delivers a direct check to the king from its new location.MahmoudUthman wrote:What is the fastest way to check if a move is a checking move if I use bit boards & an array of 64 squares indicating piece type on each ?
2. Test if the from-square is on a ray with the king. If so, test for the presence of a slider on the same ray. If there is one, test whether there are other pieces blocking its view of the king.
These checks can be done using appropriate bitmasks. You can do pre-tests using a superpiece (Amazon): if there is no alignment with a superpiece you can skip more detailed (and expensive) tests.
-
brtzsnr
- Posts: 433
- Joined: Fri Jan 16, 2015 4:02 pm
Re: fastest test if move is checking using bitboards & 8
Evert wrote:You can do this from both squares, king's square and landing square, for maximum performance.MahmoudUthman wrote: These checks can be done using appropriate bitmasks. You can do pre-tests using a superpiece (Amazon): if there is no alignment with a superpiece you can skip more detailed (and expensive) tests.
zurichess - http://www.zurichess.xyz
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: fastest test if move is checking using bitboards & 8
brtzsnr wrote:How does that work?Evert wrote:You can do this from both squares, king's square and landing square, for maximum performance.MahmoudUthman wrote: These checks can be done using appropriate bitmasks. You can do pre-tests using a superpiece (Amazon): if there is no alignment with a superpiece you can skip more detailed (and expensive) tests.
If the attack set of a superpiece at the king's square does not intersect the from/to bitmask, the move cannot be a checking move. There's no need to test both ways.
-
brtzsnr
- Posts: 433
- Joined: Fri Jan 16, 2015 4:02 pm
Re: fastest test if move is checking using bitboards & 8
Evert wrote:Blah. I misremembered where I used this trick. I used it for checking legality of a move, and I intersect Super[from]&Super[to] to find an approximate sliding path.brtzsnr wrote:How does that work?Evert wrote:You can do this from both squares, king's square and landing square, for maximum performance.MahmoudUthman wrote: These checks can be done using appropriate bitmasks. You can do pre-tests using a superpiece (Amazon): if there is no alignment with a superpiece you can skip more detailed (and expensive) tests.
If the attack set of a superpiece at the king's square does not intersect the from/to bitmask, the move cannot be a checking move. There's no need to test both ways.
https://bitbucket.org/brtzsnr/zurichess ... ion.go-224Code: Select all
// bbSuperAttack contains queen's mobility on an empty board. // Intersecting mobility from `from` and from `to` we get // the diagonal, rank or file on which the piece moved. If the // intersection is empty we are sure that no other piece was in the way. if bbSuperAttack[from]&bbSuperAttack[to]&all == BbEmpty { return true }
Otherwise, you are right: for checking a single test suffices.
zurichess - http://www.zurichess.xyz