1
/* GNU Chess 5.0 - eval.c - evaluation code
2
Copyright (c) 1999-2002 Free Software Foundation, Inc.
4
GNU Chess is based on the two research programs
5
Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.
7
GNU Chess is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
GNU Chess is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with GNU Chess; see the file COPYING. If not, write to
19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
Boston, MA 02111-1307, USA.
24
cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
27
/****************************************************************************
31
*****************************************************************************/
41
int LoneKing (int, int);
42
int ScoreKBNK (int, int);
44
int BishopTrapped (short);
45
int DoubleQR7 (short);
50
static int PawnSq[2][64] =
52
{ 0, 0, 0, 0, 0, 0, 0, 0,
53
5, 5, 5,-10,-10, 5, 5, 5,
54
-2, -2, -2, 6, 6, -2, -2, -2,
55
0, 0, 0, 25, 25, 0, 0, 0,
56
2, 2, 12, 16, 16, 12, 2, 2,
57
4, 8, 12, 16, 16, 12, 4, 4,
58
4, 8, 12, 16, 16, 12, 4, 4,
59
0, 0, 0, 0, 0, 0, 0, 0},
60
{ 0, 0, 0, 0, 0, 0, 0, 0,
61
4, 8, 12, 16, 16, 12, 4, 4,
62
4, 8, 12, 16, 16, 12, 4, 4,
63
2, 2, 12, 16, 16, 12, 2, 2,
64
0, 0, 0, 25, 25, 0, 0, 0,
65
-2, -2, -2, 6, 6, -2, -2, -2,
66
5, 5, 5,-10,-10, 5, 5, 5,
67
0, 0, 0, 0, 0, 0, 0, 0}
70
static const int Passed[2][8] =
71
{ { 0, 48, 48, 120, 144, 192, 240, 0}, {0, 240, 192, 144, 120, 48, 48, 0} };
72
/* Penalties for one or more isolated pawns on a given file */
73
static const int isolani_normal[8] = {
74
-8, -10, -12, -14, -14, -12, -10, -8
76
/* Penalties if the file is half-open (i.e. no enemy pawns on it) */
77
static const int isolani_weaker[8] = {
78
-22, -24, -26, -28, -28, -26, -24, -22
81
static const BitBoard d2e2[2] =
82
{ ULL(0x0018000000000000), ULL(0x0000000000001800) };
83
static const BitBoard brank7[2] = { ULL(0x000000000000FF00),
84
ULL(0x00FF000000000000) };
85
static const BitBoard brank8[2] = { ULL(0x00000000000000FF),
86
ULL(0xFF00000000000000) };
87
static const BitBoard brank67[2] = { ULL(0x0000000000FFFF00),
88
ULL(0x00FFFF0000000000) };
89
static const BitBoard brank58[2] = { ULL(0x00000000FFFFFFFF),
90
ULL(0xFFFFFFFF00000000) };
92
int ScoreP (short side)
93
/***************************************************************************
95
* Pawn evaluation is based on the following factors (which is being
96
* constantly updated!).
98
* 1. Pawn square tables.
101
* 4. Pawn base under attack.
104
* 7. Connected passed pawns on 6/7th rank.
105
* 8. Unmoved & blocked d, e pawn
106
* 9. Passed pawn which cannot be caught.
109
***************************************************************************/
113
int n1, n2, backward;
116
BitBoard c, t, p, blocker, *e;
119
if (board.b[side][pawn] == NULLBITBOARD)
122
EnemyKing = board.king[xside];
123
p = board.b[xside][pawn];
124
c = t = board.b[side][pawn];
125
ptable = PawnTab[side] + (PawnHashKey & PHashMask);
127
if (ptable->phase == phase && ptable->pkey == KEY(PawnHashKey))
131
passed[side] = ptable->passed;
132
weaked[side] = ptable->weaked;
137
passed[side] = NULLBITBOARD;
138
weaked[side] = NULLBITBOARD;
139
memset (nfile, 0, sizeof (nfile));
144
s += PawnSq[side][sq];
147
if ((p & PassedPawnMask[side][sq]) == NULLBITBOARD)
149
if ((side == white && (FromToRay[sq][sq|56] & c) == 0) ||
150
(side == black && (FromToRay[sq][sq&7] & c) == 0))
152
passed[side] |= BitPosArray[sq];
153
s += (Passed[side][RANK(sq)] * phase) / 12;
159
/* i = sq + (side == white ? 8 : -8); */
160
if ( side == white ) {
165
if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(sq)] & c) &&
168
n1 = nbits (c & MoveArray[ptype[xside]][i]);
169
n2 = nbits (p & MoveArray[ptype[side]][i]);
173
if (!backward && (BitPosArray[sq] & brank7[xside]))
176
i = i + (side == white ? 8 : -8);
177
if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(i1)] & c))
179
n1 = nbits (c & MoveArray[ptype[xside]][i]);
180
n2 = nbits (p & MoveArray[ptype[side]][i]);
187
weaked[side] |= BitPosArray[sq];
191
/* Pawn base under attack */
192
if ((MoveArray[ptype[side]][sq] & p) && (MoveArray[ptype[side]][sq] & c))
195
/* Increment file count for isolani & doubled pawn evaluation */
199
for (i = 0; i <= 7; i++)
206
if (nfile[i] && (!(c & IsolaniMask[i])))
208
/* Isolated on a half-open file */
209
if (!(FileBit[i] & board.b[xside][pawn]))
210
s += isolani_weaker[i] * nfile[i];
211
else /* Normal isolated pawn */
212
s += isolani_normal[i] * nfile[i];
213
weaked[side] |= (c & FileBit[i]);
218
if (computerplays == side) {
220
/* Penalize having eight pawns */
221
if (nbits(board.b[computerplays][pawn]) == 8)
224
/* Detect stonewall formation in enemy */
225
if (nbits(stonewall[xside] & board.b[xside][pawn]) == 3)
231
n = nbits((c >> 8) & board.b[xside][pawn] &
234
n = nbits((c << 8) & board.b[xside][pawn] &
237
s += n * LOCKEDPAWNS;
241
/* Save the score into the pawn hash table */
242
ptable->pkey = KEY(PawnHashKey);
243
ptable->passed = passed[side];
244
ptable->weaked = weaked[side];
246
ptable->phase = phase;
248
/***************************************************************************
250
* This section of the pawn code cannot be saved into the pawn hash as
251
* they depend on the position of other pieces. So they have to be
254
***************************************************************************/
257
/* Pawn on f6/c6 with Queen against castled king is very strong */
258
c = board.b[side][pawn];
259
sq = board.king[xside];
260
if (side == white && board.b[side][queen] &&
261
(BitPosArray[C6] | BitPosArray[F6]) & c)
263
if (c & BitPosArray[F6] && sq > H6 && distance[sq][G7]==1)
265
if (c & BitPosArray[C6] && sq > H6 && distance[sq][B7]==1)
268
else if (side == black && board.b[side][queen] &&
269
(BitPosArray[C3] | BitPosArray[F3]) & c)
271
if (c & BitPosArray[F3] && sq < A3 && distance[sq][G2]==1)
273
if (c & BitPosArray[C3] && sq < A3 && distance[sq][B2]==1)
277
/* Connected passed pawns on 6th or 7th rank */
278
t = passed[side] & brank67[side];
279
if (t && (board.pmaterial[xside] == ValueR ||
280
(board.pmaterial[xside] == ValueN &&
281
pieces[xside] == board.b[xside][knight])))
283
n1 = ROW(board.king[xside]);
284
n2 = RANK(board.king[xside]);
285
for (i = 0; i <= 6; i++)
287
if (t & FileBit[i] && t & FileBit[i+1] && (n1 < i-1 || n1 > i+1 ||
288
(side == white && n2 < 4) || (side == black && n2 > 3)))
293
/* Pawn on d2,e2/d7,e7 is blocked */
294
blocker = board.friends[side] | board.friends[xside];
295
if (side == white && (((c & d2e2[white]) >> 8) & blocker))
297
if (side == black && (((c & d2e2[black]) << 8) & blocker))
300
/* Enemy has no pieces & King is outside of passed pawn square */
301
if (passed[side] && board.pmaterial[xside]==0)
304
i1 = board.king[xside];
310
if (board.side == side)
312
if (!(SquarePawnMask[side][sq] & board.b[xside][king]))
313
s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;
315
else if (!(MoveArray[king][i1] & SquarePawnMask[side][sq]))
316
s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;
320
/* If both sides are castled on different sides, bonus for pawn storms */
321
c = board.b[side][pawn];
322
if (abs (ROW (board.king[side]) - ROW (board.king[xside])) >= 4 &&
325
n1 = ROW (board.king[xside]);
326
p = (IsolaniMask[n1] | FileBit[n1]) & c;
331
s += 10 * (5 - distance[sq][board.king[xside]]);
338
static const int Outpost[2][64] =
340
{ 0, 0, 0, 0, 0, 0, 0, 0,
341
0, 0, 0, 0, 0, 0, 0, 0,
342
0, 0, 0, 0, 0, 0, 0, 0,
343
0, 0, 1, 1, 1, 1, 0, 0,
344
0, 1, 1, 1, 1, 1, 1, 0,
345
0, 0, 1, 1, 1, 1, 0, 0,
346
0, 0, 0, 1, 1, 0, 0, 0,
347
0, 0, 0, 0, 0, 0, 0, 0 },
348
{ 0, 0, 0, 0, 0, 0, 0, 0,
349
0, 0, 0, 1, 1, 0, 0, 0,
350
0, 0, 1, 1, 1, 1, 0, 0,
351
0, 1, 1, 1, 1, 1, 1, 0,
352
0, 0, 1, 1, 1, 1, 0, 0,
353
0, 0, 0, 0, 0, 0, 0, 0,
354
0, 0, 0, 0, 0, 0, 0, 0,
355
0, 0, 0, 0, 0, 0, 0, 0 }
359
static inline int CTL(short sq, short piece __attribute__ ((unused)), short side)
360
/***************************************************************************
362
* Return a score corresponding to the number of squares in the bitboard
363
* target multiplied by a specified bonus for controlling each square.
365
* Can be used for control of the center and attacks around the king.
367
***************************************************************************/
369
int s, n, EnemyKing, FriendlyKing;
374
EnemyKing = board.king[1^side];
375
FriendlyKing = board.king[side];
377
controlled = AttackXFrom (sq, side);
380
n = nbits (controlled & boxes[0]);
383
/* Attacks against enemy king */
384
n = nbits (controlled & DistMap[EnemyKing][2]);
387
/* Defenses for friendly king */
388
n = nbits (controlled & DistMap[FriendlyKing][2]);
392
n = nbits(controlled);
398
int ScoreN (short side)
399
/***************************************************************************
401
* 1. central knight - distance from enemy king.
402
* 2. mobility/control/attack
403
* 3. outpost knight protected by pawn.
404
* 4. knight attacking weak pawns.
406
***************************************************************************/
413
if (board.b[side][knight] == NULLBITBOARD)
417
c = board.b[side][knight];
418
t = board.b[xside][pawn];
419
EnemyKing = board.king[xside];
423
s += PINNEDKNIGHT * nbits(c & pinned);
432
s1 = CTL(sq,knight,side);
434
if ( (BitPosArray[sq] & rings[3]) != NULLBITBOARD)
437
if (Outpost[side][sq] &&
438
!(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]) )
442
/* Knight defended by own pawn */
443
if (MoveArray[ptype[xside]][sq] & board.b[side][pawn])
447
/* Attack on weak opponent pawns */
448
if (MoveArray[knight][sq] & weaked[xside])
458
int ScoreB (short side)
459
/****************************************************************************
462
* 2. mobility/control/attack
464
* 4. fianchetto bishop
467
****************************************************************************/
470
int s, s1, n, sq, EnemyKing;
473
if (board.b[side][bishop] == NULLBITBOARD)
476
c = board.b[side][bishop];
478
EnemyKing = board.king[xside];
480
t = board.b[xside][pawn];
484
s += PINNEDBISHOP * nbits(c & pinned);
494
s1 = CTL(sq,bishop,side);
497
if (Outpost[side][sq] &&
498
!(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]))
502
/* Bishop defended by own pawn */
503
if (MoveArray[ptype[xside]][sq] & board.b[side][pawn])
507
/* Fianchetto bishop */
510
if (board.king[side] >= F1 && board.king[side] <= H1 && sq == G2)
512
if (board.king[side] >= A1 && board.king[side] <= C1 && sq == B2)
515
else if (side == black)
517
if (board.king[side] >= F8 && board.king[side] <= H8 && sq == G7)
519
if (board.king[side] >= A8 && board.king[side] <= C8 && sq == B7)
523
/* Attack on weak opponent pawns */
524
if (BishopAttack(sq) & weaked[xside])
530
/* Doubled bishops */
539
int BishopTrapped (short side)
540
/****************************************************************************
542
* Check for bishops trapped at A2/H2/A7/H7
544
****************************************************************************/
548
/* Don't waste time */
549
if (board.b[side][bishop] == NULLBITBOARD)
554
if ((board.b[white][bishop] & BitPosArray[A7]) &&
555
(board.b[black][pawn] & BitPosArray[B6]) && SwapOff(MOVE(A7,B6)) < 0)
557
if ((board.b[white][bishop] & BitPosArray[H7]) &&
558
(board.b[black][pawn] & BitPosArray[G6]) && SwapOff(MOVE(H7,G6)) < 0)
563
if ((board.b[black][bishop] & BitPosArray[A2]) &&
564
(board.b[white][pawn] & BitPosArray[B3]) && SwapOff(MOVE(A2,B3)) < 0)
566
if ((board.b[black][bishop] & BitPosArray[H2]) &&
567
(board.b[white][pawn] & BitPosArray[G3]) && SwapOff(MOVE(H2,G3)) < 0)
574
int ScoreR (short side)
575
/****************************************************************************
577
* 1. rook on 7th rank and Enemy king on 8th rank or pawns on 7th rank.
578
* 2. rook on open/half-open file.
579
* 3. rook in front/behind passed pawns (pawn >= 5th rank)
581
****************************************************************************/
583
int s, s1, sq, xside, fyle, EnemyKing;
586
if (board.b[side][rook] == NULLBITBOARD)
589
c = board.b[side][rook];
591
EnemyKing = board.king[xside];
595
s += PINNEDROOK * nbits(c & pinned);
604
s1 = CTL(sq,rook,side);
609
if (!(board.b[side][pawn] & FileBit[fyle]))
611
if (fyle == 5 && ROW(board.king[xside])>=E_FILE)
614
if (!(board.b[xside][pawn] & FileBit[fyle]))
619
if (phase > 6 && (FileBit[fyle] & passed[white] & brank58[white]))
621
if (nbits (Ray[sq][7] & passed[white]) == 1)
623
else if (Ray[sq][4] & passed[white])
626
if (FileBit[fyle] & passed[black] & brank58[black])
628
if (nbits (Ray[sq][4] & passed[black]) == 1)
630
else if (Ray[sq][7] & passed[black])
634
/* Attack on weak opponent pawns */
635
if (RookAttack(sq) & weaked[xside])
638
/* Rook on 7th rank */
639
if (RANK (sq) == rank7[side] && (RANK (EnemyKing) == rank8[side] ||
640
board.b[xside][pawn] & RankBit[RANK(sq)]))
649
int DoubleQR7 (short side)
650
/***************************************************************************
652
* This code just check to see if there is a QQ or QR or RR combo on the
653
* 7th rank. This is very strong and given quite a big bonus. This
654
* routine is called by the lazy section.
656
***************************************************************************/
661
if (nbits ((board.b[side][queen]|board.b[side][rook]) & brank7[side]) > 1
662
&& ((board.b[xside][king] & brank8[side]) ||
663
(board.b[xside][pawn] & brank7[side])))
670
int ScoreQ (short side)
671
/***************************************************************************
673
* 1. queen centralization.
675
* 3. Bonus if opponent king is exposed.
677
***************************************************************************/
680
int s, s1, sq, EnemyKing;
685
/* Try to keep our queen on the board for attacking purposes. */
686
if (board.b[side][queen] == NULLBITBOARD) {
687
if (side == computer) {
688
s += QUEEN_NOT_PRESENT;
694
c = board.b[side][queen];
695
EnemyKing = board.king[xside];
699
s += PINNEDQUEEN * nbits(c & pinned);
708
s1 = CTL(sq,queen,side);
710
if (distance[sq][EnemyKing] <= 2)
713
/* Attack on weak opponent pawns */
714
if (QueenAttack(sq) & weaked[xside])
724
static const int KingSq[64] =
726
24, 24, 24, 16, 16, 0, 32, 32,
727
24, 20, 16, 12, 12, 16, 20, 24,
728
16, 12, 8, 4, 4, 8, 12, 16,
729
12, 8, 4, 0, 0, 4, 8, 12,
730
12, 8, 4, 0, 0, 4, 8, 12,
731
16, 12, 8, 4, 4, 8, 12, 16,
732
24, 20, 16, 12, 12, 16, 20, 24,
733
24, 24, 24, 16, 16, 0, 32, 32
736
static const int EndingKing[64] =
738
0, 6, 12, 18, 18, 12, 6, 0,
739
6, 12, 18, 24, 24, 18, 12, 6,
740
12, 18, 24, 32, 32, 24, 18, 12,
741
18, 24, 32, 48, 48, 32, 24, 18,
742
18, 24, 32, 48, 48, 32, 24, 18,
743
12, 18, 24, 32, 32, 24, 18, 12,
744
6, 12, 18, 24, 24, 18, 12, 6,
745
0, 6, 12, 18, 18, 12, 6, 0
748
static const int pawncover[9] = { -60, -30, 0, 5, 30, 30, 30, 30, 30 };
749
static const int factor[9] = { 7, 8, 8, 7, 6, 5, 4, 2, 0, };
751
int ScoreK (short side)
752
/***************************************************************************
754
* 1. king in the corner. ?? SRW 2002-08-02 Unclear if implemented
755
* 2. pawns around king.
756
* 3. king on open file.
758
* 5. Open rook file via Ng5 or Bxh7 sac.
759
* 6. No major or minor piece in the king's quadrant.
761
***************************************************************************/
764
int s, sq, sq1, n, n1, n2, file, fsq, rank;
769
sq = board.king[side];
772
KingSafety[side] = 0;
776
s += ((6 - phase) * KingSq[sq] + phase * EndingKing[sq]) / 6;
778
/* After castling kingside, reward having all 3 pawns in front but not if
779
there is a threatening pawn. This permits the freeing move F3/F6. */
782
n = nbits (MoveArray[king][sq] & board.b[side][pawn] & RankBit[rank+1]);
784
n = nbits (MoveArray[king][sq] & board.b[side][pawn] & RankBit[rank-1]);
787
/* Penalize compromised wing pawn formations prior to castle. */
788
if (!board.castled[side]) {
791
/* King on original square and unmoved */
792
if (sq == 4 && Mvboard[sq] == 0) {
793
/* Kingside - rook on original square and unmoved. */
794
if ( (board.b[side][rook] & BitPosArray[H1])!=NULLBITBOARD &&
796
n = nbits (MoveArray[king][G1] &
797
board.b[side][pawn] & RankBit[rank+1]);
799
if ( (board.b[side][rook] & BitPosArray[A1])!=NULLBITBOARD &&
801
n = nbits (MoveArray[king][C1] &
802
board.b[side][pawn] & RankBit[rank+1]);
805
if (sq == 60 && Mvboard[sq] == 0) {
807
if ( (board.b[side][rook] & BitPosArray[H8])!=NULLBITBOARD &&
809
n = nbits (MoveArray[king][G8] &
810
board.b[side][pawn] & RankBit[rank-1]);
812
if ( (board.b[side][rook] & BitPosArray[A8])!=NULLBITBOARD &&
814
n = nbits (MoveArray[king][C8] &
815
board.b[side][pawn] & RankBit[rank-1]);
819
/* Penalize breaking the wing pawn formations prior to castle */
820
if (n != -1) s += pawncover[n];
823
if (side == computer && file >= F_FILE &&
824
!(FileBit[G_FILE] & board.b[side][pawn]))
826
if (side == white && cboard[F2] == pawn)
828
else if (side == black && cboard[F7] == pawn)
832
/* No friendly pawns on this king file */
833
if (!(FileBit[file] & board.b[side][pawn]))
836
/* No enemy pawns on this king file */
837
if (!(FileBit[file] & board.b[xside][pawn]))
845
case G_FILE : if (!(FileBit[file+1] & board.b[side][pawn]))
847
if (!(FileBit[file+1] & board.b[xside][pawn]))
853
case B_FILE : if (!(FileBit[file-1] & board.b[side][pawn]))
855
if (!(FileBit[file-1] & board.b[xside][pawn]))
862
if (board.castled[side]) {
865
if (!(BitPosArray[F2] & board.b[side][pawn]) ||
866
!(BitPosArray[G2] & board.b[side][pawn]) ||
867
!(BitPosArray[H2] & board.b[side][pawn]) )
869
} else if (file < E_FILE) {
870
if (!(BitPosArray[A2] & board.b[side][pawn]) ||
871
!(BitPosArray[B2] & board.b[side][pawn]) ||
872
!(BitPosArray[C2] & board.b[side][pawn]) )
877
if (!(BitPosArray[F7] & board.b[side][pawn]) ||
878
!(BitPosArray[G7] & board.b[side][pawn]) ||
879
!(BitPosArray[H7] & board.b[side][pawn]) )
881
} else if (file < E_FILE) {
882
if (!(BitPosArray[A7] & board.b[side][pawn]) ||
883
!(BitPosArray[B7] & board.b[side][pawn]) ||
884
!(BitPosArray[C7] & board.b[side][pawn]) )
889
if (side == computer) {
891
/* Stock piece sacrifice on h file */
893
if (file >= E_FILE && board.b[xside][queen] && board.b[xside][rook] &&
894
!((board.b[side][pawn]|board.b[xside][pawn]) & FileBit[7]))
897
/* King trapping rook */
900
if (board.b[side][rook]&mask_kr_trapped_w[H_FILE-file]) {
903
} else if (file < D_FILE) {
904
if (board.b[side][rook]&mask_qr_trapped_w[file]) {
910
if (board.b[side][rook]&mask_kr_trapped_b[H_FILE-file]) {
913
} else if (file < D_FILE) {
914
if (board.b[side][rook]&mask_qr_trapped_b[file]) {
921
/* Don't give fianchetto target for advanced pawns */
922
if (file > E_FILE && ROW(board.king[xside]) < D_FILE) {
923
if (side == white) fsq = G3; else fsq = G6;
924
if ((BitPosArray[fsq] & board.b[side][pawn]) != NULLBITBOARD)
925
if (((BitPosArray[F4]|BitPosArray[H4]|
926
BitPosArray[F5]|BitPosArray[H5])
927
& board.b[xside][pawn]) != NULLBITBOARD)
928
s += FIANCHETTO_TARGET;
930
if (file < E_FILE && ROW(board.king[xside]) > E_FILE) {
931
if (side == white) fsq = B3; else fsq = B6;
932
if ((BitPosArray[fsq] & board.b[side][pawn]) != NULLBITBOARD)
933
if (((BitPosArray[A4]|BitPosArray[C4]|
934
BitPosArray[A5]|BitPosArray[C5])
935
& board.b[xside][pawn]) != NULLBITBOARD)
936
s += FIANCHETTO_TARGET;
939
/* No major/minor piece in king's quadrant */
940
/* First identify the quadrant */
941
x = boardhalf[side] & boardside[file<=D_FILE];
942
/* Now identify the number of non-pawn enemy in quadrant */
943
n1 = nbits(x & (board.friends[xside]));
945
/* Now identify the number of non-pawn friends in quadrant */
946
n2 = nbits(x & (board.friends[side] & ~board.b[side][pawn] &
947
~board.b[side][king]));
949
s += (n1 - n2) * KING_DEFENDER_DEFICIT;
952
KingSafety[side] = s;
953
s = (s * factor[phase]) / 8;
958
s += CTL(sq,king,side);
959
b = (board.b[white][pawn] | board.b[black][pawn]);
964
if (BitPosArray[sq1] & board.b[white][pawn])
965
s -= distance[sq][sq1+8] * 10 - 5;
966
else if (BitPosArray[sq1] & board.b[white][pawn])
967
s -= distance[sq][sq1-8] * 10 - 5;
969
s -= distance[sq][sq1] - 5;
972
/* Attack on weak opponent pawns */
973
if (MoveArray[king][sq] & weaked[xside])
974
s += ATAKWEAKPAWN * 2;
982
if (!(MoveArray[king][sq] & (~board.b[side][pawn] & RankBit[1])))
983
s += KING_BACK_RANK_WEAK;
986
if (!(MoveArray[king][sq] & (~board.b[side][pawn] & RankBit[6])))
987
s += KING_BACK_RANK_WEAK;
995
int LoneKing (int side, int loser)
996
/**************************************************************************
998
* One side has a lonely king and the other has no pawns, but enough
999
* mating material. We give an additional bonus of 150 points for the
1000
* winning side to attract the search to such positions.
1002
**************************************************************************/
1004
int s, winer, sq1, sq2;
1007
if (board.material[winer] == ValueB+ValueN &&
1008
nbits(board.b[winer][bishop]) == 1 &&
1009
nbits(board.b[winer][knight]) == 1)
1010
return (ScoreKBNK (side, loser));
1012
sq1 = board.king[winer];
1013
sq2 = board.king[loser];
1014
s = 150 - 6 * taxicab[sq1][sq2] - EndingKing[sq2];
1024
/**************************************************************************
1026
* A KPK endgame evaluator. Side is the one on the move.
1027
* This is not a perfect evaluator, it merely identifies SOME positions
1028
* as wins or draw. Some WON positions could be seen as draws; the search
1029
* will be able to use the knowledge here to identify more positions.
1031
**************************************************************************/
1033
int winer, loser, sq, sqw, sql;
1036
winer = (board.b[white][pawn] ? white : black);
1038
sq = leadz (board.b[winer][pawn]);
1039
sqw = board.king[winer];
1040
sql = board.king[loser];
1041
s = ValueP + (ValueQ * Passed[winer][RANK(sq)] / PFACTOR) +
1042
4 * (winer == white ? RANK(sqw) : 7-RANK(sqw));
1044
/**************************************************************************
1046
* Pawn is outside the square of the king
1048
**************************************************************************/
1049
if (~SquarePawnMask[winer][sq] & board.b[loser][king])
1051
if (!(MoveArray[king][sql] & SquarePawnMask[winer][sq]))
1052
return (winer == side ? s : -s);
1057
/**************************************************************************
1059
* Friendly king is on same or adjacent file to the pawn, and the pawn is
1060
* on a file other than a rook file and ...
1062
**************************************************************************/
1063
if (ROW(sq) != 0 && ROW(sq) != 7 &&
1064
((IsolaniMask[ROW(sq)] | FileBit[ROW(sq)]) & board.b[winer][king]))
1067
/**************************************************************************
1069
* a. friendly king is 2 ranks more advanced than the pawn
1070
* b. friendly king is 1 rank more advanced than the pawn
1071
* i. The friendly king is on the sixth rank.
1072
* ii. The enemy king does not have direct opposition by being 2 ranks
1073
* in front of the friendly king and on the same file.
1074
* c. friendly king is same rank as pawn
1075
* i. The enemy king is not 2-4 ranks more advanced that the pawn.
1076
* ii. The pawn is on the sixth rank and the enemy king does not have
1077
* direct opposition.
1078
* d. pawn is on the 7th rank, friendly king is on sixth rank and
1079
* i. The enemy king is not on the queening square.
1080
* ii. The enemy is on the queening square but both kings are in the same
1083
**************************************************************************/
1086
if (RANK(sqw) == RANK(sq) + 2)
1087
return (winer == side ? s : -s);
1088
if (RANK(sqw) == RANK(sq) + 1)
1091
return (winer == side ? s : -s);
1094
if (sqw+16 == sql && winer == side)
1097
return (winer == side ? s : -s);
1100
if (RANK(sqw) == RANK(sq))
1102
if ((RANK(sql) - RANK(sq) < 2 || RANK(sql) - RANK(sq) > 4) &&
1105
if ((RANK(sql) - RANK(sq) < 1 || RANK(sql) - RANK(sq) > 5) &&
1108
if (RANK(sq) == 5 && sqw+16 != sql)
1109
return (winer == side ? s : 0);
1111
if (RANK(sq) == 6 && RANK(sqw) == 5)
1114
return (winer == side ? s : 0);
1115
if (sql == sq+8 && sql == sqw+16)
1116
return (winer == side ? s : 0);
1121
if (RANK(sqw) == RANK(sq) - 2)
1122
return (winer == side ? s : -s);
1123
if (RANK(sqw) == RANK(sq) - 1)
1126
return (winer == side ? s : -s);
1129
if (sqw-16 == sql && winer == side)
1132
return (winer == side ? s : -s);
1135
if (RANK(sqw) == RANK(sq))
1137
if ((RANK(sq) - RANK(sql) < 2 || RANK(sq) - RANK(sql) > 4) &&
1140
if ((RANK(sq) - RANK(sql) < 1 || RANK(sq) - RANK(sql) > 5) &&
1143
if (RANK(sq) == 5 && sqw+16 != sql)
1144
return (winer == side ? s : 0);
1146
if (RANK(sq) == 1 && RANK(sqw) == 2)
1149
return (winer == side ? s : 0);
1150
if (sql == sq-8 && sql == sqw-16)
1151
return (winer == side ? s : 0);
1162
0, 10, 20, 30, 40, 50, 60, 70,
1163
10, 20, 30, 40, 50, 60, 70, 60,
1164
20, 30, 40, 50, 60, 70, 60, 50,
1165
30, 40, 50, 60, 70, 60, 50, 40,
1166
40, 50, 60, 70, 60, 50, 40, 30,
1167
50, 60, 70, 60, 50, 40, 30, 20,
1168
60, 70, 60, 50, 40, 30, 20, 10,
1169
70, 60, 50, 40, 30, 20, 10, 0
1172
int ScoreKBNK (int side, int loser)
1173
/****************************************************************************
1175
* My very own KBNK routine!
1177
****************************************************************************/
1179
int s, winer, sq1, sq2, sqB;
1182
sqB = board.king[loser];
1183
if (board.b[winer][bishop] & WHITESQUARES)
1184
sqB = RANK(sqB)*8 + 7 - ROW(sqB);
1185
sq1 = board.king[winer];
1186
sq2 = board.king[loser];
1187
s = 300 - 6 * taxicab[sq1][sq2];
1189
s -= EndingKing[sq2];
1190
s -= taxicab[leadz(board.b[winer][knight])][sq2];
1191
s -= taxicab[leadz(board.b[winer][bishop])][sq2];
1193
/* King in the central 4x4 region is good! */
1194
if (board.b[winer][king] & ULL(0x00003C3C3C3C0000))
1204
static const BitBoard nn[2] = { ULL(0x4200000000000000), ULL(0x0000000000000042) };
1205
static const BitBoard bb[2] = { ULL(0x2400000000000000), ULL(0x0000000000000024) };
1207
int ScoreDev (short side)
1208
/***************************************************************************
1210
* Calculate the development score for side (for opening only).
1211
* Penalize the following.
1212
* . Uncastled and cannot castled
1213
* . Undeveloped knights and bishops
1214
* . Early queen move.
1216
***************************************************************************/
1222
/* Calculate whether we are developed */
1223
c = (board.b[side][knight] & nn[side]) | (board.b[side][bishop] & bb[side]);
1226
/* If we are castled or beyond the 20th move, no more ScoreDev */
1227
if (board.castled[side] || GameCnt >= 38)
1232
/* If the king is moved, nail it, otherwise check rooks */
1233
if (Mvboard[board.king[side]] > 0)
1236
/* Discourage rook moves */
1237
c = board.b[side][rook];
1241
if (Mvboard[sq] > 0)
1245
/* Penalize a queen that moves at all */
1246
if (board.b[side][queen])
1248
sq = leadz (board.b[side][queen]);
1249
if (Mvboard[sq] > 0)
1250
s += EARLYQUEENMOVE;
1251
/* s += Mvboard[sq] * EARLYQUEENMOVE; */
1254
/* Discourage repeat minor piece moves */
1255
c = board.b[side][knight] | board.b[side][bishop];
1259
if (Mvboard[sq] > 1)
1260
s += EARLYMINORREPEAT;
1261
/* s += Mvboard[sq] * EARLYMINORREPEAT; */
1264
/* Discourage any wing pawn moves */
1265
/* c = board.b[side][pawn] & (FileBit[0]|FileBit[1]|FileBit[6]|FileBit[7]); */
1266
c = board.b[side][pawn] & ULL(0xc3c3c3c3c3c3c3c3);
1270
if (Mvboard[sq] > 0)
1271
s += EARLYWINGPAWNMOVE;
1274
/* Discourage any repeat center pawn moves */
1275
/* c = board.b[side][pawn] & (FileBit[2]|FileBit[3]|FileBit[4]|FileBit[5]); */
1276
c = board.b[side][pawn] & ULL(0x3c3c3c3c3c3c3c3c);
1280
if (Mvboard[sq] > 1)
1281
s += EARLYCENTERPREPEAT;
1288
/* Array of pointer to functions */
1289
static int (*ScorePiece[7]) (short) =
1290
{ NULL, ScoreP, ScoreN, ScoreB, ScoreR, ScoreQ, ScoreK };
1293
int Evaluate (int alpha, int beta)
1294
/****************************************************************************
1296
* First check to see if this position can be specially dealt with.
1297
* E.g. if our bounds indicate that we are looking for a mate score,
1298
* then just return the material score. Nothing else is important.
1299
* If its a KPK endgame, call our KPK routine.
1300
* If one side has a lone king & the winning side has no pawns then call
1301
* the LoneKing() mating driver routine. Note that there is enough
1302
* mating material as we have already check for insufficient mating material
1303
* in the call to EvaluateDraw() in search()/quiesce().
1305
****************************************************************************/
1308
int piece, s, s1, score;
1315
/* If we are looking for a MATE, just return the material */
1316
if (alpha > MATE-255 || beta < -MATE+255)
1319
/* A KPK endgame. */
1320
if (board.material[white]+board.material[black] == ValueP)
1321
return (KPK (side));
1323
/* One side has a lone king and other side has no pawns */
1324
if (board.material[xside] == 0 && board.b[side][pawn] == NULLBITBOARD)
1325
return LoneKing (side, xside);
1326
if (board.material[side] == 0 && board.b[xside][pawn] == NULLBITBOARD)
1327
return LoneKing (side, side);
1329
/****************************************************************************
1331
* Lets try a lazy evaluation. In this stage, we should evaluate all those
1332
* features that gives big bonus/penalties. E.g. squares around king is
1333
* attacked by enemy pieces, 2 rooks on 7th rank, runaway passed pawns etc.
1334
* This will be the direction, so things will continue to change in this
1337
****************************************************************************/
1341
pieces[white] = b[knight] | b[bishop] | b[rook] | b[queen];
1342
npiece[white] = nbits (pieces[white]);
1344
pieces[black] = b[knight] | b[bishop] | b[rook] | b[queen];
1345
npiece[black] = nbits (pieces[black]);
1348
if ((s1 + maxposnscore[side] < alpha || s1 - maxposnscore[xside] > beta) &&
1355
s += ScoreDev (side) - ScoreDev (xside);
1356
s += ScoreP (side) - ScoreP (xside);
1357
s += ScoreK (side) - ScoreK (xside);
1358
s += BishopTrapped (side) - BishopTrapped (xside);
1359
s += DoubleQR7 (side) - DoubleQR7 (xside);
1363
/**************************************************************************
1365
* See if we can have a lazy evaluation cut. Otherwise its a slow eval.
1367
**************************************************************************/
1369
if (s1 + lazyscore[side] < alpha || s1 - lazyscore[side] > beta)
1378
s1 = HUNGPENALTY * ( EvalHung(side) - EvalHung(xside) );
1381
for (piece = knight; piece < king; piece++)
1383
s1 += (*ScorePiece[piece]) (side) - (*ScorePiece[piece]) (xside);
1385
lazyscore[side] = MAX (s1, lazyscore[side]);
1386
maxposnscore[side] = MAX (maxposnscore[side], s + s1);
1387
score = s + s1 + MATERIAL;
1390
/***************************************************************************
1392
* Trade down bonus code. When ahead, trade pieces & not pawns;
1394
***************************************************************************/
1396
if (MATERIAL >= 200)
1398
score += (RootPieces - nbits(pieces[white] | pieces[black])) * TRADEPIECE;
1399
score -= (RootPawns - nbits(board.b[white][pawn] | board.b[black][pawn]))
1402
else if (MATERIAL <= -200)
1404
score -= (RootPieces - nbits(pieces[white] | pieces[black])) * TRADEPIECE;
1405
score += (RootPawns - nbits(board.b[white][pawn] | board.b[black][pawn]))
1409
/***************************************************************************
1411
* Opposite color bishops is drawish.
1413
***************************************************************************/
1414
if (ENDING && pieces[white] == board.b[white][bishop] &&
1415
pieces[black] == board.b[black][bishop] &&
1416
((pieces[white] & WHITESQUARES && pieces[black] & BLACKSQUARES) ||
1417
(pieces[white] & BLACKSQUARES && pieces[black] & WHITESQUARES)))
1422
/***************************************************************************
1424
* When one side has no mating material, then his score can never be > 0.
1426
***************************************************************************/
1427
if (score > 0 && !board.b[side][pawn] && (board.material[side] < ValueR
1428
|| pieces[side] == board.b[side][knight]))
1430
if (score < 0 && !board.b[xside][pawn] && (board.material[xside] < ValueR
1431
|| pieces[xside] == board.b[xside][knight]))
1438
short EvaluateDraw (void)
1439
/***************************************************************************
1441
* This routine is called by search() and quiesce() before anything else
1442
* is done. Its purpose it to check if the current position is a draw.
1444
* 1. If there are any pawns, it is not.
1445
* 2. If both sides has anything less than a rook, draw.
1446
* 3. If both sides has <= 2 knights only, draw.
1447
* 4. If its a KBBK and bishops of same color, draw.
1449
***************************************************************************/
1455
* Exception - if we are close to a pawn move, promotion
1456
* or capture it is possible a forced mate will follow.
1457
* So we assume not drawn for 2 moves.
1460
if ( (GameCnt-Game50) < 5 )
1464
if ( (GameCnt-Game50) > 100 )
1469
if (w[pawn] != 0 || b[pawn] != 0)
1472
wm = board.material[white];
1473
bm = board.material[black];
1474
wn = nbits (w[knight]);
1475
bn = nbits (b[knight]);
1476
if ((wm<ValueR || (wm==2*ValueN && wn==2)) &&
1477
(bm<ValueR || (bm==2*ValueN && bn==2)))
1482
if (bm == 2*ValueB &&
1483
( nbits(board.b[black][bishop] & WHITESQUARES) == 2 ||
1484
nbits(board.b[black][bishop] & BLACKSQUARES) == 2 ))
1489
if (wm == 2*ValueB &&
1490
( nbits(board.b[white][bishop] & WHITESQUARES) == 2 ||
1491
nbits(board.b[white][bishop] & BLACKSQUARES) == 2 ))