# Computer Chess Club Archives

## Messages

### Subject: Re: 0x88

Author: Bruce Moreland

Date: 02:03:00 01/12/99

Go up one level in this thread

```
On January 11, 1999 at 19:42:25, jonathan Baxter wrote:

>On January 11, 1999 at 17:44:02, Bruce Moreland wrote:

>>You can write the whole thing in a few hours and have it go fast, without giving
>>yourself a stroke.
>
>Is there anywhere I could find source code for this? or a more detailed
>discussion?

You make your board a 128 element array, with 0..7 being a1..h1, 8..15 being
unused, 16..23 being a2..h2, etc.

A simple and fragmentary implementation would be as follows:

int argdBishop[] = { 17, 15, -17, -15, 0 };

void ProcTab(int * piTab, int iFrom, int coThem)
{
for (; *piTab; piTab++) {
int iTo;

for (iTo = iFrom + *piTab; !(iTo & 0x88); iTo += *piTab)
if (argsq[iTo].co == coThem) {
GenCap(iFrom, iTo); // Capture.
break;
}
if (argsq[iTo].co != coEmpty)
break;
GenMove(iFrom, iTo); // Move to vacant square.
}
}

To generate moves for a bishop on "iFrom" you would do:

ProcTab(argdBishop, iFrom, coThem);

Other pieces are analogous of course, although pawns are exceptional, and
en-passant and castling are insane and will be where most of your bugs are.

You would also make two arrays, each with 256 elements.  I said something about
using 255 elements in a previous post, I was wrong, you really need a few less,
I believe, but I'll use 256 here in order to avoid looking anal.

The first is an array of bit masks.  You'll index it by the delta between two
squares, plus a constant (128), which exists because the delta can be negative.
Each element in the array represents the kinds of pieces that can conceivably go
between two squares that are related to each other as described by the delta.

For instance, if you want to understand what can get from a1 to c3, you'd take
34 (c3) and subtract 0 (a1), and get 34.  You'd add 128 to this in order to
avoid a negative array indexing situation if you are trying to go from c3 to a1
(-34), so you'd get 162 here.  At element 162 would be the value "bfBishop |
bfQueen", since you put that value there at boot.

The other array is indexed the same way and contains the step you need to
increment by in order to get safely from one square to the other.  For instance,
in the a1..c3 example, the step is 17, since you add 17 to a1 to get to b2, then
17 to b2 to get to c3.

If you don't use a 16 x 8 element board, the above will simply crash and burn.
You'll assume that a bishop can get from g1 to a3 by the path g1..h2..a3.  A 16
x 8 board simply can't have this problem.

So to figure out if a piece can get from one square to another you do something
like this:

BOOL CanReach(int iFrom, int iTo, int pcFrom, int coFrom)
{
int dStep;

if (!(argbfMask[iTo - iFrom + 128] & argbf[coFrom][pcFrom]))
return FALSE;  // Can't conceivably reach.
dStep = argdStep[iTo - iFrom + 128];
for (;;) {
iFrom += dStep;
if (iFrom == iTo)
if (argsq[iFrom].co != coEmpty)
return FALSE;  // Blocked.
}
}

This can be used as most of the guts of an in-check routine, or as a part of the
guts of a static-exchange evaluator.

This isn't real code, it almost certainly has syntax errors and other bugs which