Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Rev 154 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 1
#include "chess.h"
108 pmbaty 2
#include "evaluate.h"
33 pmbaty 3
#include "data.h"
108 pmbaty 4
/* last modified 12/31/15 */
33 pmbaty 5
/*
6
 *******************************************************************************
7
 *                                                                             *
8
 *   Evaluate() is used to evaluate the chess board.  Broadly, it addresses    *
9
 *   four (4) distinct areas:  (1) material score which is simply a summing of *
10
 *   piece types multiplied by piece values;  (2) pawn scoring which considers *
11
 *   placement of pawns and also evaluates passed pawns, particularly in end-  *
12
 *   game situations;  (3) piece scoring which evaluates the placement of each *
13
 *   piece as well as things like piece mobility;  (4) king safety which       *
108 pmbaty 14
 *   considers the pawn shelter around the king and enemy pieces and how close *
15
 *   they are to assist in a king-side attack.                                 *
33 pmbaty 16
 *                                                                             *
17
 *******************************************************************************
18
 */
19
int Evaluate(TREE * RESTRICT tree, int ply, int wtm, int alpha, int beta) {
20
  PAWN_HASH_ENTRY *ptable;
21
  PXOR *pxtable;
108 pmbaty 22
  int score, side, can_win = 3, phase, lscore, cutoff;
23
  int full = 0;
24
  uint64_t *etable;
25
  uint64_t temp_hashkey;
33 pmbaty 26
 
27
/*
108 pmbaty 28
 *************************************************************
29
 *                                                           *
30
 *  First thing we do is if -DSKILL was passed in to the     *
31
 *  compiler, we burn some time to slow the search down,     *
32
 *  then we fall into the normal evaluation code.            *
33
 *                                                           *
34
 *************************************************************
33 pmbaty 35
 */
36
#if defined(SKILL)
37
  if (skill < 100) {
38
    int i, j;
108 pmbaty 39
    for (i = 0; i < burnc[skill / 10] && !abort_search; i++)
40
      for (j = 1; j < 10 && !abort_search; j++)
33 pmbaty 41
        burner[j - 1] = burner[j - 1] * burner[j];
108 pmbaty 42
    if (TimeCheck(tree, 1))
43
      abort_search = 1;
33 pmbaty 44
  }
45
#endif
46
/*
47
 ************************************************************
48
 *                                                          *
108 pmbaty 49
 *  Next we check to see if this position has been handled  *
50
 *  before.  If so, we can skip the work saved in the eval  *
51
 *  hash table and just return the score found there.  Note *
52
 *  that we only store FULL evaluations in the evaluation   *
53
 *  hash, if an early (lazy) exit is taken, nothing is      *
54
 *  stored.                                                 *
33 pmbaty 55
 *                                                          *
56
 ************************************************************
108 pmbaty 57
*/
58
  temp_hashkey = (wtm) ? HashKey : ~HashKey;
59
  etable = eval_hash_table + (temp_hashkey & eval_hash_mask);
60
  if (*etable >> 16 == temp_hashkey >> 16) {
61
    score = (*etable & 0xffff) - 32768;
62
    return (wtm) ? score : -score;
63
  }
33 pmbaty 64
/*
108 pmbaty 65
 *************************************************************
66
 *                                                           *
67
 *  First lazy cutoff attempt.  If the material score is way *
68
 *  below alpha or way above beta (way above means so far    *
69
 *  above it is very unlikely the positional score can bring *
70
 *  the total score back into the alpha / beta window) then  *
71
 *  we take what is known as a "lazy evaluation exit" and    *
72
 *  avoid the computational cost of a full evaluation in a   *
73
 *  position where one side is way ahead or behind.          *
74
 *                                                           *
75
 *************************************************************
33 pmbaty 76
 */
108 pmbaty 77
  cutoff = (TotalPieces(white, occupied) && TotalPieces(black, occupied))
78
      ? KNIGHT_VALUE : ROOK_VALUE;
79
  lscore = MaterialSTM(wtm);
80
  if (lscore + cutoff < alpha)
81
    return alpha;
82
  if (lscore - cutoff > beta)
83
    return beta;
33 pmbaty 84
/*
108 pmbaty 85
 *************************************************************
86
 *                                                           *
87
 *  Check for draws where one side seems to be ahead, but    *
88
 *  has no actual winning chances.  One simple example is a  *
89
 *  king, bishop and rook pawn, with the wrong colored       *
90
 *  bishop and the enemy king too close to the promotion     *
91
 *  square.                                                  *
92
 *                                                           *
93
 *  The variable "can_win" uses 2 bits.  If White can        *
94
 *  actually win in this position, bit 1 is set.  If Black   *
95
 *  can actually win in this position, bit 0 is set.  If     *
96
 *  both sides can win, both bits are set.  This is used     *
97
 *  later to drag the score closer to a draw score if the    *
98
 *  side with the better score can't actually win.           *
99
 *                                                           *
100
 *  Note that we only set these bits in minimal material     *
101
 *  positions (both sides have < 13 points of material       *
102
 *  total).  Otherwise we assume normal scoring should       *
103
 *  apply.                                                   *
104
 *                                                           *
105
 *************************************************************
33 pmbaty 106
 */
108 pmbaty 107
  tree->evaluations++;
108
  tree->score_mg = 0;
109
  tree->score_eg = 0;
110
  EvaluateMaterial(tree, wtm);
111
  if (TotalPieces(white, occupied) < 13 && TotalPieces(black, occupied) < 13)
112
    for (side = black; side <= white; side++)
113
      if (!EvaluateWinningChances(tree, side, wtm))
114
        can_win ^= (1 << side);
33 pmbaty 115
/*
108 pmbaty 116
 *************************************************************
117
 *                                                           *
118
 *  Determine if this position should be evaluated to force  *
119
 *  mate (neither side has pawns) or if it should be         *
120
 *  evaluated normally.                                      *
121
 *                                                           *
122
 *  Note the special case of no pawns, one side is ahead in  *
123
 *  total material, but the game is a hopeless draw.  KRN vs *
124
 *  KR is one example.  If EvaluateWinningChances()          *
125
 *  determines that the side with extra material can not     *
126
 *  win, the score is pulled closer to a draw although it    *
127
 *  can not collapse completely to the drawscore as it is    *
128
 *  possible to lose KRB vs KR if the KR side lets the king  *
129
 *  get trapped on the edge of the board.                    *
130
 *                                                           *
131
 *************************************************************
33 pmbaty 132
 */
133
  tree->all_pawns = Pawns(black) | Pawns(white);
134
  if (!tree->all_pawns) {
135
    if (TotalPieces(white, occupied) > 3 || TotalPieces(black, occupied) > 3) {
136
      if (Material > 0)
137
        EvaluateMate(tree, white);
138
      else if (Material < 0)
139
        EvaluateMate(tree, black);
108 pmbaty 140
      if (tree->score_eg > DrawScore(1) && !(can_win & 2))
141
        tree->score_eg = tree->score_eg / 16;
142
      if (tree->score_eg < DrawScore(1) && !(can_win & 1))
143
        tree->score_eg = tree->score_eg / 16;
33 pmbaty 144
#if defined(SKILL)
145
      if (skill < 100)
108 pmbaty 146
        tree->score_eg = (int) // Pierre-Marie Baty -- added type cast
147
            (skill * tree->score_eg / 100 + ((100 -
33 pmbaty 148
                skill) * PAWN_VALUE * (uint64_t) Random32() /
108 pmbaty 149
            0x100000000ull) / 100);
33 pmbaty 150
#endif
151
      return (wtm) ? tree->score_eg : -tree->score_eg;
152
    }
153
  }
154
/*
108 pmbaty 155
 *************************************************************
156
 *                                                           *
157
 *  Now evaluate pawns.  If the pawn hash signature has not  *
158
 *  changed from the last entry to Evaluate() then we        *
159
 *  already have everything we need in the pawn hash entry.  *
160
 *  In this case, we do not need to call EvaluatePawns() at  *
161
 *  all.  EvaluatePawns() does all of the analysis for       *
162
 *  information specifically regarding only pawns.  In many  *
163
 *  cases, it merely records the presence/absence of         *
164
 *  positional pawn features because those features also     *
165
 *  depends on pieces.                                       *
166
 *                                                           *
167
 *  Note that anything put into EvaluatePawns() can only     *
168
 *  consider the placement of pawns.  Kings or other pieces  *
169
 *  can not influence the score because those pieces are not *
170
 *  hashed into the pawn hash signature.  Violating this     *
171
 *  principle leads to lots of very difficult and            *
172
 *  challenging debugging problems.                          *
173
 *                                                           *
174
 *************************************************************
33 pmbaty 175
 */
176
  else {
177
    if (PawnHashKey == tree->pawn_score.key) {
178
      tree->score_mg += tree->pawn_score.score_mg;
179
      tree->score_eg += tree->pawn_score.score_eg;
180
    }
181
/*
108 pmbaty 182
 *************************************************************
183
 *                                                           *
184
 *  First check to see if this position has been handled     *
185
 *  before.  If so, we can skip the work saved in the pawn   *
186
 *  hash table.                                              *
187
 *                                                           *
188
 *************************************************************
33 pmbaty 189
 */
190
    else {
191
      ptable = pawn_hash_table + (PawnHashKey & pawn_hash_mask);
192
      pxtable = (PXOR *) & (tree->pawn_score);
193
      tree->pawn_score = *ptable;
108 pmbaty 194
      tree->pawn_score.key ^= pxtable->entry[1] ^ pxtable->entry[2];
33 pmbaty 195
      if (tree->pawn_score.key != PawnHashKey) {
196
        tree->pawn_score.key = PawnHashKey;
197
        tree->pawn_score.score_mg = 0;
198
        tree->pawn_score.score_eg = 0;
199
        for (side = black; side <= white; side++)
200
          EvaluatePawns(tree, side);
201
        ptable->key =
108 pmbaty 202
            pxtable->entry[0] ^ pxtable->entry[1] ^ pxtable->entry[2];
203
        memcpy((char *) ptable + 8, (char *) &(tree->pawn_score) + 8,
204
            sizeof(PAWN_HASH_ENTRY) - 8);
33 pmbaty 205
      }
206
      tree->score_mg += tree->pawn_score.score_mg;
207
      tree->score_eg += tree->pawn_score.score_eg;
208
    }
209
/*
108 pmbaty 210
 *************************************************************
211
 *                                                           *
212
 *  If there are any passed pawns, first call                *
213
 *  EvaluatePassedPawns() to evaluate them.  Then, if one    *
214
 *  side has a passed pawn and the other side has no pieces, *
215
 *  call EvaluatePassedPawnRaces() to see if the passed pawn *
216
 *  can be stopped from promoting.                           *
217
 *                                                           *
218
 *************************************************************
33 pmbaty 219
 */
220
    if (tree->pawn_score.passed[black] || tree->pawn_score.passed[white]) {
221
      for (side = black; side <= white; side++)
222
        if (tree->pawn_score.passed[side])
223
          EvaluatePassedPawns(tree, side, wtm);
224
      if ((TotalPieces(white, occupied) == 0 &&
225
              tree->pawn_score.passed[black])
226
          || (TotalPieces(black, occupied) == 0 &&
227
              tree->pawn_score.passed[white]))
228
        EvaluatePassedPawnRaces(tree, wtm);
229
    }
230
  }
231
/*
108 pmbaty 232
 *************************************************************
233
 *                                                           *
234
 *  Call EvaluateCastling() to evaluate castling potential.  *
235
 *   Note we  only do this when that side has not castled at *
236
 *  the root.                                                *
237
 *                                                           *
238
 *************************************************************
33 pmbaty 239
 */
240
  for (side = black; side <= white; side++)
108 pmbaty 241
    if (Castle(1, side) > 0)
242
      EvaluateCastling(tree, ply, side);
33 pmbaty 243
/*
108 pmbaty 244
 *************************************************************
245
 *                                                           *
246
 *  The "dangerous" flag simply indicates whether that side  *
247
 *  has enough material to whip up a mating attack if the    *
248
 *  other side is careless (Q + minor or better, or RR + two *
249
 *  minors or better).                                       *
250
 *                                                           *
251
 *************************************************************
33 pmbaty 252
 */
108 pmbaty 253
  tree->dangerous[white] = (Queens(white) && TotalPieces(white, occupied) > 9)
254
      || (TotalPieces(white, rook) > 1 && TotalPieces(white, occupied) > 15);
255
  tree->dangerous[black] = (Queens(black) && TotalPieces(black, occupied) > 9)
256
      || (TotalPieces(black, rook) > 1 && TotalPieces(black, occupied) > 15);
257
/*
258
 *************************************************************
259
 *                                                           *
260
 *  Second lazy evaluation test.  We have computed the large *
261
 *  positional scores (except for king safety).  If the      *
262
 *  score is too far outside the alpha/beta window, we skip  *
263
 *  the piece scoring which is the most expensive of all the *
264
 *  evaluation terms, and simply use what we have at this    *
265
 *  point.                                                   *
266
 *                                                           *
267
 *************************************************************
268
 */
33 pmbaty 269
  phase =
270
      Min(62, TotalPieces(white, occupied) + TotalPieces(black, occupied));
271
  score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62;
272
  lscore = (wtm) ? score : -score;
108 pmbaty 273
  int w_mat = (2 * TotalPieces(white, rook)) + TotalPieces(white,
274
      knight) + TotalPieces(white, bishop);
275
  int b_mat = (2 * TotalPieces(black, rook)) + TotalPieces(black,
276
      knight) + TotalPieces(black, bishop);
277
  cutoff = 72 + (w_mat + b_mat) * 8 + abs(w_mat - b_mat) * 16;
278
  if (tree->dangerous[white] || tree->dangerous[black])
279
    cutoff += 35;
280
/*
281
 *************************************************************
282
 *                                                           *
283
 *  Then evaluate pieces if the lazy eval test fails.        *
284
 *                                                           *
285
 *  Note:  We MUST evaluate kings last, since their scoring  *
286
 *  depends on the tropism scores computed by the other      *
287
 *  piece evaluators.  Do NOT try to collapse the following  *
288
 *  loops into one loop.  That will break things since it    *
289
 *  would violate the kings last rule.  More importantly     *
290
 *  there is no benefit as the loops below are unrolled by   *
291
 *  the compiler anyway.                                     *
292
 *                                                           *
293
 *************************************************************
294
 */
33 pmbaty 295
  if (lscore + cutoff > alpha && lscore - cutoff < beta) {
296
    tree->tropism[white] = 0;
297
    tree->tropism[black] = 0;
298
    for (side = black; side <= white; side++)
299
      EvaluateKnights(tree, side);
300
    for (side = black; side <= white; side++)
301
      EvaluateBishops(tree, side);
302
    for (side = black; side <= white; side++)
303
      EvaluateRooks(tree, side);
304
    for (side = black; side <= white; side++)
305
      EvaluateQueens(tree, side);
306
    for (side = black; side <= white; side++)
108 pmbaty 307
      EvaluateKing(tree, ply, side);
308
    full = 1;
33 pmbaty 309
  }
310
/*
108 pmbaty 311
 *************************************************************
312
 *                                                           *
313
 *  Caclulate the final score, which is interpolated between *
314
 *  the middlegame score and endgame score based on the      *
315
 *  material left on the board.                              *
316
 *                                                           *
317
 *  Adjust the score if one side can't win, but the score    *
318
 *  actually favors that side significantly.                 *
319
 *                                                           *
320
 *************************************************************
33 pmbaty 321
 */
322
  score = ((tree->score_mg * phase) + (tree->score_eg * (62 - phase))) / 62;
323
  score = EvaluateDraws(tree, ply, can_win, score);
324
#if defined(SKILL)
325
  if (skill < 100)
108 pmbaty 326
    score = (int) // Pierre-Marie Baty -- added type cast
327
        (skill * score / 100 + ((100 -
33 pmbaty 328
            skill) * PAWN_VALUE * (uint64_t) Random32() / 0x100000000ull) /
108 pmbaty 329
        100);
33 pmbaty 330
#endif
108 pmbaty 331
  if (full)
332
    *etable = (temp_hashkey & 0xffffffffffff0000) + score + 32768;
33 pmbaty 333
  return (wtm) ? score : -score;
334
}
335
 
108 pmbaty 336
/* last modified 10/19/15 */
33 pmbaty 337
/*
338
 *******************************************************************************
339
 *                                                                             *
340
 *  EvaluateBishops() is used to evaluate bishops.                             *
341
 *                                                                             *
342
 *******************************************************************************
343
 */
344
void EvaluateBishops(TREE * RESTRICT tree, int side) {
345
  uint64_t temp, moves;
108 pmbaty 346
  int square, special, i, mobility;
347
  int score_eg = 0, score_mg = 0, enemy = Flip(side), tpawns;
33 pmbaty 348
/*
349
 ************************************************************
350
 *                                                          *
351
 *  First, locate each bishop and add in its piece/square   *
108 pmbaty 352
 *  table score.                                            *
33 pmbaty 353
 *                                                          *
354
 ************************************************************
355
 */
356
  for (temp = Bishops(side); temp; temp &= temp - 1) {
357
    square = LSB(temp);
358
    score_mg += bval[mg][side][square];
359
    score_eg += bval[eg][side][square];
360
/*
361
 ************************************************************
362
 *                                                          *
363
 *  Evaluate for "outposts" which is a bishop that can't be *
364
 *  driven off by an enemy pawn, and which is supported by  *
365
 *  a friendly pawn.                                        *
366
 *                                                          *
367
 *  If the enemy has NO minor to take this bishop, then     *
368
 *  increase the bonus.                                     *
369
 *                                                          *
370
 ************************************************************
371
 */
108 pmbaty 372
    special = bishop_outpost[side][square];
373
    if (special) {
374
      if (!(mask_pattacks[enemy][square] & Pawns(enemy))) {
375
        if (pawn_attacks[enemy][square] & Pawns(side)) {
376
          special += special / 2;
377
          if (!Knights(enemy) && !(Color(square) & Bishops(enemy)))
378
            special += bishop_outpost[side][square];
33 pmbaty 379
        }
108 pmbaty 380
        score_eg += special;
381
        score_mg += special;
33 pmbaty 382
      }
108 pmbaty 383
    }
33 pmbaty 384
/*
385
 ************************************************************
386
 *                                                          *
108 pmbaty 387
 *  Next we count the number of friendly pawns on the same  *
388
 *  color squares as the bishop.  This is a bad thing since *
389
 *  it restricts the bishop's ability to move.  We only do  *
390
 *  this if there is only one bishop for this side.         *
33 pmbaty 391
 *                                                          *
392
 ************************************************************
393
 */
108 pmbaty 394
    if (TotalPieces(side, bishop) == 1) {
395
      if (dark_squares & SetMask(square))
396
        tpawns = PopCnt(dark_squares & Pawns(side));
397
      else
398
        tpawns = PopCnt(~dark_squares & Pawns(side));
399
      score_mg -= tpawns * bishop_pawns_on_color[mg];
400
      score_eg -= tpawns * bishop_pawns_on_color[eg];
33 pmbaty 401
    }
402
/*
403
 ************************************************************
404
 *                                                          *
108 pmbaty 405
 *  Mobility counts the number of squares the bishop        *
406
 *  attacks, excluding squares with friendly pieces, and    *
407
 *  weighs each square according to centralization.         *
33 pmbaty 408
 *                                                          *
409
 ************************************************************
410
 */
411
    mobility = BishopMobility(square, OccupiedSquares);
412
    if (mobility < 0 && (pawn_attacks[enemy][square] & Pawns(side))
413
        && (File(square) == FILEA || File(square) == FILEH))
414
      mobility -= 8;
415
    score_mg += mobility;
416
    score_eg += mobility;
417
/*
418
 ************************************************************
419
 *                                                          *
420
 *  Check for pawns on both wings, which makes a bishop     *
421
 *  even more valuable against an enemy knight              *
422
 *                                                          *
423
 ************************************************************
424
 */
425
    if (tree->all_pawns & mask_fgh && tree->all_pawns & mask_abc) {
108 pmbaty 426
      score_mg += bishop_wing_pawns[mg];
427
      score_eg += bishop_wing_pawns[eg];
33 pmbaty 428
    }
429
/*
430
 ************************************************************
431
 *                                                          *
432
 *  Adjust the tropism count for this piece.                *
433
 *                                                          *
434
 ************************************************************
435
 */
436
    if (tree->dangerous[side]) {
437
      moves = king_attacks[KingSQ(enemy)];
108 pmbaty 438
      i = ((bishop_attacks[square] & moves) &&
439
          ((BishopAttacks(square, OccupiedSquares & ~Queens(side))) & moves))
440
          ? 1 : Distance(square, KingSQ(enemy));
441
      tree->tropism[side] += king_tropism_b[i];
33 pmbaty 442
    }
443
  }
108 pmbaty 444
/*
445
 ************************************************************
446
 *                                                          *
447
 *  Add a bonus if this side has a pair of bishops, which   *
448
 *  can become very strong in open positions.               *
449
 *                                                          *
450
 ************************************************************
451
 */
452
  if (TotalPieces(side, bishop) > 1) {
453
    score_mg += bishop_pair[mg];
454
    score_eg += bishop_pair[eg];
455
  }
33 pmbaty 456
  tree->score_mg += sign[side] * score_mg;
457
  tree->score_eg += sign[side] * score_eg;
458
}
459
 
108 pmbaty 460
/* last modified 01/03/15 */
33 pmbaty 461
/*
462
 *******************************************************************************
463
 *                                                                             *
108 pmbaty 464
 *   EvaluateCastling() is called when "side" has not castled at the root.     *
465
 *   Its main purpose is to determine if it has either castled somewhere in    *
466
 *   the tree, or else has lost all (or some) castling rights, which reduces   *
467
 *   options significantly.                                                    *
33 pmbaty 468
 *                                                                             *
469
 *******************************************************************************
470
 */
108 pmbaty 471
void EvaluateCastling(TREE * RESTRICT tree, int ply, int side) {
472
  int enemy = Flip(side), oq, score_mg = 0;;
33 pmbaty 473
 
474
/*
475
 ************************************************************
476
 *                                                          *
108 pmbaty 477
 *  If the king castled during the search, we are done and  *
478
 *  we leave it to EvaluateKing() to figure out how safe it *
479
 *  is.  If it has not castled, we give a significant       *
480
 *  penalty if the king moves since that loses all castling *
481
 *  rights, otherwise we give a smaller penalty for moving  *
482
 *  a rook and giving up castling rights to that side of    *
483
 *  the board.  The penalty is always increased if the      *
484
 *  opponent has a queen since the position is much more    *
485
 *  dangerous.                                              *
33 pmbaty 486
 *                                                          *
487
 ************************************************************
488
 */
108 pmbaty 489
  oq = (Queens(enemy)) ? 3 : 1;
490
  if (Castle(ply, side) != Castle(1, side)) {
491
    if (Castle(ply, side) == 0)
492
      score_mg -= oq * development_losing_castle;
493
    else if (Castle(ply, side) > 0)
494
      score_mg -= (oq * development_losing_castle) / 2;
495
  } else
496
    score_mg -= oq * development_not_castled;
33 pmbaty 497
  tree->score_mg += sign[side] * score_mg;
498
}
499
 
108 pmbaty 500
/* last modified 01/03/15 */
33 pmbaty 501
/*
502
 *******************************************************************************
503
 *                                                                             *
504
 *   EvaluateDraws() is used to adjust the score based on whether the side     *
505
 *   that appears to be better according the computed score can actually win   *
506
 *   the game or not.  If the answer is "no" then the score is reduced         *
507
 *   significantly to reflect the lack of winning chances.                     *
508
 *                                                                             *
509
 *******************************************************************************
510
 */
511
int EvaluateDraws(TREE * RESTRICT tree, int ply, int can_win, int score) {
512
/*
513
 ************************************************************
514
 *                                                          *
515
 *  If the ending has only bishops of opposite colors, the  *
108 pmbaty 516
 *  score is pulled closer to a draw.                       *
33 pmbaty 517
 *                                                          *
518
 *  If this is a pure BOC ending, it is very drawish unless *
519
 *  one side has at least 4 pawns.  More pawns makes it     *
520
 *  harder for a bishop and king to stop them all from      *
521
 *  advancing.                                              *
522
 *                                                          *
108 pmbaty 523
 *  If the following are both true:                         *
524
 *                                                          *
525
 *    black and white have less than a queen left (pieces   *
526
 *    only).                                                *
527
 *                                                          *
528
 *    both have one bishop and they are opposite colored.   *
529
 *                                                          *
530
 *  then either                                             *
531
 *                                                          *
532
 *    (a) both have just one bishop, both have less than 4  *
533
 *    pawns or one side has only one more pawn than the     *
534
 *    other side then score is divided by 2 with draw score *
535
 *    added in; or                                          *
536
 *                                                          *
537
 *    (b) pieces are equal, then score is reduced by 25%    *
538
 *    with draw score added in.                             *
539
 *                                                          *
33 pmbaty 540
 ************************************************************
541
 */
542
  if (TotalPieces(white, occupied) <= 8 && TotalPieces(black, occupied) <= 8) {
543
    if (TotalPieces(white, bishop) == 1 && TotalPieces(black, bishop) == 1)
544
      if (square_color[LSB(Bishops(black))] !=
545
          square_color[LSB(Bishops(white))]) {
546
        if (TotalPieces(white, occupied) == 3 &&
547
            TotalPieces(black, occupied) == 3 &&
548
            ((TotalPieces(white, pawn) < 4 && TotalPieces(black, pawn) < 4)
549
                || Abs(TotalPieces(white, pawn) - TotalPieces(black,
550
                        pawn)) < 2))
551
          score = score / 2 + DrawScore(1);
552
        else if (TotalPieces(white, occupied) == TotalPieces(black, occupied))
553
          score = 3 * score / 4 + DrawScore(1);
554
      }
555
  }
108 pmbaty 556
/*
557
 ************************************************************
558
 *                                                          *
559
 *  Final score adjustment.  If the score says white is     *
560
 *  better, but can_win says white can not win, or if the   *
561
 *  score says black is better, but can_win says black can  *
562
 *  not win, then we divide the score by 16, and then add   *
563
 *  in the draw score.  If the can_win says neither side    *
564
 *  can win, we just set the score to draw score and exit.  *
565
 *                                                          *
566
 ************************************************************
567
 */
33 pmbaty 568
  if (can_win != 3) {
108 pmbaty 569
    if (can_win & 1) {
570
      if (score > DrawScore(1))
571
        score = score / 16 + DrawScore(1);
572
    } else if (can_win & 2) {
573
      if (score < DrawScore(1))
574
        score = score / 16 + DrawScore(1);
575
    } else
576
      score = DrawScore(1);
33 pmbaty 577
  }
578
/*
579
 ************************************************************
580
 *                                                          *
581
 *  If we are running into the 50-move rule, then start     *
582
 *  dragging the score toward draw.  This is the idea of a  *
583
 *  "weariness factor" as mentioned by Dave Slate many      *
584
 *  times.  This avoids slamming into a draw at move 50 and *
585
 *  having to move something quickly, rather than slowly    *
586
 *  discovering that the score is dropping and that pushing *
587
 *  a pawn or capturing something will cause it to go back  *
588
 *  to its correct value a bit more smoothly.               *
589
 *                                                          *
590
 ************************************************************
591
 */
592
  if (Reversible(ply) > 80) {
108 pmbaty 593
    int closeness = 101 - Reversible(ply);
33 pmbaty 594
 
108 pmbaty 595
    score = DrawScore(1) + score * closeness / 20;
33 pmbaty 596
  }
597
  return score;
598
}
599
 
108 pmbaty 600
/* last modified 01/03/15 */
33 pmbaty 601
/*
602
 *******************************************************************************
603
 *                                                                             *
604
 *   EvaluateHasOpposition() is used to determine if one king stands in        *
605
 *   "opposition" to the other.  If the kings are opposed on the same file or  *
606
 *   else are opposed on the same diagonal, then the side not-to-move has the  *
607
 *   opposition and the side-to-move must give way.                            *
608
 *                                                                             *
609
 *******************************************************************************
610
 */
611
int EvaluateHasOpposition(int on_move, int king, int enemy_king) {
612
  int file_distance, rank_distance;
613
 
614
  file_distance = FileDistance(king, enemy_king);
615
  rank_distance = RankDistance(king, enemy_king);
616
  if (rank_distance < 2)
617
    return 1;
618
  if (on_move) {
619
    if (rank_distance & 1)
620
      rank_distance--;
621
    if (file_distance & 1)
622
      file_distance--;
623
  }
624
  if (!(file_distance & 1) && !(rank_distance & 1))
625
    return 1;
626
  return 0;
627
}
628
 
108 pmbaty 629
/* last modified 01/03/15 */
33 pmbaty 630
/*
631
 *******************************************************************************
632
 *                                                                             *
108 pmbaty 633
 *   EvaluateKing() is used to evaluate a king.                                *
33 pmbaty 634
 *                                                                             *
635
 *******************************************************************************
636
 */
108 pmbaty 637
void EvaluateKing(TREE * RESTRICT tree, int ply, int side) {
33 pmbaty 638
  int score_eg = 0, score_mg = 0, defects;
639
  int ksq = KingSQ(side), enemy = Flip(side);
640
 
641
/*
642
 ************************************************************
643
 *                                                          *
644
 *  First, check for where the king should be if this is an *
108 pmbaty 645
 *  endgame.  The basic idea is to centralize unless the    *
646
 *  king is needed to deal with a passed enemy pawn.        *
33 pmbaty 647
 *                                                          *
648
 ************************************************************
649
 */
108 pmbaty 650
  score_eg += kval[side][ksq];
33 pmbaty 651
/*
652
 ************************************************************
653
 *                                                          *
654
 *  Do castle scoring, if the king has castled, the pawns   *
655
 *  in front are important.  If not castled yet, the pawns  *
656
 *  on the kingside should be preserved for this.           *
657
 *                                                          *
658
 ************************************************************
659
 */
660
  if (tree->dangerous[enemy]) {
661
    defects = 0;
662
    if (Castle(ply, side) <= 0) {
108 pmbaty 663
      if (File(ksq) > FILEE)
664
        defects = tree->pawn_score.defects_k[side];
665
      else if (File(ksq) < FILED)
666
        defects = tree->pawn_score.defects_q[side];
667
      else
668
        defects = tree->pawn_score.defects_m[side];
33 pmbaty 669
    } else {
670
      if (Castle(ply, side) == 3)
671
        defects =
672
            Min(Min(tree->pawn_score.defects_k[side],
108 pmbaty 673
                tree->pawn_score.defects_m[side]),
33 pmbaty 674
            tree->pawn_score.defects_q[side]);
675
      else if (Castle(ply, side) == 1)
676
        defects =
677
            Min(tree->pawn_score.defects_k[side],
108 pmbaty 678
            tree->pawn_score.defects_m[side]);
33 pmbaty 679
      else
680
        defects =
681
            Min(tree->pawn_score.defects_q[side],
108 pmbaty 682
            tree->pawn_score.defects_m[side]);
33 pmbaty 683
      if (defects < 3)
684
        defects = 3;
685
    }
686
/*
687
 ************************************************************
688
 *                                                          *
689
 *  Fold in the king tropism and king pawn shelter scores   *
690
 *  together.                                               *
691
 *                                                          *
692
 ************************************************************
693
 */
694
    if (tree->tropism[enemy] < 0)
695
      tree->tropism[enemy] = 0;
696
    else if (tree->tropism[enemy] > 15)
697
      tree->tropism[enemy] = 15;
698
    if (defects > 15)
699
      defects = 15;
700
    score_mg -= king_safety[defects][tree->tropism[enemy]];
701
  }
702
  tree->score_mg += sign[side] * score_mg;
703
  tree->score_eg += sign[side] * score_eg;
704
}
705
 
108 pmbaty 706
/* last modified 01/03/15 */
33 pmbaty 707
/*
708
 *******************************************************************************
709
 *                                                                             *
710
 *   EvaluateKingsFile computes defects for a file, based on whether the file  *
711
 *   is open or half-open.  If there are friendly pawns still on the file,     *
712
 *   they are penalized for advancing in front of the king.                    *
713
 *                                                                             *
714
 *******************************************************************************
715
 */
108 pmbaty 716
int EvaluateKingsFile(TREE * RESTRICT tree, int side, int first, int last) {
717
  int defects = 0, file, enemy = Flip(side);
33 pmbaty 718
 
108 pmbaty 719
  for (file = first; file <= last; file++)
33 pmbaty 720
    if (!(file_mask[file] & tree->all_pawns))
721
      defects += open_file[file];
722
    else {
723
      if (!(file_mask[file] & Pawns(enemy)))
724
        defects += half_open_file[file] / 2;
725
      else
726
        defects +=
108 pmbaty 727
            pawn_defects[side][Rank(MostAdvanced(enemy,
33 pmbaty 728
                    file_mask[file] & Pawns(enemy)))];
729
      if (!(file_mask[file] & Pawns(side)))
730
        defects += half_open_file[file];
731
      else if (!(Pawns(side) & SetMask(sqflip[side][A2] + file))) {
732
        defects++;
733
        if (!(Pawns(side) & SetMask(sqflip[side][A3] + file)))
734
          defects++;
735
      }
736
    }
737
  return defects;
738
}
739
 
108 pmbaty 740
/* last modified 10/19/15 */
33 pmbaty 741
/*
742
 *******************************************************************************
743
 *                                                                             *
744
 *   EvaluateKnights() is used to evaluate knights.                            *
745
 *                                                                             *
746
 *******************************************************************************
747
 */
748
void EvaluateKnights(TREE * RESTRICT tree, int side) {
749
  uint64_t temp;
108 pmbaty 750
  int square, special, i, score_eg = 0, score_mg = 0, enemy = Flip(side);
33 pmbaty 751
 
752
/*
753
 ************************************************************
754
 *                                                          *
755
 *  First fold in centralization score from the piece/      *
756
 *  square table "nval".                                    *
757
 *                                                          *
758
 ************************************************************
759
 */
760
  for (temp = Knights(side); temp; temp &= temp - 1) {
761
    square = LSB(temp);
762
    score_mg += nval[mg][side][square];
763
    score_eg += nval[eg][side][square];
764
/*
765
 ************************************************************
766
 *                                                          *
767
 *  Evaluate for "outposts" which is a knight that can't    *
768
 *  be driven off by an enemy pawn, and which is supported  *
769
 *  by a friendly pawn.                                     *
770
 *                                                          *
771
 *  If the enemy has NO minor to take this knight, then     *
772
 *  increase the bonus.                                     *
773
 *                                                          *
774
 ************************************************************
775
 */
108 pmbaty 776
    special = knight_outpost[side][square];
777
    if (special && !(mask_pattacks[enemy][square] & Pawns(enemy))) {
33 pmbaty 778
      if (pawn_attacks[enemy][square] & Pawns(side)) {
108 pmbaty 779
        special += special / 2;
33 pmbaty 780
        if (!Knights(enemy) && !(Color(square) & Bishops(enemy)))
108 pmbaty 781
          special += knight_outpost[side][square];
33 pmbaty 782
      }
108 pmbaty 783
      score_eg += special;
784
      score_mg += special;
33 pmbaty 785
    }
786
/*
787
 ************************************************************
788
 *                                                          *
789
 *  Adjust the tropism count for this piece.                *
790
 *                                                          *
791
 ************************************************************
792
 */
793
    if (tree->dangerous[side]) {
108 pmbaty 794
      i = Distance(square, KingSQ(enemy));
795
      tree->tropism[side] += king_tropism_n[i];
33 pmbaty 796
    }
797
  }
798
  tree->score_mg += sign[side] * score_mg;
799
  tree->score_eg += sign[side] * score_eg;
800
}
801
 
108 pmbaty 802
/* last modified 03/30/15 */
33 pmbaty 803
/*
804
 *******************************************************************************
805
 *                                                                             *
806
 *   EvaluateMate() is used to evaluate positions where neither side has pawns *
807
 *   and one side has enough material to force checkmate.  It simply trys to   *
808
 *   force the losing king to the edge of the board, and then to the corner    *
809
 *   where mates are easier to find.                                           *
810
 *                                                                             *
811
 *******************************************************************************
812
 */
813
void EvaluateMate(TREE * RESTRICT tree, int side) {
108 pmbaty 814
  int mate_score = 0, enemy = Flip(side);
33 pmbaty 815
 
816
/*
817
 ************************************************************
818
 *                                                          *
108 pmbaty 819
 *  If the winning side has a bishop + knight and the other *
820
 *  side has no pieces or pawns, then use the special       *
821
 *  bishop_knight scoring board for the losing king to      *
822
 *  force it to the right corner for mate.                  *
33 pmbaty 823
 *                                                          *
824
 ************************************************************
825
 */
108 pmbaty 826
  if (!TotalPieces(enemy, occupied) && TotalPieces(side, bishop) == 1 &&
827
      TotalPieces(side, knight) == 1) {
33 pmbaty 828
    if (dark_squares & Bishops(side))
829
      mate_score = b_n_mate_dark_squares[KingSQ(enemy)];
830
    else
831
      mate_score = b_n_mate_light_squares[KingSQ(enemy)];
832
  }
833
/*
834
 ************************************************************
835
 *                                                          *
108 pmbaty 836
 *  The winning side has to force the losing king to the    *
33 pmbaty 837
 *  edge of the board.                                      *
838
 *                                                          *
839
 ************************************************************
840
 */
108 pmbaty 841
  else
33 pmbaty 842
    mate_score = mate[KingSQ(enemy)];
108 pmbaty 843
/*
844
 ************************************************************
845
 *                                                          *
846
 *  And for either, it is important to bring the winning    *
847
 *  king to help force mate.                                *
848
 *                                                          *
849
 ************************************************************
850
 */
851
  mate_score -= Distance(KingSQ(side), KingSQ(enemy)) * king_king_tropism;
33 pmbaty 852
  tree->score_eg += sign[side] * mate_score;
853
}
854
 
108 pmbaty 855
/* last modified 10/19/15 */
33 pmbaty 856
/*
857
 *******************************************************************************
858
 *                                                                             *
859
 *  EvaluateMaterial() is used to evaluate material on the board.  It really   *
860
 *  accomplishes detecting cases where one side has made a 'bad trade' as the  *
861
 *  comments below show.                                                       *
862
 *                                                                             *
863
 *******************************************************************************
864
 */
865
void EvaluateMaterial(TREE * RESTRICT tree, int wtm) {
108 pmbaty 866
  int score_mg, score_eg, majors, minors;
33 pmbaty 867
 
868
/*
108 pmbaty 869
 *************************************************************
870
 *                                                           *
871
 *  We start with the raw Material balance for the current   *
872
 *  position, then adjust this with a small bonus for the    *
873
 *  side on move.                                            *
874
 *                                                           *
875
 *************************************************************
33 pmbaty 876
 */
877
  score_mg = Material + ((wtm) ? wtm_bonus[mg] : -wtm_bonus[mg]);
878
  score_eg = Material + ((wtm) ? wtm_bonus[eg] : -wtm_bonus[eg]);
879
/*
108 pmbaty 880
 *************************************************************
881
 *                                                           *
882
 *  test 1.  if Majors or Minors are not balanced, then if   *
883
 *  one side is only an exchange up or down, we give a       *
884
 *  penalty to the side that is an exchange down, but not as *
885
 *  big a penalty as the bad trade case below.               *
886
 *                                                           *
887
 *  test 2.  if Majors or Minors are not balanced, then if   *
888
 *  one side has more piece material points than the other   *
889
 *  (using normal piece values of 3, 3, 5, 9 for N, B, R     *
890
 *  and Q) then the side that is behind in piece material    *
891
 *  gets a penalty.                                          *
892
 *                                                           *
893
 *************************************************************
33 pmbaty 894
 */
108 pmbaty 895
  majors =
896
      TotalPieces(white, rook) + 2 * TotalPieces(white,
897
      queen) - TotalPieces(black, rook) - 2 * TotalPieces(black, queen);
898
  minors =
899
      TotalPieces(white, knight) + TotalPieces(white,
900
      bishop) - TotalPieces(black, knight) - TotalPieces(black, bishop);
901
  if (majors || minors) {
902
    if (Abs(TotalPieces(white, occupied) - TotalPieces(black, occupied)) != 2
903
        && TotalPieces(white, occupied) - TotalPieces(black, occupied) != 0) {
904
      score_mg +=
905
          Sign(TotalPieces(white, occupied) - TotalPieces(black,
906
              occupied)) * bad_trade;
907
      score_eg +=
908
          Sign(TotalPieces(white, occupied) - TotalPieces(black,
909
              occupied)) * bad_trade;
33 pmbaty 910
    }
911
  }
912
  tree->score_mg += score_mg;
913
  tree->score_eg += score_eg;
914
}
915
 
108 pmbaty 916
/* last modified 11/27/15 */
33 pmbaty 917
/*
918
 *******************************************************************************
919
 *                                                                             *
920
 *   EvaluatePassedPawns() is used to evaluate passed pawns and the danger     *
108 pmbaty 921
 *   they produce.  This code considers pieces as well, so it MUST NOT be done *
922
 *   in the normal EvaluatePawns() code since that hashes information based    *
923
 *   only on the position of pawns.                                            *
33 pmbaty 924
 *                                                                             *
108 pmbaty 925
 *   This is a significant rewrite of passed pawn evaluation, with the primary *
926
 *   change being to collect the passed pawn scoring into one place, rather    *
927
 *   than have it scattered around all over the place.  One example is the old *
928
 *   rook_behind_passed_pawn scoring term that was done in rook scoring.  It   *
929
 *   is now done here along with other passed pawn terms such as blockaded and *
930
 *   the ability to advance or not.                                            *
931
 *                                                                             *
33 pmbaty 932
 *******************************************************************************
933
 */
934
void EvaluatePassedPawns(TREE * RESTRICT tree, int side, int wtm) {
108 pmbaty 935
  uint64_t behind, forward, backward, attacked, defended, thispawn;
936
  int file, square, score, score_mg = 0, score_eg = 0, next_sq;
937
  int pawns, rank, mg_base, eg_base, bonus, enemy = Flip(side);
938
  uint64_t fsliders = Queens(side) | Rooks(side);
939
  uint64_t esliders = Queens(enemy) | Rooks(enemy);
33 pmbaty 940
 
941
/*
942
 ************************************************************
943
 *                                                          *
108 pmbaty 944
 *  Initialize.  The base value "passed_pawn[rank]" is      *
945
 *  almost the "square" of the rank.  That got a bit too    *
946
 *  big, so a hand-tuned set of values, one per rank,       *
947
 *  proved to be a better value.                            *
33 pmbaty 948
 *                                                          *
949
 ************************************************************
950
 */
951
  for (pawns = tree->pawn_score.passed[side]; pawns; pawns &= pawns - 1) {
952
    file = LSB8Bit(pawns);
108 pmbaty 953
    thispawn = Pawns(side) & file_mask[file];
954
    if (thispawn) {
955
      square = MostAdvanced(side, thispawn);
956
      rank = rankflip[side][Rank(square)];
957
      score = passed_pawn[rank];
33 pmbaty 958
/*
959
 ************************************************************
960
 *                                                          *
108 pmbaty 961
 *  For endgame only, we add in a bonus based on how close  *
962
 *  our king is to this pawn and a penalty based on how     *
963
 *  close the enemy king is.  We also try to keep our king  *
964
 *  ahead of the pawn so it can escort it to promotion.  We *
965
 *  only do this for passed pawns whose base score value is *
966
 *  greater than zero (ie pawns on ranks 4-7 since those    *
967
 *  are the ones threatening to become a major problem.)    *
968
 *  Also, if you happen to think that a small bonus for a   *
969
 *  passed pawn on the 3rd rank might be useful, consider   *
970
 *  speed.  If the 3rd rank score is non-zero, that will    *
971
 *  trigger a significant amount of work below.  In testing *
972
 *  the additional cost more than offset the gain and so it *
973
 *  is basically ignored unless rank > 3.                   *
974
 *                                                          *
33 pmbaty 975
 ************************************************************
976
 */
108 pmbaty 977
      if (score) {
978
        mg_base = score * passed_pawn_base[mg];
979
        eg_base = score * passed_pawn_base[eg];
980
        next_sq = square + direction[side];
981
        eg_base +=
982
            Distance(KingSQ(enemy),
983
            next_sq) * 2 * score - Distance(KingSQ(side), next_sq) * score;
984
        if (rank < RANK7)
985
          eg_base -=
986
              Distance(KingSQ(side), next_sq + direction[side]) * score / 2;
33 pmbaty 987
/*
988
 ************************************************************
989
 *                                                          *
108 pmbaty 990
 *  If the pawn is not blockaded, we need to see whether it *
991
 *  can actually advance or not.  Note that this directly   *
992
 *  gives a bonus for blockading a passed pawn since the    *
993
 *  mobility evaluation below will not be applied when the  *
994
 *  pawn is blockaded by any piece.                         *
33 pmbaty 995
 *                                                          *
108 pmbaty 996
 *  Step one is to determine if the squares in front of the *
997
 *  pawn are attacked by the enemy.  If not, we add in a    *
998
 *  significant score bonus.  If some are attacked, we look *
999
 *  to see if at least the square directly in front of the  *
1000
 *  pawn is not attacked so that we can advance one square, *
1001
 *  anyway.  This gets a smaller score bonus.               *
33 pmbaty 1002
 *                                                          *
1003
 ************************************************************
1004
 */
108 pmbaty 1005
        if (!(OccupiedSquares & SetMask(next_sq))) {
1006
          bonus = 0;
1007
          if (Pawns(side) & pawn_attacks[enemy][next_sq])
1008
            bonus = passed_pawn_free_advance;
1009
          else {
1010
            attacked = 0;
1011
            forward = (side) ? plus8dir[square] : minus8dir[square];
1012
            backward = (side) ? minus8dir[square] : plus8dir[square];
1013
            if ((behind = backward & esliders) &&
1014
                (FileAttacks(square) & behind))
1015
              attacked = forward;
1016
            else
1017
              attacked = Attacked(tree, enemy, forward);
1018
            if (!attacked)
1019
              bonus = passed_pawn_free_advance;
1020
            else if (!(attacked & SetMask(next_sq)))
1021
              bonus = passed_pawn_free_advance_1;
33 pmbaty 1022
/*
1023
 ************************************************************
1024
 *                                                          *
108 pmbaty 1025
 *  Step two is to determine if the squares in front of the *
1026
 *  pawn are are defended by the friendly side.  If all are *
1027
 *  defended (such as with a rook or queen behind the pawn  *
1028
 *  or the king in front and to one side of the pawn, then  *
1029
 *  we give a bonus (but smaller than the previous cases).  *
1030
 *  As a last resort, if we at least defend the square in   *
1031
 *  front of the pawn, we give a small bonus.               *
33 pmbaty 1032
 *                                                          *
1033
 ************************************************************
1034
 */
108 pmbaty 1035
            if ((behind = backward & fsliders) &&
1036
                (FileAttacks(square) & behind))
1037
              defended = forward;
1038
            else
1039
              defended = Attacked(tree, side, forward);
1040
            if (defended == forward)
1041
              bonus += passed_pawn_defended;
1042
            else if (defended & SetMask(next_sq))
1043
              bonus += passed_pawn_defended_1;
1044
          }
33 pmbaty 1045
/*
1046
 ************************************************************
1047
 *                                                          *
108 pmbaty 1048
 *  Fold in the bonus for this pawn and move on to the next *
1049
 *  (if there is one).  Note that the bonus computed above  *
1050
 *  is multiplied by the base passed pawn score for this    *
1051
 *  particular rank.                                        *
33 pmbaty 1052
 *                                                          *
1053
 ************************************************************
1054
 */
108 pmbaty 1055
          mg_base += bonus * score;
1056
          eg_base += bonus * score;
1057
        }
1058
        score_mg += mg_base;
1059
        score_eg += eg_base;
1060
      } else
1061
        score_eg += 4;
33 pmbaty 1062
    }
1063
  }
1064
/*
1065
 ************************************************************
1066
 *                                                          *
108 pmbaty 1067
 *  All pawns done, add score to the two evaluation values  *
1068
 *  and return.                                             *
33 pmbaty 1069
 *                                                          *
1070
 ************************************************************
1071
 */
1072
  tree->score_mg += sign[side] * score_mg;
1073
  tree->score_eg += sign[side] * score_eg;
1074
}
1075
 
108 pmbaty 1076
/* last modified 11/27/15 */
33 pmbaty 1077
/*
1078
 *******************************************************************************
1079
 *                                                                             *
1080
 *   EvaluatePassedPawnRaces() is used to evaluate passed pawns when one       *
1081
 *   side has passed pawns and the other side (or neither) has pieces.  In     *
108 pmbaty 1082
 *   such a case, the critical question is can the defending king stop the     *
1083
 *   pawn from queening or is it too far away?  If only one side has pawns     *
1084
 *   that can "run" then the situation is simple.  When both sides have pawns  *
1085
 *   that can "run" it becomes more complex as it then becomes necessary to    *
1086
 *   see if one side can use a forced king move to stop the other side, while  *
1087
 *   the other side doesn't have the same ability to stop ours.                *
33 pmbaty 1088
 *                                                                             *
1089
 *   In the case of king and pawn endings with exactly one pawn, the simple    *
1090
 *   evaluation rules are used:  if the king is two squares in front of the    *
1091
 *   pawn then it is a win, if the king is one one square in front with the    *
1092
 *   opposition, then it is a win,  if the king is on the 6th rank with the    *
1093
 *   pawn close by, it is a win.  Rook pawns are handled separately and are    *
1094
 *   more difficult to queen because the king can get trapped in front of the  *
1095
 *   pawn blocking promotion.                                                  *
1096
 *                                                                             *
1097
 *******************************************************************************
1098
 */
1099
void EvaluatePassedPawnRaces(TREE * RESTRICT tree, int wtm) {
108 pmbaty 1100
  uint64_t pawns, thispawn;
1101
  int file, square, queen_distance, pawnsq, passed, side, enemy;
33 pmbaty 1102
  int queener[2] = { 8, 8 };
1103
/*
1104
 ************************************************************
1105
 *                                                          *
1106
 *  Check to see if side has one pawn and neither side has  *
1107
 *  any pieces.  If so, use the simple pawn evaluation      *
1108
 *  logic.                                                  *
1109
 *                                                          *
1110
 ************************************************************
1111
 */
1112
  for (side = black; side <= white; side++) {
1113
    enemy = Flip(side);
1114
    if (Pawns(side) && !Pawns(enemy) && TotalPieces(white, occupied) == 0 &&
1115
        TotalPieces(black, occupied) == 0) {
1116
      for (pawns = Pawns(side); pawns; pawns &= pawns - 1) {
1117
        pawnsq = LSB(pawns);
1118
/*
1119
 ************************************************************
1120
 *                                                          *
1121
 *  King must be in front of the pawn or we go no further.  *
1122
 *                                                          *
1123
 ************************************************************
1124
 */
1125
        if (sign[side] * Rank(KingSQ(side)) <= sign[side] * Rank(pawnsq))
1126
          continue;
1127
/*
1128
 ************************************************************
1129
 *                                                          *
1130
 *  First a special case.  If this is a rook pawn, then the *
1131
 *  king must be on the adjacent file, and be closer to the *
1132
 *  queening square than the opposing king.                 *
1133
 *                                                          *
1134
 ************************************************************
1135
 */
1136
        if (File(pawnsq) == FILEA) {
1137
          if (File(KingSQ(side)) == FILEB &&
1138
              Distance(KingSQ(side),
1139
                  sqflip[side][A8]) < Distance(KingSQ(enemy),
1140
                  sqflip[side][A8])) {
1141
            tree->score_eg += sign[side] * pawn_can_promote;
1142
            return;
1143
          }
1144
          continue;
1145
        } else if (File(pawnsq) == FILEH) {
1146
          if (File(KingSQ(side)) == FILEG &&
1147
              Distance(KingSQ(side),
1148
                  sqflip[side][H8]) < Distance(KingSQ(enemy),
1149
                  sqflip[side][H8])) {
1150
            tree->score_eg += sign[side] * pawn_can_promote;
1151
            return;
1152
          }
1153
          continue;
1154
        }
1155
/*
1156
 ************************************************************
1157
 *                                                          *
1158
 *  If king is two squares in front of the pawn then it's a *
1159
 *  win immediately.  If the king is on the 6th rank and    *
1160
 *  closer to the pawn than the opposing king, it's also a  *
1161
 *  win.                                                    *
1162
 *                                                          *
1163
 ************************************************************
1164
 */
1165
        if (Distance(KingSQ(side), pawnsq) < Distance(KingSQ(enemy), pawnsq)) {
1166
          if (sign[side] * Rank(KingSQ(side)) >
1167
              sign[side] * (Rank(pawnsq) - 1 + 2 * side)) {
1168
            tree->score_eg += sign[side] * pawn_can_promote;
1169
            return;
1170
          }
108 pmbaty 1171
          if (Rank(KingSQ(side)) == rank6[side]) {
33 pmbaty 1172
            tree->score_eg += sign[side] * pawn_can_promote;
1173
            return;
1174
          }
1175
/*
1176
 ************************************************************
1177
 *                                                          *
1178
 *  Last chance:  if the king is one square in front of the *
1179
 *  pawn and has the opposition, then it's still a win.     *
1180
 *                                                          *
1181
 ************************************************************
1182
 */
1183
          if (Rank(KingSQ(side)) == Rank(pawnsq) - 1 + 2 * side &&
1184
              EvaluateHasOpposition(wtm == side, KingSQ(side),
1185
                  KingSQ(enemy))) {
1186
            tree->score_eg += sign[side] * pawn_can_promote;
1187
            return;
1188
          }
1189
        }
1190
      }
1191
    }
1192
/*
1193
 ************************************************************
1194
 *                                                          *
1195
 *  Check to see if enemy is out of pieces and stm has      *
1196
 *  passed pawns.  If so, see if any of these passed pawns  *
1197
 *  can outrun the defending king and promote.              *
1198
 *                                                          *
1199
 ************************************************************
1200
 */
1201
    if (TotalPieces(enemy, occupied) == 0 && tree->pawn_score.passed[side]) {
1202
      passed = tree->pawn_score.passed[side];
1203
      for (; passed; passed &= passed - 1) {
1204
        file = LSB8Bit(passed);
108 pmbaty 1205
        thispawn = Pawns(side) & file_mask[file];
1206
        if (thispawn) {
1207
          square = MostAdvanced(side, thispawn);
1208
          if (!(pawn_race[side][wtm][square] & Kings(enemy))) {
1209
            queen_distance = Abs(rank8[side] - Rank(square));
1210
            if (Kings(side) & ((side) ? plus8dir[square] : minus8dir[square])) {
1211
              if (file == FILEA || file == FILEH)
1212
                queen_distance = 99;
1213
              queen_distance++;
1214
            }
1215
            if (Rank(square) == rank2[side])
1216
              queen_distance--;
1217
            if (queen_distance < queener[side])
1218
              queener[side] = queen_distance;
33 pmbaty 1219
          }
1220
        }
1221
      }
1222
    }
1223
  }
1224
/*
1225
 ************************************************************
1226
 *                                                          *
1227
 *  Now that we know which pawns can outrun the kings for   *
108 pmbaty 1228
 *  each side, we need to do determine if one side queens   *
1229
 *  before the other.  If so, that side wins.  If they      *
1230
 *  queen at the same time, then we will have to rely on    *
1231
 *  the search to handle queening with check or queening    *
1232
 *  and attacking the opponent's queening square.           *
33 pmbaty 1233
 *                                                          *
1234
 ************************************************************
1235
 */
108 pmbaty 1236
  if (queener[white] < queener[black])
33 pmbaty 1237
    tree->score_eg += pawn_can_promote + (5 - queener[white]) * 10;
108 pmbaty 1238
  else if (queener[black] < queener[white])
1239
    tree->score_eg -= pawn_can_promote + (5 - queener[black]) * 10;
33 pmbaty 1240
}
1241
 
108 pmbaty 1242
/* last modified 11/27/15 */
33 pmbaty 1243
/*
1244
 *******************************************************************************
1245
 *                                                                             *
1246
 *   EvaluatePawns() is used to evaluate pawns.  It evaluates pawns for only   *
1247
 *   one side, and fills in the pawn hash entry information.  It requires two  *
1248
 *   calls to evaluate all pawns on the board.  Comments below indicate the    *
1249
 *   particular pawn structure features that are evaluated.                    *
1250
 *                                                                             *
108 pmbaty 1251
 *   This procedure also flags which pawns are passed, since this is scored in *
1252
 *   another part of the evaluation because that includes piece information    *
1253
 *   which can not be used here since the pawn hash signature does not include *
1254
 *   piece information of any kind.                                            *
33 pmbaty 1255
 *                                                                             *
108 pmbaty 1256
 *   Note that a pawn is not penalized for two different reasons.  If it is    *
1257
 *   isolated, it is not backward.  Etc.  This simplifies evaluation tuning    *
1258
 *   not to mention eliminating the overlap and interaction that was happening *
1259
 *   previously when multiple penalties could be applied.                      *
1260
 *                                                                             *
33 pmbaty 1261
 *******************************************************************************
1262
 */
1263
void EvaluatePawns(TREE * RESTRICT tree, int side) {
108 pmbaty 1264
  uint64_t pawns, attackers, defenders;
1265
  uint64_t doubled, supported, connected, passed, backward;
1266
  int square, file, rank, score_eg = 0, score_mg = 0, enemy = Flip(side);
1267
  unsigned int isolated, pawn_files = 0;
33 pmbaty 1268
 
1269
/*
1270
 ************************************************************
1271
 *                                                          *
108 pmbaty 1272
 *  Loop through all pawns for this side.                   *
33 pmbaty 1273
 *                                                          *
1274
 ************************************************************
1275
 */
1276
  tree->pawn_score.passed[side] = 0;
1277
  for (pawns = Pawns(side); pawns; pawns &= pawns - 1) {
1278
    square = LSB(pawns);
1279
    file = File(square);
1280
    rank = rankflip[side][Rank(square)];
108 pmbaty 1281
    pawn_files |= 1 << file;
33 pmbaty 1282
/*
1283
 ************************************************************
1284
 *                                                          *
1285
 *  Evaluate pawn advances.  Center pawns are encouraged to *
108 pmbaty 1286
 *  occupy central squares, edge pawns are penalized on all *
1287
 *  edge squares to encourage capture toward the center,    *
1288
 *  the rest are neutral.                                   *
33 pmbaty 1289
 *                                                          *
1290
 ************************************************************
1291
 */
1292
    score_mg += pval[mg][side][square];
1293
    score_eg += pval[eg][side][square];
1294
/*
1295
 ************************************************************
1296
 *                                                          *
108 pmbaty 1297
 *  Evaluate isolated pawns, which are penalized based on   *
1298
 *  which file they occupy.                                 *
33 pmbaty 1299
 *                                                          *
1300
 ************************************************************
1301
 */
108 pmbaty 1302
    isolated = !(Pawns(side) & mask_pawn_isolated[square]);
1303
    if (isolated) {
1304
      score_mg -= pawn_isolated[mg][file];
1305
      score_eg -= pawn_isolated[eg][file];
33 pmbaty 1306
    }
1307
/*
1308
 ************************************************************
1309
 *                                                          *
108 pmbaty 1310
 *  Evaluate unsupported pawns, which provide a target      *
1311
 *  since they are undefended by a pawn.  We exclude pawns  *
1312
 *  that are isolated since they have already been given a  *
1313
 *  penalty.                                                *
33 pmbaty 1314
 *                                                          *
1315
 ************************************************************
1316
 */
108 pmbaty 1317
    supported = Pawns(side) & pawn_attacks[enemy][square];
1318
    if (!isolated && !supported) {
1319
      score_mg += pawn_unsupported[mg];
1320
      score_eg += pawn_unsupported[eg];
1321
    }
33 pmbaty 1322
/*
1323
 ************************************************************
1324
 *                                                          *
108 pmbaty 1325
 *  Evaluate doubled pawns.  If there are other pawns on    *
1326
 *  this file in front of this pawn, penalize this pawn.    *
1327
 *  Note that this will NOT penalize both pawns, just the   *
1328
 *  most rearward one that is really almost worthless.      *
33 pmbaty 1329
 *                                                          *
108 pmbaty 1330
 *  The farther apart two doubled pawns (same file) are,    *
1331
 *  the less weak they are, so the penalty is reduced as    *
1332
 *  this distance increases.                                *
1333
 *                                                          *
33 pmbaty 1334
 ************************************************************
1335
 */
108 pmbaty 1336
    doubled = Pawns(side) & ((side) ? plus8dir[square] : minus8dir[square]);
1337
    if (doubled) {
1338
      score_mg -=
1339
          pawn_doubled[mg][file] / RankDistance(square, MostAdvanced(side,
1340
              doubled));
1341
      score_eg -=
1342
          pawn_doubled[eg][file] / RankDistance(square, MostAdvanced(side,
1343
              doubled));
1344
    }
33 pmbaty 1345
/*
1346
 ************************************************************
1347
 *                                                          *
108 pmbaty 1348
 *  Test the pawn to see if it is connected to a neighbor   *
1349
 *  which makes it easier to defend.                        *
33 pmbaty 1350
 *                                                          *
1351
 ************************************************************
1352
 */
108 pmbaty 1353
    connected = Pawns(side) & mask_pawn_connected[side][square];
1354
    if (connected) {
1355
      score_mg += pawn_connected[rank][file];
1356
      score_eg += pawn_connected[rank][file];
1357
    }
33 pmbaty 1358
/*
1359
 ************************************************************
1360
 *                                                          *
108 pmbaty 1361
 *  Flag passed pawns for use later when we finally call    *
1362
 *  EvaluatePassedPawns.                                    *
33 pmbaty 1363
 *                                                          *
1364
 ************************************************************
1365
 */
108 pmbaty 1366
    passed = !(Pawns(enemy) & mask_passed[side][square]);
1367
    if (passed)
1368
      tree->pawn_score.passed[side] |= 1 << file;
33 pmbaty 1369
/*
1370
 ************************************************************
1371
 *                                                          *
108 pmbaty 1372
 *  Test the pawn to see if it is backward which makes it a *
1373
 *  target that ties down pieces to defend it.              *
33 pmbaty 1374
 *                                                          *
1375
 ************************************************************
1376
 */
108 pmbaty 1377
    backward = 0;
1378
    if (!(passed | isolated | connected | (Pawns(side) &
1379
                mask_pattacks[side][square]) | (Pawns(enemy) &
1380
                PawnAttacks(side, square))))
1381
      backward = Pawns(enemy) & PawnAttacks(side, square + direction[side]);
1382
    if (backward) {
1383
      score_mg -= pawn_backward[mg][file];
1384
      score_eg -= pawn_backward[eg][file];
1385
    }
33 pmbaty 1386
/*
1387
 ************************************************************
1388
 *                                                          *
108 pmbaty 1389
 *  Determine if this pawn is a candidate passed pawn,      *
1390
 *  which is a pawn on a file with no enemy pawns in front  *
1391
 *  of it, and if it advances until it contacts an enemy    *
1392
 *  pawn, and it is defended at least as many times as it   *
1393
 *  is attacked when it reaches that pawn, then it will end *
1394
 *  up passed.                                              *
33 pmbaty 1395
 *                                                          *
1396
 ************************************************************
1397
 */
108 pmbaty 1398
    if (!(passed | backward | isolated) &&
1399
        !(Pawns(enemy) & ((side) ? plus8dir[square] : minus8dir[square]))) {
1400
      defenders = mask_pattacks[side][square + direction[side]] & Pawns(side);
1401
      attackers = mask_pattacks[enemy][square] & Pawns(enemy);
1402
      if (PopCnt(defenders) >= PopCnt(attackers)) {
1403
        score_mg += passed_pawn_candidate[mg][rank];
1404
        score_eg += passed_pawn_candidate[eg][rank];
33 pmbaty 1405
      }
1406
    }
108 pmbaty 1407
  }
33 pmbaty 1408
/*
1409
 ************************************************************
1410
 *                                                          *
108 pmbaty 1411
 *  Give a bonus for distance between left-most pawn and    *
1412
 *  right-most pawn.  The idea is that the wider the gap    *
1413
 *  between the pawns, the harder they are for a lone king  *
1414
 *  to control in the endgame.  Botvinnik referred to this  *
1415
 *  concept as "trousers" (pants with two legs, the farther *
1416
 *  the legs are apart, the better for the side with those  *
1417
 *  pawns).                                                 *
33 pmbaty 1418
 *                                                          *
1419
 ************************************************************
1420
 */
108 pmbaty 1421
  score_eg += pawn_file_width * (MSB8Bit(pawn_files) - LSB8Bit(pawn_files));
33 pmbaty 1422
/*
1423
 ************************************************************
1424
 *                                                          *
1425
 *  Evaluate king safety.                                   *
1426
 *                                                          *
108 pmbaty 1427
 *  This uses the function EvaluateKingsFile() and looks at *
1428
 *  three possible positions for the king, either castled   *
33 pmbaty 1429
 *  kingside, queenside or else standing on the d or e file *
1430
 *  stuck in the middle.  This essentially is about the     *
1431
 *  pawns in front of the king and what kind of "shelter"   *
1432
 *  they provide for the king during the middlegame.        *
1433
 *                                                          *
1434
 ************************************************************
1435
 */
108 pmbaty 1436
  tree->pawn_score.defects_q[side] =
1437
      EvaluateKingsFile(tree, side, FILEA, FILEC);
1438
  tree->pawn_score.defects_m[side] =
1439
      EvaluateKingsFile(tree, side, FILEC, FILEF);
1440
  tree->pawn_score.defects_k[side] =
1441
      EvaluateKingsFile(tree, side, FILEF, FILEH);
1442
/*
1443
 ************************************************************
1444
 *                                                          *
1445
 *  Done.  Add mg/eg scores to final result (sign-corrected *
1446
 *  so that black = -, white = +) and return.               *
1447
 *                                                          *
1448
 ************************************************************
1449
 */
33 pmbaty 1450
  tree->pawn_score.score_mg += sign[side] * score_mg;
1451
  tree->pawn_score.score_eg += sign[side] * score_eg;
1452
}
1453
 
108 pmbaty 1454
/* last modified 10/19/15 */
33 pmbaty 1455
/*
1456
 *******************************************************************************
1457
 *                                                                             *
1458
 *   EvaluateQueens() is used to evaluate queens.                              *
1459
 *                                                                             *
1460
 *******************************************************************************
1461
 */
1462
void EvaluateQueens(TREE * RESTRICT tree, int side) {
1463
  uint64_t temp;
108 pmbaty 1464
  int square, i, score_mg = 0, score_eg = 0, enemy = Flip(side);
33 pmbaty 1465
 
1466
/*
1467
 ************************************************************
1468
 *                                                          *
1469
 *  First locate each queen and obtain it's centralization  *
1470
 *  score from the static piece/square table for queens.    *
1471
 *                                                          *
1472
 ************************************************************
1473
 */
1474
  for (temp = Queens(side); temp; temp &= temp - 1) {
1475
    square = LSB(temp);
1476
/*
1477
 ************************************************************
1478
 *                                                          *
1479
 *  Then, add in the piece/square table value for the       *
1480
 *  queen.                                                  *
1481
 *                                                          *
1482
 ************************************************************
1483
*/
1484
    score_mg += qval[mg][side][square];
1485
    score_eg += qval[eg][side][square];
1486
/*
1487
 ************************************************************
1488
 *                                                          *
1489
 *  Adjust the tropism count for this piece.                *
1490
 *                                                          *
1491
 ************************************************************
1492
 */
1493
    if (tree->dangerous[side]) {
108 pmbaty 1494
      i = KingSQ(enemy);
1495
      tree->tropism[side] += king_tropism_q[Distance(square, i)];
1496
      i = 8 - (RankDistance(square, i) + FileDistance(square, i));
1497
      score_mg += i;
1498
      score_eg += i;
33 pmbaty 1499
    }
1500
  }
1501
  tree->score_mg += sign[side] * score_mg;
1502
  tree->score_eg += sign[side] * score_eg;
1503
}
1504
 
108 pmbaty 1505
/* last modified 10/19/15 */
33 pmbaty 1506
/*
1507
 *******************************************************************************
1508
 *                                                                             *
1509
 *   EvaluateRooks() is used to evaluate rooks.                                *
1510
 *                                                                             *
1511
 *******************************************************************************
1512
 */
1513
void EvaluateRooks(TREE * RESTRICT tree, int side) {
1514
  uint64_t temp, moves;
108 pmbaty 1515
  int square, rank, file, i, mobility, score_mg = 0, score_eg = 0;
33 pmbaty 1516
  int enemy = Flip(side);
1517
 
1518
/*
1519
 ************************************************************
1520
 *                                                          *
1521
 *  Initialize.                                             *
1522
 *                                                          *
1523
 ************************************************************
1524
 */
1525
  for (temp = Rooks(side); temp; temp &= temp - 1) {
1526
    square = LSB(temp);
1527
    file = File(square);
1528
    rank = Rank(square);
1529
/*
1530
 ************************************************************
1531
 *                                                          *
1532
 *  Determine if the rook is on an open file or on a half-  *
1533
 *  open file, either of which increases its ability to     *
1534
 *  attack important squares.                               *
1535
 *                                                          *
1536
 ************************************************************
1537
 */
1538
    if (!(file_mask[file] & Pawns(side))) {
1539
      if (!(file_mask[file] & Pawns(enemy))) {
1540
        score_mg += rook_open_file[mg];
1541
        score_eg += rook_open_file[eg];
1542
      } else {
1543
        score_mg += rook_half_open_file[mg];
1544
        score_eg += rook_half_open_file[eg];
1545
      }
1546
    }
1547
/*
1548
 ************************************************************
1549
 *                                                          *
108 pmbaty 1550
 *  Mobility counts the number of squares the rook attacks, *
1551
 *  excluding squares with friendly pieces, and weighs each *
1552
 *  square according to a complex formula that includes     *
1553
 *  files as well as total number of squares attacked.      *
1554
 *                                                          *
1555
 ************************************************************
1556
 */
1557
    mobility = RookMobility(square, OccupiedSquares);
1558
    score_mg += mobility;
1559
    score_eg += mobility;
1560
/*
1561
 ************************************************************
1562
 *                                                          *
33 pmbaty 1563
 *  Check to see if the king has been forced to move and    *
1564
 *  has trapped a rook at a1/b1/g1/h1, if so, then penalize *
108 pmbaty 1565
 *  the trapped rook to help extricate it.  We only need to *
1566
 *  check this if the rooks mobility is very low.           *
33 pmbaty 1567
 *                                                          *
1568
 ************************************************************
1569
 */
108 pmbaty 1570
    if (mobility < 0 && rank == rank1[side] && rank == Rank(KingSQ(side))) {
1571
      i = File(KingSQ(side));
1572
      if (i > FILEE) {
1573
        if (file > i) {
1574
          score_mg += mobility * 3;
1575
          score_eg += mobility * 3;
33 pmbaty 1576
        }
108 pmbaty 1577
      } else if (i < FILED && file < i) {
1578
        score_mg += mobility * 3;
1579
        score_eg += mobility * 3;
33 pmbaty 1580
      }
1581
    }
1582
/*
1583
 ************************************************************
1584
 *                                                          *
108 pmbaty 1585
 *   finally check to see if any rooks are on the 7th rank, *
1586
 *   with the opponent having pawns on that rank or the     *
1587
 *   opponent's king being hemmed in on the 7th/8th rank.   *
1588
 *   If so, we give a bonus for the strong rook.  If there  *
1589
 *   is another rook or queen on the 7th that is connected  *
1590
 *   with this one, then the positional advantage is even   *
1591
 *   stronger.                                              *
33 pmbaty 1592
 *                                                          *
1593
 ************************************************************
1594
 */
108 pmbaty 1595
    else if (rank == rank7[side] && (Rank(KingSQ(enemy)) == rank8[side]
1596
            || Pawns(enemy) & rank_mask[rank])) {
33 pmbaty 1597
      score_mg += rook_on_7th[mg];
1598
      score_eg += rook_on_7th[eg];
108 pmbaty 1599
      if (RankAttacks(square) & (Queens(side) | Rooks(side))) {
1600
        score_mg += rook_connected_7th[mg];
1601
        score_eg += rook_connected_7th[eg];
1602
      }
33 pmbaty 1603
    }
1604
/*
1605
 ************************************************************
1606
 *                                                          *
1607
 *  Adjust the tropism count for this piece.                *
1608
 *                                                          *
1609
 ************************************************************
1610
 */
1611
    if (tree->dangerous[side]) {
1612
      moves = king_attacks[KingSQ(enemy)];
108 pmbaty 1613
      i = (rook_attacks[square] & moves &&
33 pmbaty 1614
          RookAttacks(square,
108 pmbaty 1615
              OccupiedSquares & ~(Queens(side) | Rooks(side))) & moves) ? 1 :
1616
          Distance(square, KingSQ(enemy));
1617
      tree->tropism[side] += king_tropism_r[i];
33 pmbaty 1618
    }
1619
  }
1620
  tree->score_mg += sign[side] * score_mg;
1621
  tree->score_eg += sign[side] * score_eg;
1622
}
1623
 
108 pmbaty 1624
/* last modified 01/03/15 */
33 pmbaty 1625
/*
1626
 *******************************************************************************
1627
 *                                                                             *
1628
 *   EvaluateWinningChances() is used to determine if one side has reached a   *
1629
 *   position which can not be won, period, even though side may be ahead in   *
1630
 *   material in some way.                                                     *
1631
 *                                                                             *
1632
 *   Return values:                                                            *
108 pmbaty 1633
 *          0    ->     side on move can not win.                              *
1634
 *          1    ->     side on move can win.                                  *
33 pmbaty 1635
 *                                                                             *
1636
 *******************************************************************************
1637
 */
1638
int EvaluateWinningChances(TREE * RESTRICT tree, int side, int wtm) {
108 pmbaty 1639
  int square, ekd, promote, majors, minors, enemy = Flip(side);
33 pmbaty 1640
 
108 pmbaty 1641
  if (!Pawns(side)) {
33 pmbaty 1642
/*
1643
 ************************************************************
1644
 *                                                          *
1645
 *  If side has a piece and no pawn, it can not possibly    *
1646
 *  win.  If side is a piece ahead, the only way it can win *
1647
 *  is if the enemy is already trapped on the edge of the   *
1648
 *  board (special case to handle KRB vs KR which can be    *
1649
 *  won if the king gets trapped).                          *
1650
 *                                                          *
1651
 ************************************************************
1652
 */
1653
    if (TotalPieces(side, occupied) <= 3)
1654
      return 0;
1655
    if (TotalPieces(side, occupied) - TotalPieces(enemy, occupied) <= 3 &&
1656
        mask_not_edge & Kings(enemy))
1657
      return 0;
108 pmbaty 1658
/*
1659
 ************************************************************
1660
 *                                                          *
1661
 *  If one side is an exchange up, but has no pawns, then   *
1662
 *  that side can not possibly win.                         *
1663
 *                                                          *
1664
 ************************************************************
1665
 */
1666
    majors =
1667
        TotalPieces(white, rook) + 2 * TotalPieces(white,
1668
        queen) - TotalPieces(black, rook) - 2 * TotalPieces(black, queen);
1669
    if (Abs(majors) == 1) {
1670
      minors =
1671
          TotalPieces(black, knight) + TotalPieces(black,
1672
          bishop) - TotalPieces(white, knight) - TotalPieces(white, bishop);
1673
      if (majors == minors)
1674
        return 0;
1675
    }
1676
  } else {
1677
/*
1678
 ************************************************************
1679
 *                                                          *
1680
 *  If neither side has any pieces, and both sides have     *
1681
 *  non-rookpawns, then either side can win.                *
1682
 *                                                          *
1683
 ************************************************************
1684
 */
1685
    if (TotalPieces(white, occupied) == 0 && TotalPieces(black, occupied) == 0
1686
        && Pawns(white) & not_rook_pawns && Pawns(black) & not_rook_pawns)
1687
      return 1;
33 pmbaty 1688
  }
1689
/*
1690
 ************************************************************
1691
 *                                                          *
1692
 *  If "side" has a pawn, then either the pawn had better   *
108 pmbaty 1693
 *  not be a rook pawn, or else side had better have the    *
33 pmbaty 1694
 *  right color bishop or any other piece, otherwise it is  *
1695
 *  not winnable if the enemy king can get to the queening  *
1696
 *  square first.                                           *
1697
 *                                                          *
1698
 ************************************************************
1699
 */
108 pmbaty 1700
  if (!(Pawns(side) & not_rook_pawns))
33 pmbaty 1701
    do {
1702
      if (TotalPieces(side, occupied) > 3 || (TotalPieces(side, occupied) == 3
1703
              && Knights(side)))
1704
        continue;
1705
      if (file_mask[FILEA] & Pawns(side) && file_mask[FILEH] & Pawns(side))
1706
        continue;
1707
      if (Bishops(side)) {
1708
        if (Bishops(side) & dark_squares) {
1709
          if (file_mask[dark_corner[side]] & Pawns(side))
1710
            continue;
1711
        } else if (file_mask[light_corner[side]] & Pawns(side))
1712
          continue;
1713
      }
1714
      if (Pawns(side) & file_mask[FILEA])
1715
        promote = A8;
1716
      else
1717
        promote = H8;
1718
      ekd = Distance(KingSQ(enemy), sqflip[side][promote]) - (wtm != side);
1719
      if (ekd <= 1)
1720
        return 0;
1721
    } while (0);
1722
/*
1723
 ************************************************************
1724
 *                                                          *
108 pmbaty 1725
 *  Check to see if this is a KRP vs KR ending.  If so, and *
1726
 *  the losing king is in front of the passer, then this is *
1727
 *  a drawish ending.                                       *
33 pmbaty 1728
 *                                                          *
1729
 ************************************************************
1730
 */
1731
  if (TotalPieces(side, pawn) == 1 && TotalPieces(enemy, pawn) == 0 &&
108 pmbaty 1732
      TotalPieces(side, occupied) == 5 && TotalPieces(enemy, occupied) == 5) {
33 pmbaty 1733
    square = LSB(Pawns(side));
1734
    if (FileDistance(KingSQ(enemy), square) <= 1 &&
1735
        InFront(side, Rank(KingSQ(enemy)), Rank(square)))
1736
      return 0;
1737
  }
1738
/*
1739
 ************************************************************
1740
 *                                                          *
1741
 *  If this side has pawns, and we have made it through the *
1742
 *  previous tests, then this side has winning chances.     *
1743
 *                                                          *
1744
 ************************************************************
1745
 */
1746
  if (TotalPieces(side, pawn))
1747
    return 1;
1748
/*
1749
 ************************************************************
1750
 *                                                          *
1751
 *  If this side has two bishops, and the enemy has only a  *
1752
 *  single kinght, the two bishops win.                     *
1753
 *                                                          *
1754
 ************************************************************
1755
 */
1756
  if (TotalPieces(side, occupied) == 6)
1757
    if (TotalPieces(enemy, occupied) == 3 && (Knights(side)
1758
            || !Knights(enemy)))
1759
      return 0;
1760
/*
1761
 ************************************************************
1762
 *                                                          *
1763
 *  If one side is two knights ahead and the opponent has   *
1764
 *  no remaining material, it is a draw.                    *
1765
 *                                                          *
1766
 ************************************************************
1767
 */
1768
  if (TotalPieces(side, occupied) == 6 && !Bishops(side)
1769
      && TotalPieces(enemy, occupied) + TotalPieces(enemy, pawn) == 0)
1770
    return 0;
108 pmbaty 1771
/*
1772
 ************************************************************
1773
 *                                                          *
1774
 *  If we make it through all the above tests, then "side"  *
1775
 *  can win so we return 1.                                 *
1776
 *                                                          *
1777
 ************************************************************
1778
 */
33 pmbaty 1779
  return 1;
1780
}
108 pmbaty 1781
 
1782
/*
1783
 *******************************************************************************
1784
 *                                                                             *
1785
 *   InitializeKingSafety() is used to initialize the king safety matrix.      *
1786
 *   This is set so that the matrix, indexed by king safety pawn structure     *
1787
 *   index and by king safety piece tropism, combines the two indices to       *
1788
 *   produce a single score.  As either index rises, the king safety score     *
1789
 *   tracks along, but as both rise, the king safety score rises much more     *
1790
 *   quickly.                                                                  *
1791
 *                                                                             *
1792
 *******************************************************************************
1793
 */
1794
void InitializeKingSafety() {
1795
  int safety, tropism;
1796
 
1797
  for (safety = 0; safety < 16; safety++) {
1798
    for (tropism = 0; tropism < 16; tropism++) {
1799
      king_safety[safety][tropism] =
1800
          180 * ((safety_vector[safety] + 100) * (tropism_vector[tropism] +
1801
              100) / 100 - 100) / 100;
1802
    }
1803
  }
1804
}