~ubuntu-branches/ubuntu/precise/gcompris/precise

« back to all changes in this revision

Viewing changes to src/chess_computer-activity/gnuchess/eval.c

  • Committer: Bazaar Package Importer
  • Author(s): Yann Dirson
  • Date: 2010-06-27 22:51:30 UTC
  • mfrom: (1.1.16 upstream) (5.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100627225130-mf7h4m5r8m7bd9fb
Tags: 9.3-1
* New upstream release.
* Drop GTK_DISABLE_DEPRECATED patch, useless for now.
* Provide RELEASE_NOTE_9.3.txt downloaded from sourceforge.
* New voice package for Asturian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GNU Chess 5.0 - eval.c - evaluation code
 
2
   Copyright (c) 1999-2002 Free Software Foundation, Inc.
 
3
 
 
4
   GNU Chess is based on the two research programs 
 
5
   Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.
 
6
 
 
7
   GNU Chess is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 2, or (at your option)
 
10
   any later version.
 
11
 
 
12
   GNU Chess is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with GNU Chess; see the file COPYING.  If not, write to
 
19
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
20
   Boston, MA 02111-1307, USA.
 
21
 
 
22
   Contact Info: 
 
23
     bug-gnu-chess@gnu.org
 
24
     cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
 
25
*/
 
26
 
 
27
/****************************************************************************
 
28
 *
 
29
 *
 
30
 *
 
31
 *****************************************************************************/
 
32
 
 
33
 
 
34
#include <config.h>
 
35
#include <stdio.h>
 
36
#include <string.h>
 
37
#include <stdlib.h>
 
38
#include "common.h"
 
39
#include "eval.h"
 
40
 
 
41
int LoneKing (int, int);
 
42
int ScoreKBNK (int, int);
 
43
int KPK (int);
 
44
int BishopTrapped (short);
 
45
int DoubleQR7 (short);
 
46
 
 
47
BitBoard passed[2];
 
48
BitBoard weaked[2];
 
49
 
 
50
static int PawnSq[2][64] = 
 
51
{
 
52
{  0,  0,  0,  0,  0,  0,  0,  0,
 
53
   5,  5,  5,-10,-10,  5,  5,  5,
 
54
  -2, -2, -2,  6,  6, -2, -2, -2,
 
55
   0,  0,  0, 25, 25,  0,  0,  0,
 
56
   2,  2, 12, 16, 16, 12,  2,  2,
 
57
   4,  8, 12, 16, 16, 12,  4,  4,
 
58
   4,  8, 12, 16, 16, 12,  4,  4,
 
59
   0,  0,  0,  0,  0,  0,  0,  0},
 
60
{  0,  0,  0,  0,  0,  0,  0,  0,
 
61
   4,  8, 12, 16, 16, 12,  4,  4,
 
62
   4,  8, 12, 16, 16, 12,  4,  4,
 
63
   2,  2, 12, 16, 16, 12,  2,  2,
 
64
   0,  0,  0, 25, 25,  0,  0,  0,
 
65
  -2, -2, -2,  6,  6, -2, -2, -2,
 
66
   5,  5,  5,-10,-10,  5,  5,  5,
 
67
   0,  0,  0,  0,  0,  0,  0,  0}
 
68
};
 
69
 
 
70
static const int Passed[2][8] =
 
71
{ { 0, 48, 48, 120, 144, 192, 240, 0}, {0, 240, 192, 144, 120, 48, 48, 0} };
 
72
/* Penalties for one or more isolated pawns on a given file */
 
73
static const int isolani_normal[8] = {
 
74
  -8, -10, -12, -14, -14, -12, -10, -8
 
75
};
 
76
/* Penalties if the file is half-open (i.e. no enemy pawns on it) */
 
77
static const int isolani_weaker[8] = {
 
78
  -22, -24, -26, -28, -28, -26, -24, -22
 
79
};
 
80
 
 
81
static const BitBoard d2e2[2] =
 
82
                 { ULL(0x0018000000000000), ULL(0x0000000000001800) };
 
83
static const BitBoard brank7[2]  = { ULL(0x000000000000FF00),
 
84
                                     ULL(0x00FF000000000000) };
 
85
static const BitBoard brank8[2]  = { ULL(0x00000000000000FF),
 
86
                                     ULL(0xFF00000000000000) };
 
87
static const BitBoard brank67[2] = { ULL(0x0000000000FFFF00),
 
88
                                     ULL(0x00FFFF0000000000) };
 
89
static const BitBoard brank58[2] = { ULL(0x00000000FFFFFFFF),
 
90
                                     ULL(0xFFFFFFFF00000000) };
 
91
 
 
92
int ScoreP (short side)
 
93
/***************************************************************************
 
94
 *
 
95
 *  Pawn evaluation is based on the following factors (which is being
 
96
 *  constantly updated!).
 
97
 *
 
98
 *  1.  Pawn square tables.
 
99
 *  2.  Passed pawns.
 
100
 *  3.  Backward pawns.
 
101
 *  4.  Pawn base under attack.
 
102
 *  5.  Doubled pawns 
 
103
 *  6.  Isolated pawns 
 
104
 *  7.  Connected passed pawns on 6/7th rank.
 
105
 *  8.  Unmoved & blocked d, e pawn
 
106
 *  9.  Passed pawn which cannot be caught.
 
107
 *  10. Pawn storms.
 
108
 *
 
109
 ***************************************************************************/
 
110
{
 
111
   int xside;
 
112
   int s, sq, i, i1;
 
113
   int n1, n2, backward;
 
114
   int nfile[8];
 
115
   int EnemyKing;
 
116
   BitBoard c, t, p, blocker, *e;
 
117
   PawnSlot *ptable;
 
118
 
 
119
   if (board.b[side][pawn] == NULLBITBOARD)
 
120
      return (0);
 
121
   xside = 1^side;
 
122
   EnemyKing = board.king[xside];
 
123
   p = board.b[xside][pawn];
 
124
   c = t = board.b[side][pawn];
 
125
   ptable = PawnTab[side] + (PawnHashKey & PHashMask);
 
126
   TotalPawnHashCnt++;
 
127
   if (ptable->phase == phase && ptable->pkey == KEY(PawnHashKey))
 
128
   {
 
129
      GoodPawnHashCnt++;
 
130
      s = ptable->score;
 
131
      passed[side] = ptable->passed;
 
132
      weaked[side] = ptable->weaked;
 
133
      goto phase2; 
 
134
   }
 
135
 
 
136
   s = 0;
 
137
   passed[side] = NULLBITBOARD;
 
138
   weaked[side] = NULLBITBOARD;
 
139
   memset (nfile, 0, sizeof (nfile));
 
140
   while (t)
 
141
   {
 
142
      sq = leadz (t);
 
143
      CLEARBIT (t, sq);
 
144
      s += PawnSq[side][sq]; 
 
145
 
 
146
      /*  Passed pawns  */
 
147
      if ((p & PassedPawnMask[side][sq]) == NULLBITBOARD)
 
148
      {
 
149
         if ((side == white && (FromToRay[sq][sq|56] & c) == 0) ||
 
150
             (side == black && (FromToRay[sq][sq&7] & c) == 0)) 
 
151
         {
 
152
            passed[side] |= BitPosArray[sq];
 
153
            s += (Passed[side][RANK(sq)] * phase) / 12;
 
154
         }
 
155
      }
 
156
 
 
157
      /*  Backward pawns */
 
158
      backward = false;
 
159
    /*   i = sq + (side == white ? 8 : -8); */
 
160
      if ( side == white ) {
 
161
         i = sq + 8;  }
 
162
      else {
 
163
         i= sq - 8; }
 
164
 
 
165
      if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(sq)] & c) &&
 
166
          cboard[i] != pawn)
 
167
      {
 
168
         n1 = nbits (c & MoveArray[ptype[xside]][i]);
 
169
         n2 = nbits (p & MoveArray[ptype[side]][i]);
 
170
         if (n1 < n2)
 
171
            backward = true;
 
172
      }
 
173
      if (!backward && (BitPosArray[sq] & brank7[xside]))
 
174
      {
 
175
         i1 = 1;
 
176
         i = i + (side == white ? 8 : -8);
 
177
         if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(i1)] & c))
 
178
         {
 
179
            n1 = nbits (c & MoveArray[ptype[xside]][i]);
 
180
            n2 = nbits (p & MoveArray[ptype[side]][i]);
 
181
            if (n1 < n2)
 
182
               backward = true;
 
183
         }
 
184
      }
 
185
      if (backward)
 
186
      {
 
187
         weaked[side] |= BitPosArray[sq];
 
188
         s += BACKWARDPAWN;
 
189
      }
 
190
 
 
191
      /* Pawn base under attack */
 
192
      if ((MoveArray[ptype[side]][sq] & p) && (MoveArray[ptype[side]][sq] & c))
 
193
         s += PAWNBASEATAK;
 
194
 
 
195
      /*  Increment file count for isolani & doubled pawn evaluation */
 
196
      nfile[ROW(sq)]++;
 
197
   }
 
198
 
 
199
   for (i = 0; i <= 7; i++)
 
200
   {
 
201
      /* Doubled pawns */
 
202
      if (nfile[i] > 1)
 
203
         s += DOUBLEDPAWN;
 
204
 
 
205
      /* Isolated pawns */
 
206
      if (nfile[i] && (!(c & IsolaniMask[i])))
 
207
      {
 
208
         /* Isolated on a half-open file */
 
209
         if (!(FileBit[i] & board.b[xside][pawn]))
 
210
           s += isolani_weaker[i] * nfile[i];
 
211
         else /* Normal isolated pawn */
 
212
           s += isolani_normal[i] * nfile[i];
 
213
         weaked[side] |= (c & FileBit[i]);
 
214
      }
 
215
   }
 
216
 
 
217
 
 
218
  if (computerplays == side) {
 
219
 
 
220
    /* Penalize having eight pawns */
 
221
    if (nbits(board.b[computerplays][pawn]) == 8)
 
222
        s += EIGHT_PAWNS;
 
223
 
 
224
    /* Detect stonewall formation in enemy */
 
225
    if (nbits(stonewall[xside] & board.b[xside][pawn]) == 3)
 
226
      s += STONEWALL;
 
227
 
 
228
    /* Locked pawns */
 
229
    n = 0;
 
230
    if (side == white)
 
231
      n = nbits((c >> 8) & board.b[xside][pawn] &
 
232
               boxes[1]);
 
233
    else
 
234
      n = nbits((c << 8) & board.b[xside][pawn] &
 
235
               boxes[1]);
 
236
    if (n > 1)
 
237
      s += n * LOCKEDPAWNS;
 
238
  }
 
239
 
 
240
 
 
241
   /* Save the score into the pawn hash table */ 
 
242
   ptable->pkey = KEY(PawnHashKey);
 
243
   ptable->passed = passed[side];
 
244
   ptable->weaked = weaked[side];
 
245
   ptable->score = s;
 
246
   ptable->phase = phase;
 
247
 
 
248
/***************************************************************************
 
249
 *  
 
250
 *  This section of the pawn code cannot be saved into the pawn hash as
 
251
 *  they depend on the position of other pieces.  So they have to be 
 
252
 *  calculated again.
 
253
 *
 
254
 ***************************************************************************/
 
255
phase2:
 
256
 
 
257
   /* Pawn on f6/c6 with Queen against castled king is very strong */
 
258
   c = board.b[side][pawn];
 
259
   sq = board.king[xside];
 
260
   if (side == white && board.b[side][queen] && 
 
261
        (BitPosArray[C6] | BitPosArray[F6]) & c)
 
262
   {
 
263
      if (c & BitPosArray[F6] && sq > H6 && distance[sq][G7]==1)
 
264
         s += PAWNNEARKING;
 
265
      if (c & BitPosArray[C6] && sq > H6 && distance[sq][B7]==1)
 
266
         s += PAWNNEARKING;
 
267
   }
 
268
   else if (side == black && board.b[side][queen] &&
 
269
        (BitPosArray[C3] | BitPosArray[F3]) & c)
 
270
   {
 
271
      if (c & BitPosArray[F3] && sq < A3 && distance[sq][G2]==1)
 
272
         s += PAWNNEARKING;
 
273
      if (c & BitPosArray[C3] && sq < A3 && distance[sq][B2]==1)
 
274
         s += PAWNNEARKING;
 
275
   }
 
276
 
 
277
   /* Connected passed pawns on 6th or 7th rank */
 
278
   t = passed[side] & brank67[side];
 
279
   if (t && (board.pmaterial[xside] == ValueR || 
 
280
        (board.pmaterial[xside] == ValueN &&
 
281
        pieces[xside] == board.b[xside][knight])))
 
282
   {
 
283
      n1 = ROW(board.king[xside]);
 
284
      n2 = RANK(board.king[xside]);
 
285
      for (i = 0; i <= 6; i++)
 
286
      {
 
287
         if (t & FileBit[i] && t & FileBit[i+1] && (n1 < i-1 || n1 > i+1 ||
 
288
                (side == white && n2 < 4) || (side == black && n2 > 3)))
 
289
            s += CONNECTEDPP;
 
290
      }
 
291
   }
 
292
 
 
293
   /* Pawn on d2,e2/d7,e7 is blocked  */
 
294
   blocker = board.friends[side] | board.friends[xside];
 
295
   if (side == white && (((c & d2e2[white]) >> 8) & blocker))
 
296
      s += BLOCKDEPAWN;
 
297
   if (side == black && (((c & d2e2[black]) << 8) & blocker))
 
298
      s += BLOCKDEPAWN;
 
299
 
 
300
   /* Enemy has no pieces & King is outside of passed pawn square */
 
301
   if (passed[side] && board.pmaterial[xside]==0)
 
302
   {
 
303
      e = board.b[xside];
 
304
      i1 = board.king[xside];
 
305
      p = passed[side];
 
306
      while (p)
 
307
      {
 
308
         sq = leadz (p);
 
309
         CLEARBIT (p, sq);
 
310
         if (board.side == side)
 
311
         {
 
312
            if (!(SquarePawnMask[side][sq] & board.b[xside][king]))
 
313
               s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;
 
314
         }
 
315
         else if (!(MoveArray[king][i1] & SquarePawnMask[side][sq]))
 
316
            s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;
 
317
      }
 
318
   }
 
319
 
 
320
  /* If both sides are castled on different sides, bonus for pawn storms */
 
321
  c = board.b[side][pawn];
 
322
  if (abs (ROW (board.king[side]) - ROW (board.king[xside])) >= 4 &&
 
323
        PHASE < 6)
 
324
  {
 
325
     n1 = ROW (board.king[xside]);
 
326
     p = (IsolaniMask[n1] | FileBit[n1]) & c;
 
327
     while (p)
 
328
     {
 
329
        sq = leadz (p);
 
330
        CLEARBIT (p, sq);
 
331
        s += 10 * (5 - distance[sq][board.king[xside]]);
 
332
     }
 
333
  }
 
334
 
 
335
   return (s);
 
336
}
 
337
 
 
338
static const int Outpost[2][64] =
 
339
{
 
340
  { 0, 0, 0, 0, 0, 0, 0, 0,
 
341
    0, 0, 0, 0, 0, 0, 0, 0,
 
342
    0, 0, 0, 0, 0, 0, 0, 0,
 
343
    0, 0, 1, 1, 1, 1, 0, 0,
 
344
    0, 1, 1, 1, 1, 1, 1, 0,
 
345
    0, 0, 1, 1, 1, 1, 0, 0,
 
346
    0, 0, 0, 1, 1, 0, 0, 0,
 
347
    0, 0, 0, 0, 0, 0, 0, 0 },
 
348
  { 0, 0, 0, 0, 0, 0, 0, 0,
 
349
    0, 0, 0, 1, 1, 0, 0, 0,
 
350
    0, 0, 1, 1, 1, 1, 0, 0,
 
351
    0, 1, 1, 1, 1, 1, 1, 0,
 
352
    0, 0, 1, 1, 1, 1, 0, 0,
 
353
    0, 0, 0, 0, 0, 0, 0, 0,
 
354
    0, 0, 0, 0, 0, 0, 0, 0,
 
355
    0, 0, 0, 0, 0, 0, 0, 0 }
 
356
};
 
357
 
 
358
 
 
359
static inline int CTL(short sq, short piece __attribute__ ((unused)), short side)
 
360
/***************************************************************************
 
361
 *
 
362
 *  Return a score corresponding to the number of squares in the bitboard
 
363
 *  target multiplied by a specified bonus for controlling each square.
 
364
 *
 
365
 *  Can be used for control of the center and attacks around the king.
 
366
 *
 
367
 ***************************************************************************/
 
368
{
 
369
  int s, n, EnemyKing, FriendlyKing;
 
370
  BitBoard controlled;
 
371
 
 
372
  s = 0;
 
373
 
 
374
  EnemyKing = board.king[1^side];
 
375
  FriendlyKing = board.king[side];
 
376
 
 
377
  controlled = AttackXFrom (sq, side);
 
378
 
 
379
  /* Center control */
 
380
  n = nbits (controlled & boxes[0]);
 
381
  s += 4*n;
 
382
 
 
383
  /* Attacks against enemy king */
 
384
  n = nbits (controlled & DistMap[EnemyKing][2]);
 
385
  s += n;
 
386
 
 
387
  /* Defenses for friendly king */
 
388
  n = nbits (controlled & DistMap[FriendlyKing][2]);
 
389
  s += n;
 
390
 
 
391
  /* Mobility */
 
392
  n = nbits(controlled);
 
393
  s += 4*n;
 
394
 
 
395
  return (s);
 
396
}
 
397
 
 
398
int ScoreN (short side)
 
399
/***************************************************************************
 
400
 *
 
401
 *  1.  central knight - distance from enemy king.
 
402
 *  2.  mobility/control/attack
 
403
 *  3.  outpost knight protected by pawn.
 
404
 *  4.  knight attacking weak pawns.
 
405
 *
 
406
 ***************************************************************************/
 
407
{
 
408
   int xside;
 
409
   int s, s1, sq;
 
410
   int EnemyKing;
 
411
   BitBoard c, t;
 
412
 
 
413
   if (board.b[side][knight] == NULLBITBOARD)
 
414
      return (0);
 
415
   xside = side^1;
 
416
   s = s1 = 0;
 
417
   c = board.b[side][knight];
 
418
   t = board.b[xside][pawn]; 
 
419
   EnemyKing = board.king[xside];
 
420
 
 
421
   if ( c & pinned )
 
422
   {
 
423
        s += PINNEDKNIGHT * nbits(c & pinned);
 
424
   }
 
425
 
 
426
   while (c)
 
427
   {
 
428
      sq = leadz (c);
 
429
      CLEARBIT (c, sq);
 
430
 
 
431
      /* Control */
 
432
      s1 = CTL(sq,knight,side);
 
433
  
 
434
      if ( (BitPosArray[sq] & rings[3]) != NULLBITBOARD)
 
435
        s1 += KNIGHTONRIM;
 
436
 
 
437
      if (Outpost[side][sq] && 
 
438
          !(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]) )
 
439
      {
 
440
         s1 += OUTPOSTKNIGHT;
 
441
 
 
442
         /* Knight defended by own pawn */
 
443
         if (MoveArray[ptype[xside]][sq] & board.b[side][pawn])
 
444
            s1 += OUTPOSTKNIGHT;
 
445
      }
 
446
    
 
447
      /* Attack on weak opponent pawns */
 
448
      if (MoveArray[knight][sq] & weaked[xside])
 
449
         s1 += ATAKWEAKPAWN;
 
450
 
 
451
      s += s1;
 
452
   }
 
453
 
 
454
   return (s);
 
455
}
 
456
 
 
457
 
 
458
int ScoreB (short side)
 
459
/****************************************************************************
 
460
 *
 
461
 *  1.  double bishops.
 
462
 *  2.  mobility/control/attack
 
463
 *  3.  outpost bishop
 
464
 *  4.  fianchetto bishop
 
465
 *  5.  Bishop pair
 
466
 *
 
467
 ****************************************************************************/
 
468
{
 
469
   int xside;
 
470
   int s, s1, n, sq, EnemyKing;
 
471
   BitBoard c, t;
 
472
 
 
473
   if (board.b[side][bishop] == NULLBITBOARD)
 
474
      return (0);
 
475
   s = s1 = 0;
 
476
   c = board.b[side][bishop];
 
477
   xside = side ^ 1;
 
478
   EnemyKing = board.king[xside];
 
479
   n = 0;
 
480
   t = board.b[xside][pawn];
 
481
 
 
482
   if ( c & pinned )
 
483
   {
 
484
        s += PINNEDBISHOP * nbits(c & pinned);
 
485
   }
 
486
 
 
487
   while (c)
 
488
   {
 
489
      sq = leadz (c);
 
490
      CLEARBIT (c, sq);
 
491
      n++;
 
492
 
 
493
      /* Control */
 
494
      s1 = CTL(sq,bishop,side);
 
495
 
 
496
      /*  Outpost bishop */
 
497
      if (Outpost[side][sq] && 
 
498
          !(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]))
 
499
      {
 
500
         s1 += OUTPOSTBISHOP;
 
501
 
 
502
         /* Bishop defended by own pawn */
 
503
         if (MoveArray[ptype[xside]][sq] & board.b[side][pawn])
 
504
            s1 += OUTPOSTBISHOP;
 
505
      }
 
506
 
 
507
      /*  Fianchetto bishop */
 
508
      if (side == white)
 
509
      {
 
510
         if (board.king[side] >= F1 && board.king[side] <= H1 && sq == G2)
 
511
            s1 += FIANCHETTO;
 
512
         if (board.king[side] >= A1 && board.king[side] <= C1 && sq == B2)
 
513
            s1 += FIANCHETTO;
 
514
      }
 
515
      else if (side == black)
 
516
      {
 
517
         if (board.king[side] >= F8 && board.king[side] <= H8 && sq == G7)
 
518
            s1 += FIANCHETTO;
 
519
         if (board.king[side] >= A8 && board.king[side] <= C8 && sq == B7)
 
520
            s1 += FIANCHETTO;
 
521
      }
 
522
 
 
523
      /* Attack on weak opponent pawns */
 
524
      if (BishopAttack(sq) & weaked[xside])
 
525
         s1 += ATAKWEAKPAWN;
 
526
 
 
527
      s += s1;
 
528
   }
 
529
 
 
530
   /* Doubled bishops */
 
531
   if (n > 1)            
 
532
      s += DOUBLEDBISHOPS;
 
533
 
 
534
   return (s);
 
535
 
 
536
}
 
537
 
 
538
 
 
539
int BishopTrapped (short side)
 
540
/****************************************************************************
 
541
 *
 
542
 *  Check for bishops trapped at A2/H2/A7/H7
 
543
 *
 
544
 ****************************************************************************/
 
545
{
 
546
   int s = 0;
 
547
 
 
548
   /* Don't waste time */
 
549
   if (board.b[side][bishop] == NULLBITBOARD)
 
550
     return (0); 
 
551
 
 
552
   if (side == white)
 
553
   {
 
554
      if ((board.b[white][bishop] & BitPosArray[A7]) &&
 
555
          (board.b[black][pawn] & BitPosArray[B6]) && SwapOff(MOVE(A7,B6)) < 0)
 
556
         s += BISHOPTRAPPED;
 
557
      if ((board.b[white][bishop] & BitPosArray[H7]) &&
 
558
          (board.b[black][pawn] & BitPosArray[G6]) && SwapOff(MOVE(H7,G6)) < 0)
 
559
         s += BISHOPTRAPPED;
 
560
   }
 
561
   else
 
562
   {
 
563
      if ((board.b[black][bishop] & BitPosArray[A2]) &&
 
564
          (board.b[white][pawn] & BitPosArray[B3]) && SwapOff(MOVE(A2,B3)) < 0)
 
565
         s += BISHOPTRAPPED;
 
566
      if ((board.b[black][bishop] & BitPosArray[H2]) &&
 
567
          (board.b[white][pawn] & BitPosArray[G3]) && SwapOff(MOVE(H2,G3)) < 0)
 
568
         s += BISHOPTRAPPED;
 
569
   }
 
570
 
 
571
   return (s);
 
572
}
 
573
 
 
574
int ScoreR (short side)
 
575
/****************************************************************************
 
576
 *
 
577
 *  1.  rook on 7th rank and Enemy king on 8th rank or pawns on 7th rank.
 
578
 *  2.  rook on open/half-open file.
 
579
 *  3.  rook in front/behind passed pawns (pawn >= 5th rank)
 
580
 *
 
581
 ****************************************************************************/
 
582
{
 
583
   int s, s1, sq, xside, fyle, EnemyKing;
 
584
   BitBoard c;
 
585
 
 
586
   if (board.b[side][rook] == NULLBITBOARD)
 
587
      return (0);
 
588
   s = s1 = 0;
 
589
   c = board.b[side][rook];
 
590
   xside = side ^ 1;
 
591
   EnemyKing = board.king[xside];
 
592
 
 
593
   if ( c & pinned )
 
594
   {
 
595
        s += PINNEDROOK * nbits(c & pinned);
 
596
   }
 
597
 
 
598
   while (c)
 
599
   {
 
600
      sq = leadz (c);
 
601
      CLEARBIT (c, sq);
 
602
 
 
603
      /* Control */
 
604
      s1 = CTL(sq,rook,side);
 
605
 
 
606
      fyle = ROW(sq);
 
607
      if (PHASE < 7)
 
608
      {
 
609
         if (!(board.b[side][pawn] & FileBit[fyle]))
 
610
         {
 
611
            if (fyle == 5 && ROW(board.king[xside])>=E_FILE)
 
612
              s1 += ROOKLIBERATED;
 
613
            s1 += ROOKHALFFILE;
 
614
            if (!(board.b[xside][pawn] & FileBit[fyle]))
 
615
               s1 += ROOKOPENFILE;
 
616
         }
 
617
      }
 
618
 
 
619
      if (phase > 6 && (FileBit[fyle] & passed[white] & brank58[white]))
 
620
      {
 
621
         if (nbits (Ray[sq][7] & passed[white]) == 1)
 
622
            s1 += ROOKBEHINDPP;
 
623
         else if (Ray[sq][4] & passed[white])
 
624
            s1 += ROOKINFRONTPP;
 
625
      }
 
626
      if (FileBit[fyle] & passed[black] & brank58[black])
 
627
      {
 
628
         if (nbits (Ray[sq][4] & passed[black]) == 1)
 
629
            s1 += ROOKBEHINDPP;
 
630
         else if (Ray[sq][7] & passed[black])
 
631
            s1 += ROOKINFRONTPP;
 
632
      }
 
633
 
 
634
      /* Attack on weak opponent pawns */
 
635
      if (RookAttack(sq) & weaked[xside])
 
636
         s1 += ATAKWEAKPAWN;
 
637
 
 
638
      /* Rook on 7th rank */
 
639
      if (RANK (sq) == rank7[side] && (RANK (EnemyKing) == rank8[side] ||
 
640
          board.b[xside][pawn] & RankBit[RANK(sq)]))
 
641
         s1 += ROOK7RANK;
 
642
 
 
643
      s += s1;
 
644
   }
 
645
 
 
646
   return (s);
 
647
}
 
648
 
 
649
int DoubleQR7 (short side)
 
650
/***************************************************************************
 
651
 *
 
652
 *  This code just check to see if there is a QQ or QR or RR combo on the
 
653
 *  7th rank.  This is very strong and given quite a big bonus.  This 
 
654
 *  routine is called by the lazy section.
 
655
 *
 
656
 ***************************************************************************/
 
657
{
 
658
   int xside;
 
659
 
 
660
   xside = 1^side;
 
661
   if (nbits ((board.b[side][queen]|board.b[side][rook]) & brank7[side]) > 1
 
662
      && ((board.b[xside][king] & brank8[side]) || 
 
663
          (board.b[xside][pawn] & brank7[side])))
 
664
 
 
665
      return (ROOKS7RANK);
 
666
   else
 
667
      return (0);
 
668
}
 
669
 
 
670
int ScoreQ (short side)
 
671
/***************************************************************************
 
672
 *
 
673
 *  1. queen centralization.
 
674
 *  2. king tropism.
 
675
 *  3. Bonus if opponent king is exposed.
 
676
 *
 
677
 ***************************************************************************/
 
678
{
 
679
   int xside;
 
680
   int s, s1, sq, EnemyKing;
 
681
   BitBoard c;
 
682
   
 
683
   s = s1 = 0;
 
684
 
 
685
   /* Try to keep our queen on the board for attacking purposes. */
 
686
   if (board.b[side][queen] == NULLBITBOARD) {
 
687
       if (side == computer) {
 
688
         s += QUEEN_NOT_PRESENT;
 
689
       }
 
690
       return(s);
 
691
    }                                                                           
 
692
 
 
693
   xside = 1 ^ side;
 
694
   c = board.b[side][queen];
 
695
   EnemyKing = board.king[xside];
 
696
 
 
697
   if ( c & pinned )
 
698
   {
 
699
        s += PINNEDQUEEN * nbits(c & pinned);
 
700
   }
 
701
 
 
702
   while (c)
 
703
   {
 
704
      sq = leadz (c);
 
705
      CLEARBIT (c, sq);
 
706
 
 
707
      /* Control */
 
708
      s1 = CTL(sq,queen,side);
 
709
 
 
710
      if (distance[sq][EnemyKing] <= 2)
 
711
         s1 += QUEENNEARKING;
 
712
 
 
713
      /* Attack on weak opponent pawns */
 
714
      if (QueenAttack(sq) & weaked[xside])
 
715
         s1 += ATAKWEAKPAWN;
 
716
 
 
717
      s += s1;
 
718
   }
 
719
 
 
720
   return (s);
 
721
}
 
722
 
 
723
 
 
724
static const int KingSq[64] =
 
725
{
 
726
   24, 24, 24, 16, 16,  0, 32, 32,
 
727
   24, 20, 16, 12, 12, 16, 20, 24,
 
728
   16, 12,  8,  4,  4,  8, 12, 16,
 
729
   12,  8,  4,  0,  0,  4,  8, 12,
 
730
   12,  8,  4,  0,  0,  4,  8, 12,
 
731
   16, 12,  8,  4,  4,  8, 12, 16,
 
732
   24, 20, 16, 12, 12, 16, 20, 24,
 
733
   24, 24, 24, 16, 16,  0, 32, 32
 
734
};
 
735
 
 
736
static const int EndingKing[64] =
 
737
{
 
738
   0,  6, 12, 18, 18, 12,  6,  0,
 
739
   6, 12, 18, 24, 24, 18, 12,  6,
 
740
  12, 18, 24, 32, 32, 24, 18, 12,
 
741
  18, 24, 32, 48, 48, 32, 24, 18,
 
742
  18, 24, 32, 48, 48, 32, 24, 18,
 
743
  12, 18, 24, 32, 32, 24, 18, 12,
 
744
   6, 12, 18, 24, 24, 18, 12,  6,
 
745
   0,  6, 12, 18, 18, 12,  6,  0
 
746
};
 
747
 
 
748
static const int pawncover[9] = { -60, -30, 0, 5, 30, 30, 30, 30, 30 };
 
749
static const int factor[9] = { 7, 8, 8, 7, 6, 5, 4, 2, 0, };
 
750
 
 
751
int ScoreK (short side)
 
752
/***************************************************************************
 
753
 *
 
754
 *  1.  king in the corner. ?? SRW 2002-08-02 Unclear if implemented
 
755
 *  2.  pawns around king.
 
756
 *  3.  king on open file.
 
757
 *  4.  Uncastled king.
 
758
 *  5.  Open rook file via Ng5 or Bxh7 sac.
 
759
 *  6.  No major or minor piece in the king's quadrant.
 
760
 *
 
761
 ***************************************************************************/
 
762
{
 
763
   int xside;
 
764
   int s, sq, sq1, n, n1, n2, file, fsq, rank;
 
765
   BitBoard b, x;
 
766
 
 
767
   s = 0;
 
768
   xside = 1^side;
 
769
   sq = board.king[side];
 
770
   file = ROW (sq);
 
771
   rank = RANK (sq);
 
772
   KingSafety[side] = 0;
 
773
   if (!ENDING)
 
774
   { 
 
775
 
 
776
      s += ((6 - phase) * KingSq[sq] + phase * EndingKing[sq]) / 6;
 
777
 
 
778
      /* After castling kingside, reward having all 3 pawns in front but not if
 
779
         there is a threatening pawn. This permits the freeing move F3/F6. */
 
780
         
 
781
      if (side == white)
 
782
        n = nbits (MoveArray[king][sq] & board.b[side][pawn] & RankBit[rank+1]);
 
783
      else
 
784
        n = nbits (MoveArray[king][sq] & board.b[side][pawn] & RankBit[rank-1]);
 
785
      s += pawncover[n];
 
786
 
 
787
      /* Penalize compromised wing pawn formations prior to castle. */
 
788
      if (!board.castled[side]) {
 
789
        n = -1;
 
790
        if (side == white) {
 
791
          /* King on original square and unmoved */
 
792
          if (sq == 4 && Mvboard[sq] == 0) {
 
793
            /* Kingside - rook on original square and unmoved. */
 
794
            if ( (board.b[side][rook] & BitPosArray[H1])!=NULLBITBOARD &&
 
795
                 Mvboard[H1] == 0)
 
796
                   n = nbits (MoveArray[king][G1] & 
 
797
                              board.b[side][pawn] & RankBit[rank+1]);
 
798
            /* Queenside */
 
799
            if ( (board.b[side][rook] & BitPosArray[A1])!=NULLBITBOARD &&
 
800
                 Mvboard[A1] == 0)
 
801
                   n = nbits (MoveArray[king][C1] & 
 
802
                              board.b[side][pawn] & RankBit[rank+1]);
 
803
          }
 
804
        } else {
 
805
          if (sq == 60 && Mvboard[sq] == 0) {
 
806
            /* Kingside */
 
807
            if ( (board.b[side][rook] & BitPosArray[H8])!=NULLBITBOARD &&
 
808
                 Mvboard[H8] == 0)
 
809
                   n = nbits (MoveArray[king][G8] & 
 
810
                              board.b[side][pawn] & RankBit[rank-1]);
 
811
            /* Queenside */
 
812
            if ( (board.b[side][rook] & BitPosArray[A8])!=NULLBITBOARD &&
 
813
                 Mvboard[A8] == 0)
 
814
                   n = nbits (MoveArray[king][C8] & 
 
815
                              board.b[side][pawn] & RankBit[rank-1]);
 
816
          }
 
817
        }
 
818
        
 
819
        /* Penalize breaking the wing pawn formations prior to castle */
 
820
        if (n != -1) s += pawncover[n];
 
821
      }
 
822
 
 
823
      if (side == computer && file >= F_FILE && 
 
824
                !(FileBit[G_FILE] & board.b[side][pawn]))
 
825
      {
 
826
         if (side == white && cboard[F2] == pawn)
 
827
            s += GOPEN;
 
828
         else if (side == black && cboard[F7] == pawn)
 
829
            s += GOPEN;
 
830
      }
 
831
 
 
832
      /* No friendly pawns on this king file */
 
833
      if (!(FileBit[file] & board.b[side][pawn]))
 
834
         s += KINGOPENFILE;
 
835
 
 
836
      /* No enemy pawns on this king file */
 
837
      if (!(FileBit[file] & board.b[xside][pawn]))
 
838
         s += KINGOPENFILE1;
 
839
 
 
840
      switch (file)
 
841
      {
 
842
         case A_FILE :
 
843
         case E_FILE :
 
844
         case F_FILE :
 
845
         case G_FILE : if (!(FileBit[file+1] & board.b[side][pawn]))
 
846
                          s += KINGOPENFILE;
 
847
                       if (!(FileBit[file+1] & board.b[xside][pawn]))
 
848
                          s += KINGOPENFILE1;
 
849
                       break;
 
850
         case H_FILE :
 
851
         case D_FILE :
 
852
         case C_FILE :
 
853
         case B_FILE : if (!(FileBit[file-1] & board.b[side][pawn]))
 
854
                          s += KINGOPENFILE;
 
855
                       if (!(FileBit[file-1] & board.b[xside][pawn]))
 
856
                          s += KINGOPENFILE1;
 
857
                       break;
 
858
         default :
 
859
                       break;
 
860
      }
 
861
 
 
862
      if (board.castled[side]) {
 
863
        if (side == white) {
 
864
          if (file > E_FILE) {
 
865
            if (!(BitPosArray[F2] & board.b[side][pawn]) ||
 
866
                !(BitPosArray[G2] & board.b[side][pawn]) ||
 
867
                !(BitPosArray[H2] & board.b[side][pawn]) )
 
868
                s += RUPTURE;
 
869
          } else if (file < E_FILE) {
 
870
            if (!(BitPosArray[A2] & board.b[side][pawn]) ||
 
871
                !(BitPosArray[B2] & board.b[side][pawn]) ||
 
872
                !(BitPosArray[C2] & board.b[side][pawn]) )
 
873
                s += RUPTURE;
 
874
          }
 
875
        } else {
 
876
          if (file > E_FILE) {
 
877
            if (!(BitPosArray[F7] & board.b[side][pawn]) ||
 
878
                !(BitPosArray[G7] & board.b[side][pawn]) ||
 
879
                !(BitPosArray[H7] & board.b[side][pawn]) )
 
880
                s += RUPTURE;
 
881
          } else if (file < E_FILE) {
 
882
            if (!(BitPosArray[A7] & board.b[side][pawn]) ||
 
883
                !(BitPosArray[B7] & board.b[side][pawn]) ||
 
884
                !(BitPosArray[C7] & board.b[side][pawn]) )
 
885
                s += RUPTURE;
 
886
          }
 
887
        }
 
888
      }
 
889
      if (side == computer) {
 
890
 
 
891
        /* Stock piece sacrifice on h file */
 
892
 
 
893
        if (file >= E_FILE && board.b[xside][queen] && board.b[xside][rook] &&
 
894
            !((board.b[side][pawn]|board.b[xside][pawn]) & FileBit[7]))
 
895
         s += HOPEN;
 
896
        
 
897
        /* King trapping rook */
 
898
        if (side == white) {
 
899
          if (file > E_FILE) {
 
900
            if (board.b[side][rook]&mask_kr_trapped_w[H_FILE-file]) {
 
901
                s += ROOKTRAPPED;
 
902
            }
 
903
          } else if (file < D_FILE) {
 
904
            if (board.b[side][rook]&mask_qr_trapped_w[file]) {
 
905
                s += ROOKTRAPPED;
 
906
            }
 
907
          }
 
908
        } else {
 
909
          if (file > E_FILE) {
 
910
            if (board.b[side][rook]&mask_kr_trapped_b[H_FILE-file]) {
 
911
                s += ROOKTRAPPED;
 
912
            }
 
913
          } else if (file < D_FILE) {
 
914
            if (board.b[side][rook]&mask_qr_trapped_b[file]) {
 
915
                s += ROOKTRAPPED;
 
916
            }
 
917
          }
 
918
        }
 
919
      }
 
920
 
 
921
      /* Don't give fianchetto target for advanced pawns */
 
922
      if (file > E_FILE && ROW(board.king[xside]) < D_FILE) {
 
923
         if (side == white) fsq = G3; else fsq = G6;
 
924
         if ((BitPosArray[fsq] & board.b[side][pawn]) != NULLBITBOARD)
 
925
            if (((BitPosArray[F4]|BitPosArray[H4]|
 
926
                 BitPosArray[F5]|BitPosArray[H5])
 
927
              & board.b[xside][pawn]) != NULLBITBOARD) 
 
928
                s += FIANCHETTO_TARGET; 
 
929
      }
 
930
      if (file < E_FILE && ROW(board.king[xside]) > E_FILE) {
 
931
         if (side == white) fsq = B3; else fsq = B6;
 
932
         if ((BitPosArray[fsq] & board.b[side][pawn]) != NULLBITBOARD)
 
933
            if (((BitPosArray[A4]|BitPosArray[C4]|
 
934
                 BitPosArray[A5]|BitPosArray[C5])
 
935
              & board.b[xside][pawn]) != NULLBITBOARD) 
 
936
                s += FIANCHETTO_TARGET; 
 
937
      }
 
938
 
 
939
      /* No major/minor piece in king's quadrant */
 
940
      /* First identify the quadrant */
 
941
      x = boardhalf[side] & boardside[file<=D_FILE];
 
942
      /* Now identify the number of non-pawn enemy in quadrant */
 
943
      n1 = nbits(x & (board.friends[xside]));
 
944
      if (n1 > 0) {
 
945
        /* Now identify the number of non-pawn friends in quadrant */
 
946
        n2 = nbits(x & (board.friends[side] & ~board.b[side][pawn] & 
 
947
                ~board.b[side][king]));
 
948
        if (n1 > n2)
 
949
          s += (n1 - n2) * KING_DEFENDER_DEFICIT;
 
950
      }
 
951
      
 
952
      KingSafety[side] = s;
 
953
      s = (s * factor[phase]) / 8;
 
954
   }
 
955
   else
 
956
   {
 
957
      s += EndingKing[sq];
 
958
      s += CTL(sq,king,side);
 
959
      b = (board.b[white][pawn] | board.b[black][pawn]);
 
960
      while (b)
 
961
      {
 
962
         sq1 = leadz (b);
 
963
         CLEARBIT (b, sq1);
 
964
         if (BitPosArray[sq1] & board.b[white][pawn])
 
965
            s -= distance[sq][sq1+8] * 10 - 5;
 
966
         else if (BitPosArray[sq1] & board.b[white][pawn])
 
967
            s -= distance[sq][sq1-8] * 10 - 5;
 
968
         else
 
969
            s -= distance[sq][sq1] - 5;
 
970
      }
 
971
 
 
972
      /* Attack on weak opponent pawns */
 
973
      if (MoveArray[king][sq] & weaked[xside])
 
974
         s += ATAKWEAKPAWN * 2;
 
975
 
 
976
   }
 
977
 
 
978
    if (phase >= 4) {
 
979
      /* Weak back rank */
 
980
      if (side == white) {
 
981
        if (sq < A2) 
 
982
          if (!(MoveArray[king][sq] & (~board.b[side][pawn] & RankBit[1]))) 
 
983
            s += KING_BACK_RANK_WEAK;
 
984
      } else {
 
985
        if (sq > H7) 
 
986
          if (!(MoveArray[king][sq] & (~board.b[side][pawn] & RankBit[6]))) 
 
987
            s += KING_BACK_RANK_WEAK;
 
988
      }
 
989
   }
 
990
 
 
991
   return (s);
 
992
}
 
993
 
 
994
 
 
995
int LoneKing (int side, int loser)
 
996
/**************************************************************************
 
997
 *
 
998
 *  One side has a lonely king and the other has no pawns, but enough
 
999
 *  mating material.  We give an additional bonus of 150 points for the 
 
1000
 *  winning side to attract the search to such positions.
 
1001
 *
 
1002
 **************************************************************************/
 
1003
{
 
1004
   int s, winer, sq1, sq2;
 
1005
 
 
1006
   winer = 1^loser;
 
1007
   if (board.material[winer] == ValueB+ValueN && 
 
1008
        nbits(board.b[winer][bishop]) == 1 &&
 
1009
        nbits(board.b[winer][knight]) == 1)
 
1010
      return (ScoreKBNK (side, loser));
 
1011
 
 
1012
   sq1 = board.king[winer];
 
1013
   sq2 = board.king[loser];
 
1014
   s = 150 - 6 * taxicab[sq1][sq2] - EndingKing[sq2];
 
1015
   if (side == loser)
 
1016
      s = -s;
 
1017
   s += MATERIAL;
 
1018
 
 
1019
   return (s);
 
1020
}
 
1021
 
 
1022
 
 
1023
int KPK (int side)
 
1024
/**************************************************************************
 
1025
 *
 
1026
 *  A KPK endgame evaluator.  Side is the one on the move.
 
1027
 *  This is not a perfect evaluator, it merely identifies SOME positions
 
1028
 *  as wins or draw.  Some WON positions could be seen as draws; the search
 
1029
 *  will be able to use the knowledge here to identify more positions.
 
1030
 *
 
1031
 **************************************************************************/
 
1032
{
 
1033
   int winer, loser, sq, sqw, sql;
 
1034
   int s;
 
1035
 
 
1036
   winer = (board.b[white][pawn] ? white : black);
 
1037
   loser = 1 ^ winer;
 
1038
   sq  = leadz (board.b[winer][pawn]);
 
1039
   sqw = board.king[winer];
 
1040
   sql = board.king[loser];
 
1041
   s = ValueP + (ValueQ * Passed[winer][RANK(sq)] / PFACTOR) + 
 
1042
         4 * (winer == white ? RANK(sqw) : 7-RANK(sqw));
 
1043
 
 
1044
/**************************************************************************
 
1045
 *
 
1046
 * Pawn is outside the square of the king 
 
1047
 *
 
1048
 **************************************************************************/
 
1049
   if (~SquarePawnMask[winer][sq] & board.b[loser][king])
 
1050
   {
 
1051
      if (!(MoveArray[king][sql] & SquarePawnMask[winer][sq]))
 
1052
         return (winer == side ? s : -s);
 
1053
      if (winer == side)
 
1054
         return (s);
 
1055
   }
 
1056
 
 
1057
/**************************************************************************
 
1058
 *
 
1059
 *  Friendly king is on same or adjacent file to the pawn, and the pawn is 
 
1060
 *  on a file other than a rook file and ...
 
1061
 *
 
1062
 **************************************************************************/
 
1063
   if (ROW(sq) != 0 && ROW(sq) != 7 &&
 
1064
        ((IsolaniMask[ROW(sq)] | FileBit[ROW(sq)]) & board.b[winer][king]))
 
1065
   {
 
1066
 
 
1067
/**************************************************************************
 
1068
 *
 
1069
 * a. friendly king is 2 ranks more advanced than the pawn 
 
1070
 * b. friendly king is 1 rank more advanced than the pawn 
 
1071
 *    i.  The friendly king is on the sixth rank.
 
1072
 *    ii. The enemy king does not have direct opposition by being 2 ranks
 
1073
 *        in front of the friendly king and on the same file.
 
1074
 * c. friendly king is same rank as pawn
 
1075
 *    i.  The enemy king is not 2-4 ranks more advanced that the pawn.
 
1076
 *    ii. The pawn is on the sixth rank and the enemy king does not have
 
1077
 *        direct opposition.
 
1078
 * d. pawn is on the 7th rank, friendly king is on sixth rank and
 
1079
 *    i.  The enemy king is not on the queening square.
 
1080
 *    ii. The enemy is on the queening square but both kings are in the same
 
1081
 *        file.
 
1082
 * 
 
1083
 **************************************************************************/
 
1084
      if (winer == white)
 
1085
      {
 
1086
         if (RANK(sqw) == RANK(sq) + 2)
 
1087
            return (winer == side ? s : -s);
 
1088
         if (RANK(sqw) == RANK(sq) + 1)
 
1089
         {
 
1090
            if (RANK(sqw) == 5)
 
1091
               return (winer == side ? s : -s);
 
1092
            if (sqw < A6) 
 
1093
            {
 
1094
               if (sqw+16 == sql && winer == side)
 
1095
                  return (0);
 
1096
               else
 
1097
                  return (winer == side ? s : -s);
 
1098
            }
 
1099
         }
 
1100
         if (RANK(sqw) == RANK(sq))
 
1101
         {
 
1102
            if ((RANK(sql) - RANK(sq) < 2 || RANK(sql) - RANK(sq) > 4) &&
 
1103
                 winer == side)
 
1104
               return (s);
 
1105
            if ((RANK(sql) - RANK(sq) < 1 || RANK(sql) - RANK(sq) > 5) &&
 
1106
                 loser == side)
 
1107
               return (-s);
 
1108
            if (RANK(sq) == 5 && sqw+16 != sql)
 
1109
               return (winer == side ? s : 0);
 
1110
         }
 
1111
         if (RANK(sq) == 6 && RANK(sqw) == 5)
 
1112
         {
 
1113
            if (sql != sq+8)
 
1114
               return (winer == side ? s : 0);
 
1115
            if (sql == sq+8 && sql == sqw+16)
 
1116
               return (winer == side ? s : 0);
 
1117
         }
 
1118
      } 
 
1119
      else
 
1120
      {
 
1121
         if (RANK(sqw) == RANK(sq) - 2)
 
1122
            return (winer == side ? s : -s);
 
1123
         if (RANK(sqw) == RANK(sq) - 1)
 
1124
         {
 
1125
            if (RANK(sqw) == 2)
 
1126
               return (winer == side ? s : -s);
 
1127
            if (sqw > H3)
 
1128
            {
 
1129
               if (sqw-16 == sql && winer == side)
 
1130
                  return (0);
 
1131
               else
 
1132
                  return (winer == side ? s : -s);
 
1133
            }   
 
1134
         }
 
1135
         if (RANK(sqw) == RANK(sq))
 
1136
         {
 
1137
            if ((RANK(sq) - RANK(sql) < 2 || RANK(sq) - RANK(sql) > 4) &&
 
1138
                 winer == side)
 
1139
               return (s);
 
1140
            if ((RANK(sq) - RANK(sql) < 1 || RANK(sq) - RANK(sql) > 5) &&
 
1141
                 loser == side)
 
1142
               return (-s);
 
1143
            if (RANK(sq) == 5 && sqw+16 != sql)
 
1144
               return (winer == side ? s : 0);
 
1145
         }
 
1146
         if (RANK(sq) == 1 && RANK(sqw) == 2)
 
1147
         {
 
1148
            if (sql != sq-8)
 
1149
               return (winer == side ? s : 0);
 
1150
            if (sql == sq-8 && sql == sqw-16)
 
1151
               return (winer == side ? s : 0);
 
1152
         }
 
1153
      } 
 
1154
   }  
 
1155
 
 
1156
   return (0);
 
1157
}
 
1158
 
 
1159
 
 
1160
int KBNK[64] = 
 
1161
{
 
1162
   0, 10, 20, 30, 40, 50, 60, 70,
 
1163
  10, 20, 30, 40, 50, 60, 70, 60,
 
1164
  20, 30, 40, 50, 60, 70, 60, 50,
 
1165
  30, 40, 50, 60, 70, 60, 50, 40,
 
1166
  40, 50, 60, 70, 60, 50, 40, 30,
 
1167
  50, 60, 70, 60, 50, 40, 30, 20,
 
1168
  60, 70, 60, 50, 40, 30, 20, 10,
 
1169
  70, 60, 50, 40, 30, 20, 10,  0
 
1170
};
 
1171
 
 
1172
int ScoreKBNK (int side, int loser)
 
1173
/****************************************************************************
 
1174
 *
 
1175
 *  My very own KBNK routine!
 
1176
 *
 
1177
 ****************************************************************************/
 
1178
{
 
1179
   int s, winer, sq1, sq2, sqB;
 
1180
 
 
1181
   winer = 1^loser;
 
1182
   sqB = board.king[loser];
 
1183
   if (board.b[winer][bishop] & WHITESQUARES)
 
1184
      sqB = RANK(sqB)*8 + 7 - ROW(sqB);
 
1185
   sq1 = board.king[winer];
 
1186
   sq2 = board.king[loser];
 
1187
   s = 300 - 6 * taxicab[sq1][sq2];
 
1188
   s -= KBNK[sqB];
 
1189
   s -= EndingKing[sq2];
 
1190
   s -= taxicab[leadz(board.b[winer][knight])][sq2];
 
1191
   s -= taxicab[leadz(board.b[winer][bishop])][sq2];
 
1192
 
 
1193
   /*  King in the central 4x4 region is good! */
 
1194
   if (board.b[winer][king] & ULL(0x00003C3C3C3C0000))
 
1195
      s += 20;
 
1196
   if (side == loser)
 
1197
      s = -s;
 
1198
   s += MATERIAL;
 
1199
 
 
1200
   return (s); 
 
1201
}
 
1202
 
 
1203
 
 
1204
static const BitBoard nn[2] = { ULL(0x4200000000000000), ULL(0x0000000000000042) };
 
1205
static const BitBoard bb[2] = { ULL(0x2400000000000000), ULL(0x0000000000000024) };
 
1206
 
 
1207
int ScoreDev (short side)
 
1208
/***************************************************************************
 
1209
 *
 
1210
 *  Calculate the development score for side (for opening only).
 
1211
 *  Penalize the following.
 
1212
 *  .  Uncastled and cannot castled
 
1213
 *  .  Undeveloped knights and bishops
 
1214
 *  .  Early queen move.
 
1215
 *
 
1216
 ***************************************************************************/
 
1217
{
 
1218
   int s;
 
1219
   int sq;
 
1220
   BitBoard c;
 
1221
 
 
1222
   /* Calculate whether we are developed */
 
1223
   c = (board.b[side][knight] & nn[side]) | (board.b[side][bishop] & bb[side]);
 
1224
   s = nbits(c) * -8;
 
1225
 
 
1226
   /* If we are castled or beyond the 20th move, no more ScoreDev */
 
1227
   if (board.castled[side] || GameCnt >= 38)
 
1228
      return (s);
 
1229
 
 
1230
   s += NOTCASTLED;
 
1231
 
 
1232
   /* If the king is moved, nail it, otherwise check rooks */
 
1233
   if (Mvboard[board.king[side]] > 0) 
 
1234
      s += KINGMOVED;
 
1235
 
 
1236
   /* Discourage rook moves */
 
1237
   c = board.b[side][rook];
 
1238
   while (c) {
 
1239
     sq = leadz(c);
 
1240
     CLEARBIT(c, sq);
 
1241
     if (Mvboard[sq] > 0)
 
1242
       s += ROOKMOVED;
 
1243
   }
 
1244
 
 
1245
   /* Penalize a queen that moves at all */
 
1246
   if (board.b[side][queen])
 
1247
   {
 
1248
      sq = leadz (board.b[side][queen]);
 
1249
      if (Mvboard[sq] > 0)
 
1250
         s += EARLYQUEENMOVE;
 
1251
         /* s += Mvboard[sq] * EARLYQUEENMOVE; */
 
1252
   }
 
1253
 
 
1254
   /* Discourage repeat minor piece moves */
 
1255
   c = board.b[side][knight] | board.b[side][bishop];
 
1256
   while (c) {
 
1257
     sq = leadz(c);
 
1258
     CLEARBIT(c, sq);
 
1259
     if (Mvboard[sq] > 1)
 
1260
        s += EARLYMINORREPEAT;
 
1261
        /* s += Mvboard[sq] * EARLYMINORREPEAT; */
 
1262
   }
 
1263
 
 
1264
   /* Discourage any wing pawn moves */
 
1265
/*   c = board.b[side][pawn] & (FileBit[0]|FileBit[1]|FileBit[6]|FileBit[7]); */
 
1266
   c = board.b[side][pawn] & ULL(0xc3c3c3c3c3c3c3c3);
 
1267
   while (c) {
 
1268
     sq = leadz(c);
 
1269
     CLEARBIT(c, sq);
 
1270
     if (Mvboard[sq] > 0) 
 
1271
        s += EARLYWINGPAWNMOVE;
 
1272
   }
 
1273
 
 
1274
   /* Discourage any repeat center pawn moves */
 
1275
/*   c = board.b[side][pawn] & (FileBit[2]|FileBit[3]|FileBit[4]|FileBit[5]); */
 
1276
   c = board.b[side][pawn] & ULL(0x3c3c3c3c3c3c3c3c);
 
1277
   while (c) {
 
1278
     sq = leadz(c);
 
1279
     CLEARBIT(c, sq);
 
1280
     if (Mvboard[sq] > 1) 
 
1281
        s += EARLYCENTERPREPEAT;
 
1282
   }
 
1283
 
 
1284
   return (s);
 
1285
}
 
1286
 
 
1287
 
 
1288
/*  Array of pointer to functions  */
 
1289
static int (*ScorePiece[7]) (short) =
 
1290
{ NULL, ScoreP, ScoreN, ScoreB, ScoreR, ScoreQ, ScoreK };
 
1291
 
 
1292
 
 
1293
int Evaluate (int alpha, int beta)
 
1294
/****************************************************************************
 
1295
 *
 
1296
 *  First check to see if this position can be specially dealt with.
 
1297
 *  E.g. if our bounds indicate that we are looking for a mate score,
 
1298
 *  then just return the material score.  Nothing else is important.
 
1299
 *  If its a KPK endgame, call our KPK routine.
 
1300
 *  If one side has a lone king & the winning side has no pawns then call
 
1301
 *  the LoneKing() mating driver routine.  Note that there is enough
 
1302
 *  mating material as we have already check for insufficient mating material
 
1303
 *  in the call to EvaluateDraw() in search()/quiesce().
 
1304
 *
 
1305
 ****************************************************************************/
 
1306
{
 
1307
   int side, xside;
 
1308
   int piece, s, s1, score;
 
1309
   int npiece[2];
 
1310
   BitBoard *b;
 
1311
 
 
1312
   side = board.side;
 
1313
   xside = 1 ^ side;
 
1314
 
 
1315
   /*  If we are looking for a MATE, just return the material */
 
1316
   if (alpha > MATE-255 || beta < -MATE+255)
 
1317
      return (MATERIAL); 
 
1318
 
 
1319
   /*  A KPK endgame. */
 
1320
   if (board.material[white]+board.material[black] == ValueP)
 
1321
      return (KPK (side));  
 
1322
 
 
1323
   /*  One side has a lone king and other side has no pawns */
 
1324
   if (board.material[xside] == 0 && board.b[side][pawn] == NULLBITBOARD)
 
1325
      return LoneKing (side, xside);
 
1326
   if (board.material[side] == 0 && board.b[xside][pawn] == NULLBITBOARD)
 
1327
      return LoneKing (side, side);
 
1328
 
 
1329
/****************************************************************************
 
1330
 *
 
1331
 *  Lets try a lazy evaluation.  In this stage, we should evaluate all those
 
1332
 *  features that gives big bonus/penalties.  E.g. squares around king is
 
1333
 *  attacked by enemy pieces, 2 rooks on 7th rank, runaway passed pawns etc.
 
1334
 *  This will be the direction, so things will continue to change in this
 
1335
 *  section.
 
1336
 *
 
1337
 ****************************************************************************/
 
1338
   EvalCall++;
 
1339
   phase = PHASE;
 
1340
   b = board.b[white];
 
1341
   pieces[white] = b[knight] | b[bishop] | b[rook] | b[queen];
 
1342
   npiece[white] = nbits (pieces[white]);
 
1343
   b = board.b[black];
 
1344
   pieces[black] = b[knight] | b[bishop] | b[rook] | b[queen];
 
1345
   npiece[black] = nbits (pieces[black]);
 
1346
   s1 = MATERIAL;
 
1347
 
 
1348
   if ((s1 + maxposnscore[side] < alpha || s1 - maxposnscore[xside] > beta) &&
 
1349
        phase <= 6)
 
1350
   {
 
1351
      score = s1;
 
1352
      goto next;
 
1353
   }
 
1354
   s = 0;
 
1355
   s += ScoreDev (side) - ScoreDev (xside);
 
1356
   s += ScoreP (side) - ScoreP (xside);
 
1357
   s += ScoreK (side) - ScoreK (xside);
 
1358
   s += BishopTrapped (side) - BishopTrapped (xside);
 
1359
   s += DoubleQR7 (side) - DoubleQR7 (xside);
 
1360
 
 
1361
   s1 = s + MATERIAL;
 
1362
 
 
1363
/**************************************************************************
 
1364
 *
 
1365
 *  See if we can have a lazy evaluation cut.  Otherwise its a slow eval.
 
1366
 * 
 
1367
 **************************************************************************/
 
1368
 
 
1369
   if (s1 + lazyscore[side] < alpha || s1 - lazyscore[side] > beta)
 
1370
   {
 
1371
      score = s1;
 
1372
   }
 
1373
   else
 
1374
   {
 
1375
      EvalCnt++;
 
1376
 
 
1377
        GenAtaks();
 
1378
        s1 = HUNGPENALTY * ( EvalHung(side) - EvalHung(xside) );
 
1379
        FindPins(&pinned);
 
1380
 
 
1381
      for (piece = knight; piece < king; piece++)
 
1382
      {
 
1383
         s1 += (*ScorePiece[piece]) (side) - (*ScorePiece[piece]) (xside);
 
1384
      }
 
1385
      lazyscore[side] = MAX (s1, lazyscore[side]);
 
1386
      maxposnscore[side] = MAX (maxposnscore[side], s + s1);
 
1387
      score = s + s1 + MATERIAL;
 
1388
   }
 
1389
 
 
1390
/***************************************************************************
 
1391
 *
 
1392
 *  Trade down bonus code.  When ahead, trade pieces & not pawns;
 
1393
 *
 
1394
 ***************************************************************************/
 
1395
next:
 
1396
   if (MATERIAL >= 200)
 
1397
   {
 
1398
      score += (RootPieces - nbits(pieces[white] | pieces[black])) * TRADEPIECE;
 
1399
      score -= (RootPawns - nbits(board.b[white][pawn] | board.b[black][pawn])) 
 
1400
                        * TRADEPAWNS;
 
1401
   }
 
1402
   else if (MATERIAL <= -200)
 
1403
   {
 
1404
      score -= (RootPieces - nbits(pieces[white] | pieces[black])) * TRADEPIECE;
 
1405
      score += (RootPawns - nbits(board.b[white][pawn] | board.b[black][pawn]))
 
1406
                         * TRADEPAWNS;
 
1407
   }
 
1408
      
 
1409
/***************************************************************************
 
1410
 *
 
1411
 *  Opposite color bishops is drawish.
 
1412
 *
 
1413
 ***************************************************************************/
 
1414
   if (ENDING && pieces[white] == board.b[white][bishop] && 
 
1415
                 pieces[black] == board.b[black][bishop] &&
 
1416
       ((pieces[white] & WHITESQUARES && pieces[black] & BLACKSQUARES) ||
 
1417
        (pieces[white] & BLACKSQUARES && pieces[black] & WHITESQUARES)))
 
1418
   {
 
1419
      score /= 2;
 
1420
   }
 
1421
    
 
1422
/***************************************************************************
 
1423
 *
 
1424
 *  When one side has no mating material, then his score can never be > 0.
 
1425
 *
 
1426
 ***************************************************************************/
 
1427
   if (score > 0 && !board.b[side][pawn] && (board.material[side] < ValueR
 
1428
        || pieces[side] == board.b[side][knight]))
 
1429
      score = 0;
 
1430
   if (score < 0 && !board.b[xside][pawn] && (board.material[xside] < ValueR
 
1431
        || pieces[xside] == board.b[xside][knight]))
 
1432
      score = 0;
 
1433
   
 
1434
   return (score);
 
1435
}
 
1436
 
 
1437
 
 
1438
short EvaluateDraw (void)
 
1439
/***************************************************************************
 
1440
 *
 
1441
 *  This routine is called by search() and quiesce() before anything else
 
1442
 *  is done.  Its purpose it to check if the current position is a draw.
 
1443
 *  0.  50-move draw.
 
1444
 *  1.  If there are any pawns, it is not.
 
1445
 *  2.  If both sides has anything less than a rook, draw.
 
1446
 *  3.  If both sides has <= 2 knights only, draw.
 
1447
 *  4.  If its a KBBK and bishops of same color, draw.
 
1448
 *
 
1449
 ***************************************************************************/
 
1450
{
 
1451
   BitBoard *w, *b;
 
1452
   int wm, bm, wn, bn;
 
1453
 
 
1454
   /* 
 
1455
    * Exception - if we are close to a pawn move, promotion 
 
1456
    * or capture it is possible a forced mate will follow.
 
1457
    * So we assume not drawn for 2 moves.
 
1458
    */
 
1459
 
 
1460
   if ( (GameCnt-Game50) < 5 )
 
1461
     return (false);
 
1462
 
 
1463
   /* 50 move rule */
 
1464
   if ( (GameCnt-Game50) > 100 )
 
1465
     return (true);
 
1466
 
 
1467
   w = board.b[white];
 
1468
   b = board.b[black];
 
1469
   if (w[pawn] != 0 || b[pawn] != 0)
 
1470
      return (false);
 
1471
 
 
1472
   wm = board.material[white];
 
1473
   bm = board.material[black];
 
1474
   wn = nbits (w[knight]);
 
1475
   bn = nbits (b[knight]);
 
1476
   if  ((wm<ValueR || (wm==2*ValueN && wn==2)) &&
 
1477
        (bm<ValueR || (bm==2*ValueN && bn==2)))
 
1478
      return (true); 
 
1479
 
 
1480
   if (wm < ValueR)
 
1481
   {
 
1482
      if (bm == 2*ValueB && 
 
1483
         ( nbits(board.b[black][bishop] & WHITESQUARES) == 2 ||
 
1484
           nbits(board.b[black][bishop] & BLACKSQUARES) == 2 ))
 
1485
      return (true);
 
1486
   }
 
1487
   if (bm < ValueR)
 
1488
   {
 
1489
      if (wm == 2*ValueB && 
 
1490
         ( nbits(board.b[white][bishop] & WHITESQUARES) == 2 ||
 
1491
           nbits(board.b[white][bishop] & BLACKSQUARES) == 2 ))
 
1492
      return (true);
 
1493
   }
 
1494
 
 
1495
   return (false);
 
1496
}