# Computer Chess Club Archives

## Messages

### Subject: unique distance relationship

Author: Gerd Isenberg

Date: 11:33:52 08/15/02

```In IsiChess, as well in other chess programs, two (precomputed) two-dimensional
arrays are used, to get the distance and the taxi-distance between two squares:

int distance[64][64];
int taxidist[64][64];

eg. from square 0 (A1) upper left corner:

distance
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  2  2  3  4  5  6  7
3  3  3  3  4  5  6  7
4  4  4  4  4  5  6  7
5  5  5  5  5  5  6  7
6  6  6  6  6  6  6  7
7  7  7  7  7  7  7  7

taxidist
0  1  2  3  4  5  6  7
1  2  3  4  5  6  7  8
2  3  4  5  6  7  8  9
3  4  5  6  7  8  9 10
4  5  6  7  8  9 10 11
5  6  7  8  9 10 11 12
6  7  8  9 10 11 12 13
7  8  9 10 11 12 13 14

If the two squares are on same rank/file both distances are equal.
On the diagonals the taxis (in NY) have the double way to go.

If you want to determine whether there are special distance relationships
between two squares, eg. straight or diagonal adjacent, opposition, some far
oppositions or knight distance, but no matter from what direction, you may
combine both distances (if you don't want to use too many special purpose
arrays):

bool isOpposition(int sq1, int sq2){
return (distance[sq1][sq2] == 2) && (taxidist[sq1][sq2] == 2);}

bool isKnightDistance(int sq1, int sq2){
return (distance[sq1][sq2] == 2) && (taxidist[sq1][sq2] == 3);}

These distance relationships are faster to implement, if you use the
(precomputed) sum of distance and taxi-distance:

eg. combidist[0] = distance[0] + taxidist[0]
0  2  4  6  8 10 12 14
2  3  5  7  5 11 13 15
4  5  6  8 10 12 14 16
6  7  8  9 11 13 15 17
8  9 10 11 12 14 16 18
10 11 12 13 14 15 17 19
12 13 14 15 16 17 18 20
14 15 16 17 18 19 20 21

All combi-distances less than six determine unique relationships, so you can
safely do:

bool isOpposition(int sq1, int sq2) {
return combidist[sq1][sq2] == 4;}

bool isKnightDistance(int sq1, int sq2) {
return combidist[sq1][sq2] == 5;}

Next idea was to use some linear combination of distance and taxi-distance,
to make all distance relationships unique:

eg. combidist71[0] = 7*distance[0] + 1*taxidist[0]
0  8 16 24 32 40 48 56
8  9 17 25 33 41 49 57
16 17 18 26 34 42 50 58
24 25 26 27 35 43 51 59
32 33 34 35 36 44 52 60
40 41 42 43 44 45 53 61
48 49 50 51 52 53 54 62
56 57 58 59 60 61 62 63

As you see, all distance relationships are unique (with respect to
symmetrics)and straight combi71-distances are divisible without remainder by 8,
but the diagonal distances by 9, what is not so efficient to determine.

So the final step was to use a modified 15*distance + taxidist, to get
divisibility of 16 on ranks and files. The modification affects the diagonals,
where i reset bit 0-2 but set bit 3, to force a divisibility of 8.

UDRDist[0]
8  16  32  48  64  80  96 112
16  24  33  49  65  81  97 113
32  33  40  50  66  82  98 114
48  49  50  56  67  83  99 115
64  65  66  67  72  84 100 116
80  81  82  83  84  88 101 117
96  97  98  99 100 101 104 118
112 113 114 115 116 117 118 120

x08 x10 x20 x30 x40 x50 x60 x70
x10 x18 x21 x31 x41 x51 x61 x71
x20 x21 x28 x32 x42 x52 x62 x72
x30 x31 x32 x38 x43 x53 x63 x73
x40 x41 x42 x43 x48 x54 x64 x74
x50 x51 x52 x53 x54 x58 x65 x75
x60 x61 x62 x63 x64 x65 x68 x76
x70 x71 x72 x73 x74 x75 x76 x78

There is stil a unique distance relationship, but also some more usefull
information whether the two squares are on a common line or diagonal:

If the three LSBs are zero (divisible by 8 without remainder), both squares are
on a common line or diagonal. If the lowest Nibble is zero (divisible by 16
without remainder), both squares are on the same rank or file.

IMHO the UDRDist-Array allows efficient recognization of direction independend
distance relations between two squares, like same line or diagonal, adjacent,
opposition, knight-distance and so on.

Gerd

```