Keep track of attacked squares near King
authorH.G.Muller <hgm@hgm-xboard.(none)>
Sat, 14 Jan 2017 11:48:19 +0000 (12:48 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Sat, 14 Jan 2017 11:48:19 +0000 (12:48 +0100)
The move generator now marks all attacked squares on an auxiliary board.
At the end it counts the number of such squares next to the enemy King,
empty squares and captures separately. It also counts the number of
unattacked empty squares next to the King.

dropper.c

index 85c44c3..219c868 100644 (file)
--- a/dropper.c
+++ b/dropper.c
@@ -691,6 +691,7 @@ typedef struct {   // move stack sectioning
     int castlings; // end of list of board moves without castlings
     int epSqr;
     int checker;
+    int safety, hole, escape;
 } MoveStack;
 
 HashEntry *hashTable;
@@ -740,20 +741,24 @@ void
 Dump (char *s)
 {int i; printf("%s\n",s); for(i=0; i<ply; i++) printf(" {%x} %s", deprec[i], MoveToText(path[i])); PrintDBoard("board", board, "   ", 11); exit(1); }
 
+#define attacks (rawAttacks + 23)
+static int attackKey, rawAttacks[13*22];
+
 int
 MoveGen (int stm, MoveStack *m, int castle)
 {   // generate all board moves, return 1 if King capture found amongst those
-    int r, f;
+    int r, f, c = ++attackKey;
     m->firstMove = m->nonCapts =  m->late = moveSP; m->stage = 0;
     for(r=0; r<boardEnd; r+=22) for(f=0; f<nrFiles; f++) {
        int from = r + f, piece = board[from];
        if(piece & stm) {
            int step, dir = 2*firstDir[piece-WHITE]; // steps data comes in pairs
            while((step = steps[dir++])){ // next direction
-               int range = steps[dir++], to = from, victim, inZone = zoneTab[from];
+               int range = steps[dir++], to = from, victim, inZone = zoneTab[from], d = c - (range == 11);
                do {
                    int move, promote, slot;
                    victim = board[to += step];
+                   attacks[to] = d; // keep track of attacked squares (even with own piece)
                    if(victim & stm) break; // captures own piece
                    if(range & 2) { // divergent move: must be FIDE Pawn
                        if(to == m->epSqr) { // reaches e.p. square: must be through diagonal move, and e.p. square is always empty
@@ -808,6 +813,14 @@ MoveGen (int stm, MoveStack *m, int castle)
        if(board[r-1] == 0 && board[r-2] == 0 && board[r-3] == 0) f += 2, moveStack[moveSP++] = r << 8 | 8*22+21 + 22*(stm == BLACK);
     }
 
+    r = location[stm+31^COLOR]; // enemy King
+#   define HOLE(X) (attacks[X] == c)*!board[X]
+    m->hole = HOLE(r+1) + HOLE(r-1) + HOLE(r+22) + HOLE(r+21) + HOLE(r+23) + HOLE(r-21) + HOLE(r-22) + HOLE(r-23);
+#   define SAFE(X) (attacks[X] == c)*!(board[X] & stm)
+    m->safety = SAFE(r+1) + SAFE(r-1) + SAFE(r+22) + SAFE(r+21) + SAFE(r+23) + SAFE(r-21) + SAFE(r-22) + SAFE(r-23);
+#   define ESC(X) (board[X] & stm || attacks[X] == c)
+    m->escape = 8 - (ESC(r+1) + ESC(r-1) + ESC(r+22) + ESC(r+21) + ESC(r+23) + ESC(r-21) + ESC(r-22) + ESC(r-23));
+
     return 0;
 }