Code: Select all
--------
--------
--------
--------
---B----
--/-----
-*------
o-------
multiply by h column (0x0101010101010101)
o*------
||------
||------
||------
||-B----
||/-----
|*------
o-------
shift by 56
--------
--------
--------
--------
--------
--------
--------
o*------
keep LSB only
--------
--------
--------
--------
--------
--------
--------
-*------
multiply by h column
-|------
-|------
-|------
-|------
-|------
-|------
-|------
-*------
intersect (&) with original bishop path
-|------
-|------
-|------
-|------
-|-B----
-|------
-*------
o|------
here's the MSB = captured piece on bishop path:
--------
--------
--------
--------
--------
--------
-*------
--------
For other bishop directions, the same trick can be used adding a 256 entries array, to handle separately the empty squares and capture square. I've done this on Satana and it gives a little speed-up:
Code: Select all
for(uint64_t i=0; i<0xffULL; i++)
{
if (i == boEmpty)
{
VertMSBE[i] = VertEmptyE[i] = VertEmptyW[i] = boEmpty;
}else
{
uint64_t posE = LastBit(i);
uint64_t takenE = LastBit(i ^ posE);
VertMSBE[i] = posE * BOARD_H_COL;
VertEmptyE[i] = ((posE - (takenE == boEmpty ? 1 : takenE)) & ~takenE) * BOARD_H_COL;
uint64_t posW = FirstBit(i);
uint64_t takenW = FirstBit(i ^ posW);
VertEmptyW[i] = (((takenW == boEmpty ? 0x100ULL : takenW) - posW) & ~posW) *BOARD_H_COL;
}
}
Code: Select all
--------
--------
--------
--------
---B----
--------
------*-
--------
--------
--------
--------
--------
--------
--------
--------
---B--*-
----||--
----||--
----||--
----||--
----||--
----||--
----||--
----||--
With a little extra work, this could be done for two directions at a time.
For rook moves, you can multiply by a diagonal, instead of the h column.
This idea avoid using MSB function, that is expensive, without intrinsics.
