GNU Shogi 1.1p02
[gnushogi.git] / src / eval.c
blob95dd3aa23ef2c7b580a00a439e221ec3defb8fe6
1 /*
2 * eval.c - C source for GNU SHOGI
4 * Copyright (c) 1993 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU Shogi.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 1, or (at your option)
16 * any later version.
18 * GNU Shogi is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Shogi; see the file COPYING. If not, write to
25 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "gnushogi.h"
29 #ifdef USE_PATTERN
30 #include "pattern.h"
31 #endif
34 #ifdef CACHE
35 etable_field *etab[2];
36 #endif
39 const small_short Stboard[NO_SQUARES] =
40 {lance,knight,silver,gold,king,gold,silver,knight,lance,
41 0, bishop, 0, 0, 0, 0, 0, rook, 0,
42 pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
43 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
47 0, rook, 0, 0, 0, 0, 0, bishop, 0,
48 lance,knight,silver,gold,king,gold,silver,knight,lance};
50 const small_short Stcolor[NO_SQUARES] =
51 {black, black, black, black, black, black, black, black, black,
52 neutral, black, neutral, neutral, neutral, neutral, neutral, black, neutral,
53 black, black, black, black, black, black, black, black, black,
54 neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
55 neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
56 neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
57 white, white, white, white, white, white, white, white, white,
58 neutral, white, neutral, neutral, neutral, neutral, neutral, white, neutral,
59 white, white, white, white, white, white, white, white, white};
61 small_short board[NO_SQUARES], color[NO_SQUARES];
64 int EADD = 0;
65 int EGET = 0;
66 int PUTVAR = false;
69 #ifdef DEBUG_EVAL
70 extern short debug_eval;
71 extern FILE *debug_eval_file;
72 #endif
75 static short in_opening_stage = true;
76 static short behind_in_material[2] = {false, false};
79 /* distance to enemy king */
80 static const EnemyKingDistanceBonus[9] =
81 {0, 20, 15, 8, 5, 3, 1, 0, 0};
83 /* distance to own king */
84 static const OwnKingDistanceBonus[9] =
85 {0, 10, 4, 1, 0, 0, 0, 0, 0};
87 /* distance to promotion zone */
88 static const PromotionZoneDistanceBonus[NO_ROWS] =
89 {0, 0, 0, 0, 4, 8, 10, 10, 10};
91 /* Bishop mobility bonus indexed by # reachable squares */
92 static const short BMBLTY[20] =
93 {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
95 /* Rook mobility bonus indexed by # reachable squares */
96 static const short RMBLTY[20] =
97 {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
99 /* Lance mobility bonus indexed by # reachable squares */
100 static const short LMBLTY[8] =
101 {0, 0, 0, 0, 1, 2, 4, 8};
104 /* penalty for threats to king, indexed by number of such threats */
105 static const short KTHRT[36] =
106 {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
107 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
108 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
111 #if !defined USE_PATTERN
113 /* Pawn positional bonus (STATIC ROOK vs. STATIC ROOK) */
114 static const small_short PawnAdvanceSS[NO_SQUARES] =
115 { 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 3, -2, 15, 4, 6, 1, 6, 8, 3,
119 0, -5, -5, 0, 0, 0, 5, 10, 5,
120 0, 0, 0, 0, 0, 0, 0, 0, 10,
121 0, 0, 0, 0, 0, 0, 0, 0, 0,
122 0, 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0, 0 };
125 #define PawnAdvanceSR PawnAdvanceSS
127 /* Pawn positional bonus (RANGING ROOK vs. STATIC ROOK) */
128 static const small_short PawnAdvanceRS[NO_SQUARES] =
129 { 0, 0, 0, 0, 0, 0, 0, 0, 0,
130 0, 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0, 0,
132 3, -2, 15, 3, 5, 0, -2, -4, 3,
133 1, 0, 8, 3, 5, 2, 2, -2, -2,
134 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0 };
139 #define PawnAdvanceRR PawnAdvanceRS
141 /* Lance positional bonus (STATIC ROOK vs. STATIC ROOK) */
142 static small_short LanceAdvanceSS[NO_SQUARES] =
143 { 10, 5, 5, 5, 5, 5, 5, 5, 10,
144 2, 4, 4, 4, 4, 4, 4, 4, 2,
145 4, 1, 1, 1, 1, 1, 1, 1, 4,
146 -2, -2, -2, -2, -2, -2, -2, -2, -2,
147 -4, -4, -4, -4, -4, -4, -4, -4, -4,
148 -6, -6, -6, -6, -6, -6, -6, -6, -6,
149 -8, -8, -8, -8, -8, -8, -8, -8, -8,
150 -9, -9, -9, -9, -9, -9, -9, -9, -9,
151 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* impossible */
153 #define LanceAdvanceSR LanceAdvanceSS
154 #define LanceAdvanceRS LanceAdvanceSS
155 #define LanceAdvanceRR LanceAdvanceRS
157 /* Knight positional bonus (STATIC ROOK vs. STATIC ROOK) */
158 static small_short KnightAdvanceSS[NO_SQUARES] =
159 {-9, 4, 4, 4, 4, 4, 4, 4,-9,
160 -9, 2, 2, 2, 2, 2, 2, 2,-9,
161 -9, 1,-10, 1, 1, 1, 1, 1,-9,
162 -9, 0, 0, 0, 0, 0, 0, 0,-9,
163 -9, -5, 0, -5, 0,-5, 0,-5,-9
164 -9, 0, 0, 0, 0, 0, 0, 0,-9,
165 -9, -9, -9, -9,-9,-9,-9,-9,-9,
166 0, 0, 0, 0, 0, 0, 0, 0, 0, /* impossible */
167 0, 0, 0, 0, 0, 0, 0, 0, 0 };/* impossible */
169 #define KnightAdvanceSR KnightAdvanceSS
170 #define KnightAdvanceRS KnightAdvanceSS
171 #define KnightAdvanceRR KnightAdvanceRS
173 /* Silver positional bonus (STATIC ROOK vs. STATIC ROOK) */
174 static small_short SilverAdvanceSS[NO_SQUARES] =
175 { 0, 0, 0, 0, -6, 0, 0, 0, 0,
176 0, 8, 3, 4, 0, 3, 2, 0, 0,
177 0, 0, 10, 0, 0, 6, 6, 4, 0,
178 0, 0, 0, 0, 4, 0, 4, 5, 0,
179 0, 0, 0, 0, 0, 0, 0, 0, 0,
180 0, 0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0, 0,
182 0, 0, 0, 0, 0, 0, 0, 0, 0,
183 0, 0, 0, 0, 0, 0, 0, 0, 0 };
185 /* Silver positional bonus (STATIC ROOK vs. RANGING ROOK) */
186 static small_short SilverAdvanceSR[NO_SQUARES] =
187 { 0, 0, 0, 0, -6, 0, 0, 0, 0,
188 0, -4, -4, 4, 0, 5, 3, 0, 0,
189 0, 0, -4, -4, 2, 8, 6, 0, 0,
190 0, 0, 0, 3, 0, 0, 4, 0, 0,
191 0, 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0, 0,
193 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0, 0 };
197 /* Silver positional bonus (RANGING ROOK vs. STATIC ROOK) */
198 static small_short SilverAdvanceRS[NO_SQUARES] =
199 { -3, 0, 0, 0, 0, 0, 0, 0, -2,
200 -3, -1, 3, 3, -1, -1, 8, -1, -2,
201 -2, -2, 0, 5, -1, 9, -2, 5, -3,
202 0, 0, 5, 2, 5, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, 0, 0, 0, 0, 0, 0, 0,
206 0, 0, 0, 0, 0, 0, 0, 0, 0,
207 0, 0, 0, 0, 0, 0, 0, 0, 0 };
209 #define SilverAdvanceRR SilverAdvanceRS
211 /* Gold positional bonus (STATIC ROOK vs. STATIC ROOK) */
212 static small_short GoldAdvanceSS[NO_SQUARES] =
213 { 0, 0, 0, 0, 0, 0, 0, 0, 0,
214 0, 0, 10, 0, 6, 0, 0, 0, 0,
215 0, 0, 0, 8, 0, 0, 0, 0, 0,
216 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0,
220 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0 };
223 /* Gold positional bonus (STATIC ROOK vs. RANGING ROOK) */
224 static small_short GoldAdvanceSR[NO_SQUARES] =
225 { 0, 0, 0, 10, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 6, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 0, 0, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0, 0 };
235 /* Gold positional bonus (RANGING ROOK vs. STATIC ROOK) */
236 static small_short GoldAdvanceRS[NO_SQUARES] =
237 { -1, 0, -1, 0, -1, 0, -1, -1, -1,
238 -1, 0, 4, -1, 4, -1, 8, 0, -1,
239 -2, -1, 0, -2, 0, 6, 0, -1, -2,
240 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0 };
247 #define GoldAdvanceRR GoldAdvanceRS
249 /* Bishop positional bonus (STATIC ROOK vs. STATIC ROOK) */
250 static small_short BishopAdvanceSS[NO_SQUARES] =
251 { 3, 0, 0, 0, 0, 0, 0, 0, 3,
252 0, 4, 0, 8, 0, 0, 0, 3, 0,
253 0, 0, 6, 0, 0, 0, 4, 0, 0,
254 0, 2, 0, 3, 0, 3, 0, 2, 0,
255 0, 0, 2, 0, 3, 0, 0, 0, 0,
256 0, 2, 0, 3, 0, 3, 0, 2, 0,
257 0, 0, 3, 0, 0, 0, 3, 0, 0,
258 0, 3, 0, 0, 0, 0, 0, 3, 0,
259 3, 0, 0, 0, 0, 0, 0, 0, 3 };
261 /* Bishop positional bonus (STATIC ROOK vs. RANGING ROOK) */
262 static small_short BishopAdvanceSR[NO_SQUARES] =
263 { 3, 0, 0, 0, 0, 0, 0, 0, 3,
264 0, 10, 0, 2, 0, 0, 0, 3, 0,
265 0, 0, 2, 0, 0, 0, 4, 0, 0,
266 0, 2, 0, 3, 0, 3, 0, 2, 0,
267 0, 0, 2, 0, 3, 0, 0, 0, 0,
268 0, 2, 0, 3, 0, 3, 0, 2, 0,
269 0, 0, 3, 0, 0, 0, 3, 0, 0,
270 0, 3, 0, 0, 0, 0, 0, 3, 0,
271 3, 0, 0, 0, 0, 0, 0, 0, 3 };
273 /* Bishop positional bonus (RANGING ROOK vs. STATIC ROOK) */
274 static small_short BishopAdvanceRS[NO_SQUARES] =
275 { 3, 0, 0, 0, 0, 0, 0, 0, 3,
276 0, 4, 0, 2, 0, 0, 0, 3, 0,
277 0, 0, 8, 0, 0, 0, 4, 0, 0,
278 0, 2, 0, 3, 0, 3, 0, 2, 0,
279 0, 0, 2, 0, 3, 0, 0, 0, 0,
280 0, 2, 0, 3, 0, 3, 0, 2, 0,
281 0, 0, 3, 0, 0, 0, 3, 0, 0,
282 0, 3, 0, 0, 0, 0, 0, 3, 0,
283 3, 0, 0, 0, 0, 0, 0, 0, 3 };
285 #define BishopAdvanceRR BishopAdvanceRS
287 /* Rook positional bonus (STATIC ROOK vs. STATIC ROOK) */
288 static small_short RookAdvanceSS[NO_SQUARES] =
289 { 2, 0, 0, 0, 0, 0, 0, 4, 2,
290 2, 0, 0, 0, 0, 0, 0, 8, 2,
291 -2, 0, 0, 0, 0, 0, 0, 2, -2,
292 -2, 0, 0, 0, 0, 0, 0, 4, -2,
293 -2, 0, 0, 0, 0, 0, 0, 2, -2,
294 -2, 0, 0, 0, 0, 0, 0, 2, -2,
295 4, 4, 4, 4, 4, 4, 4, 4, 4,
296 6, 6, 6, 6, 6, 6, 6, 6, 6,
297 8, 8, 8, 8, 8, 8, 8, 8, 8 };
299 /* Rook positional bonus (RANING ROOK vs. STATIC ROOK) */
300 static small_short RookAdvanceRS[NO_SQUARES] =
301 { 2, 6, 6, 6, 6, 0, 0, 0, 2,
302 2, 4, 4, 4, 4, 0, 0, 0, 2,
303 -2, 2, 3, 3, 3, 0, 0, 0, -2,
304 -2, 4, 1, 1, 1, 0, 0, 0, -2,
305 -2, 0, 2, 2, 2, 0, 0, 0, -2,
306 -2, 0, 0, 0, 0, 0, 0, 0, -2,
307 4, 4, 4, 4, 4, 4, 4, 4, 4,
308 6, 6, 6, 6, 6, 6, 6, 6, 6,
309 8, 8, 8, 8, 8, 8, 8, 8, 8 };
311 #define RookAdvanceSR RookAdvanceSS
312 #define RookAdvanceRR RookAdvanceRS
314 /* King positional bonus inopening stage (STATIC ROOK vs. STATIC ROOK) */
315 static const small_short KingAdvanceSS[NO_SQUARES] =
316 { 0, -4, 10, 0, -6, -8,-10,-12,-12,
317 -2, 4, 6, -6, -8, -8,-10,-12,-12,
318 -6, -6, -6, -8, -8,-10,-11,-12,-12,
319 -12,-12,-12,-12,-12,-12,-12,-12,-12,
320 -12,-12,-12,-12,-12,-12,-12,-12,-12,
321 -12,-12,-12,-12,-12,-12,-12,-12,-12,
322 -12,-12,-12,-12,-12,-12,-12,-12,-12,
323 -12,-12,-12,-12,-12,-12,-12,-12,-12,
324 -12,-12,-12,-12,-12,-12,-12,-12,-12 };
326 /* King positional bonus inopening stage (STATIC ROOK vs. RANGING ROOK) */
327 static const small_short KingAdvanceSR[NO_SQUARES] =
328 { 5, -4, -4, -4, -6, -8,-10,-12,-12,
329 -2, 4, 10, 6, -8, -8,-10,-12,-12,
330 -6, -6, -6, -8, -8,-10,-11,-12,-12,
331 -12,-12,-12,-12,-12,-12,-12,-12,-12,
332 -12,-12,-12,-12,-12,-12,-12,-12,-12,
333 -12,-12,-12,-12,-12,-12,-12,-12,-12,
334 -12,-12,-12,-12,-12,-12,-12,-12,-12,
335 -12,-12,-12,-12,-12,-12,-12,-12,-12,
336 -12,-12,-12,-12,-12,-12,-12,-12,-12 };
338 /* King positional bonus inopening stage (RANGING ROOK vs. STATIC ROOK) */
339 static const small_short KingAdvanceRS[NO_SQUARES] =
340 {-12,-12, -8, -6, -4, -8,-10,-12,-12,
341 -12,-12, -8, -6, -8, 12, 16, 20, -8,
342 -12,-12, -6, -8, -8,-10, 0, 0, -4,
343 -12,-12,-12,-12,-12,-12, 0, 0,-12,
344 -12,-12,-12,-12,-12,-12,-12,-12,-12,
345 -12,-12,-12,-12,-12,-12,-12,-12,-12,
346 -12,-12,-12,-12,-12,-12,-12,-12,-12,
347 -12,-12,-12,-12,-12,-12,-12,-12,-12,
348 -12,-12,-12,-12,-12,-12,-12,-12,-12 };
350 #define KingAdvanceRR KingAdvanceRS
352 #endif /* !USE_PATTERN */
355 static small_short Kfield[2][NO_SQUARES];
357 char GameType[2] = { UNKNOWN, UNKNOWN };
359 #ifdef USE_PATTERN
360 OpeningPattern *attack_pattern[2], *castle_pattern[2];
361 #endif
363 #if defined USE_PATTERN
366 static small_short Mpawn[2][NO_SQUARES];
367 static small_short Msilver[2][NO_SQUARES];
368 static small_short Mgold[2][NO_SQUARES];
369 static small_short Mking[2][NO_SQUARES];
370 static small_short Mlance[2][NO_SQUARES];
371 static small_short Mknight[2][NO_SQUARES];
372 static small_short Mbishop[2][NO_SQUARES];
373 static small_short Mrook[2][NO_SQUARES];
375 static Mpiece_array Mpawn, Mlance, Mknight, Msilver, Mgold,
376 Mbishop, Mrook, Mking;
378 Mpiece_array *Mpiece[NO_PIECES] =
379 { NULL, &Mpawn, &Mlance, &Mknight, &Msilver, &Mgold, &Mbishop, &Mrook,
380 &Mgold, &Mgold, &Mgold, &Mgold, &Mbishop, &Mrook, &Mking };
382 #else
384 static small_short Mpawn[2][NO_SQUARES];
385 static small_short Msilver[2][NO_SQUARES];
386 static small_short Mgold[2][NO_SQUARES];
387 static small_short Mking[2][NO_SQUARES];
389 static small_short *Mlance[2];
390 static small_short *Mknight[2];
391 static small_short *Mbishop[2];
392 static small_short *Mrook[2];
394 #endif
396 static short c1, c2;
397 static small_short *PC1, *PC2;
399 static long *atk1, *atk2;
401 static long int atak[2][NO_SQUARES];
403 #if defined USE_PATTERN
405 short ADVNCM[NO_PIECES];
407 #else
409 static short PADVNCM, SADVNCM, GADVNCM, KADVNCM;
411 #endif
413 static short R2NDCOL, EDRNK2B, PWEAKH, PAWNSHIELD;
414 static short NEDGE;
415 static short PMBLTY, BDCLOSED, PSTRONG, P2STRONG;
417 static short PawnBonus, BishopBonus, RookBonus;
418 static short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
419 static short RHOPN, RHOPNX, BHCLSD, BHCLSDX, KHOPN, KHOPNX, KSFTY;
421 static short LHOPN, LHOPNX, LPROTECT, NDNGR, LDNGR;
422 static short SBEFOREG, BXCHG;
423 static short LXRAY, BRXRAY;
424 static short KINGED, KINGOD, PROMD;
426 static short KCASTLD, KMOVD, OPENOK, OPENWRONG;
427 static short ATAKD, HUNGP, HUNGX, PINVAL;
429 #ifdef USE_PATTERN
430 static short PATTACK, PCASTLE;
431 #endif
434 short pscore[2];
438 #if defined DEBUG8 || defined DEBUG_EVAL
441 void
442 debug_position (FILE *D)
444 short r, c, l, side, piece;
446 fprintf (D, "\n current board is\n\n");
447 for (piece = pawn; piece <= king; piece++)
448 if (c = Captured[white][piece])
449 fprintf(D, "%i%c ",c,pxx[piece]);
450 fprintf (D, "\n");
451 for (c = 0; c < NO_COLS; c++)
452 fprintf (D, " %d", PawnCnt[white][c]);
453 fprintf (D, "\n\n");
454 for (r = (NO_ROWS-1); r >= 0; r--)
456 for (c = 0; c < NO_COLS; c++)
458 l = locn (r, c);
459 if (color[l] == neutral)
460 fprintf (D, " -");
461 else if (color[l] == black)
462 fprintf (D, " %c", qxx[board[l]]);
463 else
464 fprintf (D, " %c", pxx[board[l]]);
466 fprintf (D, "\n");
468 fprintf (D, "\n");
469 for (c = 0; c < NO_COLS; c++)
470 fprintf (D, " %d", PawnCnt[black][c]);
471 fprintf (D, "\n");
472 for (piece = pawn; piece <= king; piece++)
473 if (c = Captured[black][piece])
474 fprintf(D, "%i%c ",c,pxx[piece]);
475 fprintf(D, "\n");
479 #if !defined SAVE_SVALUE
481 void
482 debug_svalue (FILE *D)
484 short r, c;
486 for (r = (NO_ROWS-1); r >= 0; r--)
488 for (c = 0; c < NO_COLS; c++)
490 short sq = (r * NO_COLS) + c;
491 fprintf(D,"%5d",svalue[sq]);
493 fprintf (D, "\n");
495 fprintf (D, "\n");
498 #endif
500 void
501 debug_table (FILE *D, small_short *table)
503 short r, c;
505 for (r = (NO_ROWS-1); r >= 0; r--)
507 for (c = 0; c < NO_COLS; c++)
509 short sq = (r * NO_COLS) + c;
510 fprintf(D,"%5d",table[sq]);
512 fprintf (D, "\n");
514 fprintf (D, "\n");
517 void
518 debug_ataks (FILE *D)
520 short side;
521 for (side = black; side <= white; side++)
523 short l,c,i;
524 long *atk = atak[side];
525 fprintf(D, "\n");
526 for (l = NO_ROWS-1; l >= 0; l--) {
527 for (c = 0; c < NO_COLS; c++) {
528 short sq = (l * NO_COLS) + c;
529 long v = atk[sq];
530 short n = (short)(v & CNT_MASK);
531 char s[20];
532 fprintf(D,"%2d",n);
533 strcpy(s,"");
534 if ( v & ctlP ) strcat(s,"P");
535 if ( v & ctlPp ) strcat(s,"+P");
536 if ( v & ctlL ) strcat(s,"L");
537 if ( v & ctlLp ) strcat(s,"+L");
538 if ( v & ctlN ) strcat(s,"N");
539 if ( v & ctlNp ) strcat(s,"+N");
540 if ( v & ctlS ) strcat(s,"S");
541 if ( v & ctlSp ) strcat(s,"+S");
542 if ( v & ctlG ) strcat(s,"G");
543 if ( v & ctlB ) strcat(s,"B");
544 if ( v & ctlBp ) strcat(s,"+B");
545 if ( v & ctlR ) strcat(s,"R");
546 if ( v & ctlRp ) strcat(s,"+R");
547 if ( v & ctlK ) strcat(s,"K");
548 fprintf(D,s);
549 for (i = strlen(s); i < 5; i++)
550 fprintf(D," ");
551 fprintf(D," ");
553 fprintf(D,"\n");
555 fprintf(D, "\n");
559 #endif
563 /* ............ POSITIONAL EVALUATION ROUTINES ............ */
566 * Inputs are:
567 * mtl[side] - value of all material
568 * hung[side] - count of hung pieces
569 * Tscore[ply] - search tree score for ply ply
570 * Pscore[ply] - positional score for ply ply
571 * INCscore - bonus score or penalty for certain moves
572 * Sdepth - search goal depth
573 * xwndw - evaluation window about alpha/beta
574 * EWNDW - second evaluation window about alpha/beta
575 * ChkFlag[ply]- checking piece at level ply or 0 if no check
576 * TesujiFlag[ply]- 1 if tesuji move at level ply or 0 if no tesuji
577 * PC1[column] - # of my pawns in this column
578 * PC2[column] - # of opponents pawns in column
579 * PieceCnt[side] - just what it says
585 evaluate (register short int side,
586 register short int ply,
587 register short int alpha,
588 register short int beta,
589 short int INCscore,
590 short int *InChk) /* output Check flag */
593 * Compute an estimate of the score by adding the positional score from the
594 * previous ply to the material difference. If this score falls inside a
595 * window which is 180 points wider than the alpha-beta window (or within a
596 * 50 point window during quiescence search) call ScorePosition() to
597 * determine a score, otherwise return the estimated score.
598 * "side" has to moved.
602 register short evflag, xside;
603 short s, sq, blockable;
605 xside = side ^ 1;
606 s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
608 #ifdef DEBUG_EVAL
609 if ( debug_eval )
610 fprintf (debug_eval_file, "estimated score at ply %d:%d, -%d+%d-%d-%d\n",
611 ply, s, Pscore[ply-1], mtl[side], mtl[xside], INCscore );
612 #endif
614 hung[black] = hung[white] = 0;
616 /* should we use the estimete or score the position */
618 #if !defined OLD_EVALUATE
619 if ( ply == 1 ||
620 (ply == Sdepth) ||
621 (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30))) ||
622 #else
623 if ( ply <= Sdepth ||
624 ((ply == Sdepth + 1 || ply == (Sdepth + 2)) && (s > (alpha - xwndw) && s < (beta + xwndw))) ||
625 (ply > (Sdepth + 2) && s >= (alpha - EWNDW) && s <= (beta + EWNDW)) ||
626 #endif
627 #ifdef CACHE
628 (CheckEETable (side)) )
629 #endif
631 { short sq;
632 /* score the position */
633 #ifdef DEBUG_EVAL
634 if ( debug_eval )
635 fprintf (debug_eval_file, "do NOT use the estimete\n");
636 #endif
637 ataks (side, atak[side]);
638 if (Anyatak (side, sq=PieceList[xside][0]) && board[sq] == king) {
639 *InChk = (board[sq=PieceList[side][0]] == king) ? SqAtakd (sq, xside, &blockable) : false;
640 return ((SCORE_LIMIT+1001) - ply);
642 ataks (xside, atak[xside]);
643 *InChk = (board[sq=PieceList[side][0]] == king) ? Anyatak (xside, sq) : false;
644 #ifndef BAREBONES
645 EvalNodes++;
646 #endif
647 #if !defined OLD_EVALUATE
648 if ( ply > 4 )
649 #endif
650 PUTVAR=true;
651 s = ScorePosition (side);
652 PUTVAR = false;
654 else
656 /* use the estimate but look at check */
657 short sq;
658 #ifdef DEBUG_EVAL
659 if ( debug_eval )
660 fprintf (debug_eval_file, "use the estimete\n");
661 #endif
662 *InChk = (board[sq=PieceList[side][0]] == king) ? SqAtakd (sq, xside, &blockable) : false;
663 if ( SqAtakd (sq=PieceList[xside][0], side, &blockable) && board[sq] == king ) {
664 return ((SCORE_LIMIT+1001) - ply);
668 Pscore[ply] = s - mtl[side] + mtl[xside];
669 ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
670 return (s);
673 inline
675 BRLscan (register short int sq, short int *mob)
678 * Find (promoted) Bishop, (promoted) Rook, and Lance mobility, XRAY attacks, and pins.
679 * Let BRL be the bishop, rook, or lance.
680 * Let P be the first piece (no king and no pawn) in a direction and let Q be the second
681 * piece in the same direction. If Q is an unprotected opponent's piece with
682 * bigger relative value than BRL, there is a pin if P is an opponent's piece and
683 * there is an XRAY attack if P is an own piece.
684 * Increment the hung[] array if a pin is found.
687 #ifdef SAVE_NEXTPOS
688 short d;
689 #else
690 register unsigned char *ppos, *pdir;
691 #endif
692 register short s, mobx;
693 register short u, pin, ptyp;
694 short piece, rvalue;
695 small_short *Kf;
696 mobx = s = 0;
697 Kf = Kfield[c1];
698 piece = board[sq];
700 rvalue = relative_value[piece];
701 ptyp = ptype[c1][unpromoted[piece]];
702 #ifdef SAVE_NEXTPOS
703 u = first_direction(ptyp,&d,sq);
704 #else
705 ppos = (*nextpos[ptyp])[sq];
706 pdir = (*nextdir[ptyp])[sq];
707 u = ppos[sq];
708 #endif
709 pin = -1; /* start new direction */
712 s += Kf[u];
713 #ifdef DEBUG_EVAL
714 if ( debug_eval && Kf[u] != 0 )
715 fprintf(debug_eval_file,"add %d for controlling square near enemy king\n",Kf[u]);
716 #endif
717 if (color[u] == neutral)
719 #ifdef SAVE_NEXTPOS
720 short xu, dd = d;
721 xu = next_position(ptyp,&d,sq,u);
722 if ( xu == next_direction(ptyp,&dd,sq) )
723 pin = -1; /* oops new direction */
724 u = xu;
725 #else
726 if (ppos[u] == pdir[u])
727 pin = -1; /* oops new direction */
728 u = ppos[u];
729 #endif
730 mobx++;
732 else
733 { /* there is a piece in current direction */
734 if (pin < 0)
735 { /* it's the first piece in the current direction */
736 if (piece == lance && color[u] == c1 )
738 if ( board[u] == pawn )
740 s += LPROTECT;
741 #ifdef DEBUG_EVAL
742 if ( debug_eval )
743 fprintf(debug_eval_file,"adding %d for lance protection\n",LPROTECT);
744 #endif
746 else if ( in_opening_stage )
748 s -= 2*LPROTECT;
749 #ifdef DEBUG_EVAL
750 if ( debug_eval )
751 fprintf(debug_eval_file,"adding %d for lance protection\n",-2*LPROTECT);
752 #endif
755 else if ( piece == bishop && board[u] == pawn )
757 if ( color[u] == c1 )
759 s += 2*BHCLSD;
760 #ifdef DEBUG_EVAL
761 if (debug_eval )
762 fprintf(debug_eval_file,"add %d for own pawn in bishops direction\n",2*BHCLSD);
763 #endif
765 else
767 s += 2*BHCLSDX;
768 #ifdef DEBUG_EVAL
769 if (debug_eval )
770 fprintf(debug_eval_file,"add %d for opponents pawn in bishops direction\n",2*BHCLSDX);
771 #endif
774 if (board[u] == pawn || board[u] == king)
775 #ifdef SAVE_NEXTPOS
776 u = next_direction(ptyp,&d,sq);
777 #else
778 u = pdir[u];
779 #endif
780 else
782 #ifdef SAVE_NEXTPOS
783 short xu, dd = d;
784 xu = next_position(ptyp,&d,sq,u);
785 if ( xu != next_direction(ptyp,&dd,sq) )
786 pin = u; /* not on the edge and on to find a pin */
787 u = xu;
788 #else
789 if (ppos[u] != pdir[u])
790 pin = u; /* not on the edge and on to find a pin */
791 u = ppos[u];
792 #endif
795 else
797 /* it's the second piece in the current direction */
798 if ( piece == bishop && board[u] == pawn )
800 if ( color[u] == c1 )
802 s += BHCLSD;
803 #ifdef DEBUG_EVAL
804 if (debug_eval )
805 fprintf(debug_eval_file,"add %d for own pawn in bishops (2) direction\n",BHCLSD);
806 #endif
808 else
810 s += BHCLSDX;
811 #ifdef DEBUG_EVAL
812 if (debug_eval )
813 fprintf(debug_eval_file,"add %d for opponents pawn in bishops (2) direction\n",BHCLSDX);
814 #endif
817 if ((color[u] == c2) &&
818 (relative_value[board[u]] > rvalue || atk2[u] == 0))
820 if (color[pin] == c2)
822 s += PINVAL;
823 #ifdef DEBUG_EVAL
824 if ( debug_eval )
825 fprintf(debug_eval_file,"adding %d for pin\n",PINVAL);
826 #endif
827 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
828 ++hung[c2];
830 else
831 if ( piece == lance ) {
832 s += LXRAY;
833 #ifdef DEBUG_EVAL
834 if ( debug_eval )
835 fprintf(debug_eval_file,"lance xray: %d\n",LXRAY);
836 #endif
837 } else {
838 s += BRXRAY;
839 #ifdef DEBUG_EVAL
840 if ( debug_eval )
841 fprintf(debug_eval_file,"bishop/rook xray: %d\n",BRXRAY);
842 #endif
845 pin = -1; /* new direction */
846 #ifdef SAVE_NEXTPOS
847 u = next_direction(ptyp,&d,sq);
848 #else
849 u = pdir[u];
850 #endif
854 while (u != sq);
855 *mob = mobx;
856 return s;
861 #define ctlSG (ctlS | ctlG | ctlPp | ctlLp | ctlNp | ctlSp)
864 inline
865 short int
866 KingScan (register short int sq)
869 * Assign penalties if king can be threatened by checks, if squares near the
870 * king are controlled by the enemy (especially by promoted pieces),
871 * or if there are no own generals near the king.
872 * The following must be true:
873 * board[sq] == king, c1 == color[sq], c2 == otherside[c1]
877 #define ScoreThreat \
878 { if (color[u] != c2)\
879 if (atk1[u] == 0 || (atk2[u] & CNT_MASK) > 1) {\
880 ++cnt;\
882 else s -= 3;\
887 register short cnt;
888 #ifdef SAVE_NEXTPOS
889 short d;
890 #else
891 register unsigned char *ppos, *pdir;
892 #endif
893 register short int s;
894 register short u, ptyp;
895 short int ok;
896 #ifdef DEBUG_EVAL
897 short s0;
898 #endif
900 /* Penalties, if a king can be threatened by checks. */
902 s = 0;
903 cnt = 0;
904 { short p;
905 for ( p = pawn; p < king; p++ )
906 if ( HasPiece[c2][p] || Captured[c2][p] )
907 { short ptyp;
908 /* if a c1 piece can reach u from sq,
909 * then a c2 piece can reach sq from u.
910 * That means, each u is a square, from which a
911 * piece of type p and color c2 threats square sq.
913 ptyp = ptype[c1][p];
914 #ifdef SAVE_NEXTPOS
915 u = first_direction(ptyp,&d,sq);
916 #else
917 ppos = (*nextpos[ptyp])[sq];
918 pdir = (*nextdir[ptyp])[sq];
919 u = ppos[sq];
920 #endif
923 /* If a p piece can reach (controls or can drop to)
924 * square u, then score threat.
926 if (atk2[u] & control[p])
927 ScoreThreat
928 else if (Captured[c2][p] && color[u] == neutral)
929 ScoreThreat
930 #ifdef SAVE_NEXTPOS
931 u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
932 : next_direction(ptyp,&d,sq));
933 #else
934 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
935 #endif
937 while (u != sq);
940 s += (KSFTY * KTHRT[cnt]) / 16;
942 #ifdef DEBUG_EVAL
943 s0 = s;
944 if (debug_eval )
945 fprintf(debug_eval_file,"penalty %d for possible king threats\n",
946 s0);
947 #endif
949 /* Penalties, if squares near king are controlled by enemy. */
951 cnt = 0;
952 ok = false;
953 ptyp = ptype[black][king];
954 #ifdef SAVE_NEXTPOS
955 u = first_direction(ptyp,&d,sq);
956 #else
957 pdir = (*nextpos[ptyp])[sq];
958 u = pdir[sq];
959 #endif
962 if ( !ok && color[u] == c1 )
964 short ptype_piece = ptype[c1][board[u]];
965 if ( ptype_piece == ptype_silver || ptype_piece == ptype_gold )
966 ok = true;
968 if (atk2[u] > atk1[u])
970 ++cnt;
971 if (atk2[u] & ctlSG)
972 s -= 3;
974 #ifdef SAVE_NEXTPOS
975 u = next_direction(ptyp,&d,sq);
976 #else
977 u = pdir[u];
978 #endif
980 while (u != sq);
981 if (!ok)
982 s -= KSFTY;
983 if (cnt > 1)
984 s -= KSFTY;
986 #ifdef DEBUG_EVAL
987 if (debug_eval )
988 fprintf(debug_eval_file,"penalty %d for squares near king controlled by enemy\n",
989 s-s0);
990 #endif
992 return (s);
995 inline
997 trapped (register short int sq)
1000 * See if the attacked piece has unattacked squares to move to. The following
1001 * must be true: c1 == color[sq] c2 == otherside[c1]
1005 register short u, ptyp;
1006 #ifdef SAVE_NEXTPOS
1007 short d;
1008 #else
1009 register unsigned char *ppos, *pdir;
1010 #endif
1011 register short int piece;
1012 short rvalue;
1014 piece = board[sq];
1015 rvalue = relative_value[piece];
1016 ptyp = ptype[c1][piece];
1017 #ifdef SAVE_NEXTPOS
1018 u = first_direction(ptyp,&d,sq);
1019 #else
1020 ppos = (*nextpos[ptyp])[sq];
1021 pdir = (*nextdir[ptyp])[sq];
1022 u = ppos[sq];
1023 #endif
1024 do {
1025 if (color[u] != c1)
1026 if (atk2[u] == 0 || relative_value[board[u]] >= rvalue)
1027 return (false);
1028 #ifdef SAVE_NEXTPOS
1029 u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
1030 : next_direction(ptyp,&d,sq));
1031 #else
1032 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1033 #endif
1034 } while (u != sq);
1035 #ifdef DEBUG_EVAL
1036 if ( debug_eval )
1037 fprintf(debug_eval_file,"piece is trapped\n");
1038 #endif
1039 return (true);
1044 #define mirrored(sq) (NO_SQUARES-1-sq)
1045 #define csquare(side,sq) ((side==black)?sq:mirrored(sq))
1046 #define crow(side,sq) row(csquare(side,sq))
1047 #define ccolumn(side,sq) column(csquare(side,sq))
1050 inline
1051 static short on_csquare(short side,short piece,short square)
1052 { short sq;
1053 return(board[sq=csquare(side,square)]==piece && color[sq]==side);
1056 inline
1057 static short on_column(short side,short piece,short c)
1058 { short sq;
1059 for (sq = c; sq < NO_SQUARES; sq+=9)
1060 if (on_csquare(side,piece,sq))
1061 return(true);
1062 return(false);
1065 #define empty_csquare(side,square) (board[csquare(side,square)]==no_piece)
1067 inline
1068 static short on_left_side(short side,short piece)
1069 { short c;
1070 for (c=0; c<4; c++)
1071 if (on_column(side,piece,c))
1072 return(true);
1073 return(false);
1076 inline
1077 static short on_right_side(short side,short piece)
1078 { short c;
1079 for (c=5; c<NO_COLS; c++)
1080 if (on_column(side,piece,c))
1081 return(true);
1082 return(false);
1086 /* Distance bonus */
1088 inline
1089 static
1090 short AddEnemyKingDistanceBonus (short sq)
1091 { short s = 0;
1092 /* near enemy king */
1093 if ( !in_opening_stage || behind_in_material[c1] )
1094 if ( distance(sq,OwnKing) > 2 )
1095 s = EnemyKingDistanceBonus[distance(sq,EnemyKing)];
1096 return(s);
1099 inline
1100 static
1101 short AddOwnKingDistanceBonus (short sq)
1102 { short s = 0;
1103 /* near own king */
1104 if ( !in_opening_stage || behind_in_material[c1] )
1105 s = OwnKingDistanceBonus[distance(sq,OwnKing)];
1106 return(s);
1109 inline
1110 static
1111 short AddPromotionZoneDistanceBonus (short sq)
1112 { short s = 0;
1113 /* near promotion zone */
1114 if ( !in_opening_stage )
1115 s = PromotionZoneDistanceBonus[crow(c1,sq)];
1116 return(s);
1120 static inline int
1121 PawnValue (register short int sq, short int side)
1123 * Calculate the positional value for a pawn on 'sq'.
1127 register short s;
1128 short n;
1129 long a1, a2;
1131 #if defined USE_PATTERN
1132 s = Mpawn[c1][sq] + 2*crow(c1,sq);
1133 #else
1134 s = Mpawn[c1][csquare(c1,sq)] + 2*crow(c1,sq);
1135 #endif
1137 #ifdef DEBUG_EVAL
1138 if ( debug_eval )
1139 fprintf(debug_eval_file,"inital value [%d] for pawn on %c%c: %d\n",
1140 csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
1141 #endif
1143 s += PROMD * AddPromotionZoneDistanceBonus(sq);
1145 /* pawn mobility */
1147 short u, ptyp = ptype[c1][pawn];
1148 #ifdef SAVE_NEXTPOS
1149 short d;
1150 u = first_direction(ptyp,&d,sq);
1151 #else
1152 register unsigned char *pdir;
1153 pdir = (*nextdir[ptyp])[sq];
1154 u = pdir[sq];
1155 #endif
1156 if ( u != sq )
1157 if ( color[u] == neutral ) {
1158 s += PMBLTY;
1159 #ifdef DEBUG_EVAL
1160 if ( debug_eval )
1161 fprintf(debug_eval_file,"adding %d for mobility\n", PMBLTY);
1162 #endif
1166 a1 = atk1[sq];
1167 a2 = atk2[sq];
1169 if (a2 > 0)
1171 if (a1 == 0 || a2 > ctlP + 1)
1173 s += HUNGP;
1174 #ifdef DEBUG_EVAL
1175 if ( debug_eval )
1176 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
1177 #endif
1178 if (trapped (sq)) {
1179 hung[c1] += 2;
1181 hung[c1]++;
1183 else if (a2 > a1) {
1184 s += ATAKD;
1185 #ifdef DEBUG_EVAL
1186 if ( debug_eval )
1187 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
1188 #endif
1192 if ( a1 > 0 ) {
1193 s += (a1 & CNT_MASK);
1194 #ifdef DEBUG_EVAL
1195 if ( debug_eval )
1196 fprintf(debug_eval_file,"adding %ld for protected piece\n",(a1 & CNT_MASK));
1197 #endif
1200 if ( sq == csquare(c1,20) ) {
1201 s += BDCLOSED;
1202 #ifdef DEBUG_EVAL
1203 if ( debug_eval )
1204 fprintf(debug_eval_file,"adding %d for closed bishops diagonal\n",BDCLOSED);
1205 #endif
1208 if ( (a1 & ((ctlR | ctlRp) | ctlL)) ) {
1209 s += PSTRONG;
1210 #ifdef DEBUG_EVAL
1211 if ( debug_eval )
1212 fprintf(debug_eval_file,"adding %d for rook/lance-supported pawn\n", PSTRONG);
1213 #endif
1216 if ( in_opening_stage ) {
1218 if ( crow(c1,sq) == 2 ) /* pawn on 3d rank */
1219 if ( Mvboard[(c1==black)?(sq+36):(sq-36)] )
1220 { /* opposing pawn has been moved (even column == (sq & 1)) */
1221 s -= (sq & 1) ? (3*PMBLTY/2) : (2*PMBLTY);
1222 #ifdef DEBUG_EVAL
1223 if ( debug_eval )
1224 fprintf(debug_eval_file,"adding %d for opposing pawn pushed\n",
1225 ((sq & 1) ? -(3*PMBLTY/2) : -(2*PMBLTY)));
1226 #endif
1229 if ( GameType[c1] == STATIC_ROOK && sq == csquare(c1,43) )
1230 if ( (atk2[csquare(c1,52)] & CNT_MASK) < 2 )
1232 s += P2STRONG;
1233 #ifdef DEBUG_EVAL
1234 if ( debug_eval )
1235 fprintf(debug_eval_file,"adding %d for attacking pawn on 2nd col\n",
1236 P2STRONG);
1237 #endif
1240 if ( GameType[c2] == STATIC_ROOK && ccolumn(c1,sq) == 1 )
1242 if ( sq == csquare(c1,28) )
1244 s -= P2STRONG;
1245 #ifdef DEBUG_EVAL
1246 if ( debug_eval )
1247 fprintf(debug_eval_file,"adding %d for pushed pawn on 8th file\n",
1248 -P2STRONG);
1249 #endif
1251 if ( (atk1[csquare(c1,19)] & CNT_MASK) < 2 && (atk1[csquare(c1,28)] & CNT_MASK) < 2 )
1253 s -= 2*P2STRONG;
1254 #ifdef DEBUG_EVAL
1255 if ( debug_eval )
1256 fprintf(debug_eval_file,"adding %d for weak pawn on 8th col\n",
1257 -2*P2STRONG);
1258 #endif
1263 return (s);
1267 static inline int
1268 LanceValue (register short int sq, short int side)
1270 * Calculate the positional value for a lance on 'sq'.
1274 register short s;
1275 register short fyle, rank;
1276 short mob;
1277 short checked_trapped = false;
1278 long a1, a2;
1280 #if defined USE_PATTERN
1281 s = Mlance[c1][sq];
1282 #else
1283 s = Mlance[c1][csquare(c1,sq)];
1284 #endif
1286 #ifdef DEBUG_EVAL
1287 if ( debug_eval )
1288 fprintf(debug_eval_file,"inital value [%d] for lance on %c%c: %d\n",
1289 csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
1290 #endif
1292 s += KINGOD * AddOwnKingDistanceBonus(sq);
1294 s += BRLscan (sq, &mob);
1295 s += LMBLTY[mob];
1297 fyle = column(sq);
1298 rank = crow(c1,sq);
1300 if (PC1[fyle] == 0)
1302 s += LHOPN;
1303 #ifdef DEBUG_EVAL
1304 if ( debug_eval )
1305 fprintf(debug_eval_file,"adding %d for no own pawn on lance file\n",LHOPN);
1306 #endif
1308 if (PC2[fyle] == 0)
1310 s += LHOPNX;
1311 #ifdef DEBUG_EVAL
1312 if ( debug_eval )
1313 fprintf(debug_eval_file,"adding %d for no opponents pawn on lance file\n",LHOPNX);
1314 #endif
1317 a2 = atk2[sq];
1318 a1 = atk1[sq];
1320 if (a2 > 0)
1322 if (a1 == 0 || a2 > ctlL + 1)
1324 s += HUNGP;
1325 #ifdef DEBUG_EVAL
1326 if ( debug_eval )
1327 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
1328 #endif
1329 if (trapped (sq))
1330 hung[c1] += 2;
1331 hung[c1]++;
1333 else if (a2 >= ctlL || a1 < ctlP)
1335 s += ATAKD;
1336 #ifdef DEBUG_EVAL
1337 if ( debug_eval )
1338 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
1339 #endif
1343 if ( !checked_trapped && rank > 2 )
1345 if (in_opening_stage || trapped (sq))
1347 s += LDNGR;
1348 #ifdef DEBUG_EVAL
1349 if ( debug_eval )
1350 fprintf(debug_eval_file,"adding %d for lance in danger\n",LDNGR);
1351 #endif
1353 else
1355 s += LDNGR / 2;
1356 #ifdef DEBUG_EVAL
1357 if ( debug_eval )
1358 fprintf(debug_eval_file,"adding %d for lance in danger\n",LDNGR / 2);
1359 #endif
1363 if ( a1 > 0 ) {
1364 s += (a1 & CNT_MASK);
1365 #ifdef DEBUG_EVAL
1366 if ( debug_eval )
1367 fprintf(debug_eval_file,"adding %ld for protected piece\n",(a1 & CNT_MASK));
1368 #endif
1371 return (s);
1374 static inline int
1375 KnightValue (register short int sq, short int side)
1377 * Calculate the positional value for a knight on 'sq'.
1381 register short s;
1382 long a1, a2;
1383 short checked_trapped = false;
1384 short c = column(sq);
1386 #if defined USE_PATTERN
1387 s = Mknight[c1][sq];
1388 #else
1389 s = Mknight[c1][csquare(c1,sq)];
1390 #endif
1392 #ifdef DEBUG_EVAL
1393 if ( debug_eval )
1394 fprintf(debug_eval_file,"inital value [%d] for knight on %c%c: %d\n",
1395 csquare(c1,sq), cxx[c], rxx[row(sq)], s);
1396 #endif
1398 s += PROMD * AddPromotionZoneDistanceBonus(sq);
1399 s += KINGOD * AddOwnKingDistanceBonus(sq);
1401 a2 = atk2[sq];
1402 a1 = atk1[sq];
1404 if (a2 > 0)
1406 if (a1 == 0 || a2 > ctlN + 1)
1408 s += HUNGP;
1409 #ifdef DEBUG_EVAL
1410 if ( debug_eval )
1411 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
1412 #endif
1413 checked_trapped = true;
1414 if (trapped (sq))
1415 hung[c1] += 2;
1416 hung[c1]++;
1418 else if (a2 >= ctlN || a1 < ctlP)
1420 s += ATAKD;
1421 #ifdef DEBUG_EVAL
1422 if ( debug_eval )
1423 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
1424 #endif
1428 if ( !checked_trapped && crow(c1,sq) > 2 )
1430 if (trapped (sq))
1432 s += NDNGR;
1433 #ifdef DEBUG_EVAL
1434 if ( debug_eval )
1435 fprintf(debug_eval_file,"adding %d for knight in danger\n",NDNGR);
1436 #endif
1438 else
1440 s += NDNGR / 4;
1441 #ifdef DEBUG_EVAL
1442 if ( debug_eval )
1443 fprintf(debug_eval_file,"adding %d for knight in danger\n",NDNGR / 4);
1444 #endif
1448 if ( c == 0 || c == 8 ) {
1449 s += NEDGE;
1450 #ifdef DEBUG_EVAL
1451 if ( debug_eval )
1452 fprintf(debug_eval_file,"adding %d for knight on edge file\n",NEDGE);
1453 #endif
1456 if ( a1 > 0 ) {
1457 s += (a1 & CNT_MASK);
1458 #ifdef DEBUG_EVAL
1459 if ( debug_eval )
1460 fprintf(debug_eval_file,"adding %ld for protected piece\n",(a1 & CNT_MASK));
1461 #endif
1464 return (s);
1467 static inline int
1468 SilverValue (register short int sq, short int side)
1470 * Calculate the positional value for a silver on 'sq'.
1474 register short s;
1475 long a1, a2;
1477 #if defined USE_PATTERN
1478 s = Msilver[c1][sq];
1479 #else
1480 s = Msilver[c1][csquare(c1,sq)];
1481 #endif
1483 s += KINGED * AddEnemyKingDistanceBonus(sq);
1484 s += KINGOD * AddOwnKingDistanceBonus(sq);
1486 a2 = atk2[sq];
1487 a1 = atk1[sq];
1488 if (a2 > 0)
1490 if (a1 == 0 || a2 > ctlS + 1)
1492 s += HUNGP;
1493 if (trapped (sq))
1494 hung[c1] += 2;
1495 hung[c1]++;
1497 else if (a2 >= ctlS || a1 < ctlP)
1498 s += ATAKD;
1500 if ( a1 > 0 )
1501 s += (a1 & CNT_MASK);
1503 if ( in_opening_stage && GameType[c1] == STATIC_ROOK )
1504 if ( csquare(c1,sq) == 12 )
1506 short csq;
1507 if ( board[csq = csquare(c1,20)] == bishop && color[csq] == c1 )
1509 s += 2 * OPENWRONG;
1513 /* proverb: silver before gold */
1515 short u, ptyp = ptype[c2][pawn];
1516 #ifdef SAVE_NEXTPOS
1517 short d;
1518 u = first_direction(ptyp,&d,sq);
1519 #else
1520 register unsigned char *pdir;
1521 pdir = (*nextdir[ptyp])[sq];
1522 u = pdir[sq];
1523 #endif
1524 if ( u != sq )
1525 if ( color[u] == c1 && board[u] == gold )
1526 s += SBEFOREG;
1528 return (s);
1531 static inline int
1532 GoldValue (register short int sq, short int side)
1534 * Calculate the positional value for a gold on 'sq'.
1538 register short s;
1539 long a1, a2;
1541 #if defined USE_PATTERN
1542 s = Mgold[c1][sq];
1543 #else
1544 s = Mgold[c1][csquare(c1,sq)];
1545 #endif
1547 s += KINGED * AddEnemyKingDistanceBonus(sq);
1548 s += KINGOD * AddOwnKingDistanceBonus(sq);
1550 a2 = atk2[sq];
1551 a1 = atk1[sq];
1552 if (a2 > 0)
1554 if (a1 == 0 || a2 > ctlG + 1)
1556 s += HUNGP;
1557 if (trapped (sq))
1558 hung[c1] += 2;
1559 hung[c1]++;
1561 else if (a2 >= ctlG || a1 < ctlP)
1562 s += ATAKD;
1564 if ( a1 > 0 )
1565 s += (a1 & CNT_MASK);
1567 if ( in_opening_stage &&
1568 GameType[c1] == STATIC_ROOK && GameType[c2] != STATIC_ROOK )
1569 if ( Mvboard[csquare(c1,3)] )
1571 s += 2 * OPENWRONG;
1575 return (s);
1578 static inline int
1579 BishopValue (register short int sq, short int side)
1581 * Calculate the positional value for a bishop on 'sq'.
1585 register short s;
1586 long a2, a1;
1587 short mob;
1589 #if defined USE_PATTERN
1590 s = Mbishop[c1][sq];
1591 #else
1592 s = Mbishop[c1][csquare(c1,sq)];
1593 #endif
1595 #ifdef DEBUG_EVAL
1596 if (debug_eval )
1597 fprintf(debug_eval_file,"inital value [%d] for bishop on %c%c: %d\n",
1598 csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
1599 #endif
1601 s += BRLscan (sq, &mob);
1602 s += BMBLTY[mob];
1604 a2 = atk2[sq];
1605 if (a2 > 0)
1607 a1 = atk1[sq];
1608 if (a1 == 0 || a2 > ctlB + 1)
1610 s += HUNGP;
1611 #ifdef DEBUG_EVAL
1612 if ( debug_eval )
1613 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
1614 #endif
1615 if (trapped (sq))
1616 hung[c1] += 2;
1617 hung[c1]++;
1619 else if (a2 >= ctlB || a1 < ctlP)
1621 s += ATAKD;
1622 #ifdef DEBUG_EVAL
1623 if ( debug_eval )
1624 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
1625 #endif
1629 if ( in_opening_stage )
1631 if ( GameType[c1] == RANGING_ROOK )
1633 /* Bishops diagonal should not be open */
1634 if ( !on_csquare(c1,pawn,30) )
1635 s += OPENWRONG;
1637 else if ( GameType[c2] == RANGING_ROOK )
1639 /* Bishops diagonal should be open */
1640 if ( csquare(c1,sq) == 10 &&
1641 (!empty_csquare(c1,20) || !empty_csquare(c1,30)) )
1642 s += OPENWRONG;
1643 else if ( csquare(c1,sq) == 20 && !empty_csquare(c1,30) )
1644 s += OPENWRONG;
1648 return (s);
1651 static inline int
1652 RookValue (register short int sq, short int side)
1654 * Calculate the positional value for a rook on 'sq'.
1658 register short s;
1659 register short fyle;
1660 long a2, a1;
1661 short mob, r, c;
1663 #if defined USE_PATTERN
1664 s = Mrook[c1][sq];
1665 #else
1666 s = Mrook[c1][csquare(c1,sq)];
1667 #endif
1669 #ifdef DEBUG_EVAL
1670 if (debug_eval )
1671 fprintf(debug_eval_file,"inital value [%d] for rook on %c%c: %d\n",
1672 csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
1673 #endif
1675 s += BRLscan (sq, &mob);
1676 s += RMBLTY[mob];
1678 #ifdef DEBUG_EVAL
1679 if ( debug_eval && (c = RMBLTY[mob]) != 0 ) {
1680 s += c;
1681 fprintf(debug_eval_file,"adding rook for mobility %d value %d\n",mob,c);
1683 #endif
1685 fyle = column (sq);
1687 if (PC1[fyle] == 0) {
1688 s += RHOPN; /* no own pawn on rook file */
1689 #ifdef DEBUG_EVAL
1690 if ( debug_eval )
1691 fprintf(debug_eval_file,"adding %d for no own pawn on rook file\n",RHOPN);
1692 #endif
1694 if (PC2[fyle] == 0) {
1695 s += RHOPNX; /* no enemy pawn on rook file */
1696 #ifdef DEBUG_EVAL
1697 if ( debug_eval )
1698 fprintf(debug_eval_file,"adding %d for no enemy pawn on rook file\n",RHOPNX);
1699 #endif
1702 a2 = atk2[sq];
1703 if (a2 > 0)
1705 a1 = atk1[sq];
1706 if (a1 == 0 || a2 > ctlR + 1)
1708 s += HUNGP;
1709 #ifdef DEBUG_EVAL
1710 if ( debug_eval )
1711 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
1712 #endif
1713 if (trapped (sq)) {
1714 hung[c1] += 2;
1716 hung[c1]++;
1718 else if (a2 >= ctlR || a1 < ctlP)
1720 s += ATAKD;
1721 #ifdef DEBUG_EVAL
1722 if ( debug_eval )
1723 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
1724 #endif
1728 if ( in_opening_stage ) {
1729 #ifdef DEBUG_EVAL
1730 short s0 = s;
1731 #endif
1732 if ( GameType[c1] == STATIC_ROOK )
1734 short c = ccolumn(c1,sq);
1735 /* Bonus for rook on 8th file */
1736 if ( c == 7 ) {
1737 s += R2NDCOL;
1739 /* Bonus for rook on right side, malus for rook on left side */
1740 c = 4 - c;
1741 if ( c < 0 ) {
1742 s += c + c + OPENOK;
1743 } else if ( c >= 0 ) {
1744 s += c + c + OPENWRONG;
1747 else if ( GameType[c1] == RANGING_ROOK )
1749 /* Bonus for rook on left side and bishops diagonal closed, malus otherwise. */
1750 short c;
1751 c = 4 - ccolumn(c1,sq);
1752 if ( c >= 0 ) {
1753 /* Bishops diagonal should not be open */
1754 if ( on_csquare(c1,pawn,30) )
1755 s += OPENOK;
1756 else
1757 s += c + c + OPENWRONG;
1758 } else if ( c < 0 ) {
1759 s += c + c + OPENWRONG;
1760 /* Malus for king not on initial square */
1761 if ( !on_csquare(side,king,4) ) {
1762 s += 4 * OPENWRONG;
1766 #ifdef DEBUG_EVAL
1767 if ( debug_eval && (s0 != s) )
1768 fprintf(debug_eval_file,"adding %d for opening\n",(s-s0));
1769 #endif
1772 return (s);
1775 static inline int
1776 PPawnValue (register short int sq, short int side)
1778 * Calculate the positional value for a promoted pawn on 'sq'.
1782 register short s;
1783 long a2, a1;
1785 s = 0;
1787 s += (KINGED + 2) * AddEnemyKingDistanceBonus(sq);
1789 a2 = atk2[sq];
1790 if (a2 > 0)
1792 a1 = atk1[sq];
1793 if (a1 == 0 || a2 > ctlPp + 1)
1795 s += HUNGP;
1796 if (trapped (sq))
1797 hung[c1] += 2;
1798 hung[c1]++;
1800 else if (a2 >= ctlPp || a1 < ctlP)
1801 s += ATAKD;
1804 return (s);
1807 static inline int
1808 PLanceValue (register short int sq, short int side)
1810 * Calculate the positional value for a promoted lance on 'sq'.
1814 register short s;
1815 long a2, a1;
1817 s = 0;
1819 s += (KINGED + 1) * AddEnemyKingDistanceBonus(sq);
1821 a2 = atk2[sq];
1822 if (a2 > 0)
1824 a1 = atk1[sq];
1825 if (a1 == 0 || a2 > ctlLp + 1)
1827 s += HUNGP;
1828 if (trapped (sq))
1829 hung[c1] += 2;
1830 hung[c1]++;
1832 else if (a2 >= ctlLp || a1 < ctlP)
1833 s += ATAKD;
1836 return (s);
1839 static inline int
1840 PKnightValue (register short int sq, short int side)
1842 * Calculate the positional value for a promoted knight on 'sq'.
1846 register short s;
1847 long a2, a1;
1849 s = 0;
1851 s += (KINGED + 1 ) * AddEnemyKingDistanceBonus(sq);
1853 a2 = atk2[sq];
1854 if (a2 > 0)
1856 a1 = atk1[sq];
1857 if (a1 == 0 || a2 > ctlNp + 1)
1859 s += HUNGP;
1860 if (trapped (sq))
1861 hung[c1] += 2;
1862 hung[c1]++;
1864 else if (a2 >= ctlNp || a1 < ctlP)
1865 s += ATAKD;
1868 return (s);
1871 static inline int
1872 PSilverValue (register short int sq, short int side)
1874 * Calculate the positional value for a promoted silver on 'sq'.
1878 register short s;
1879 long a2, a1;
1881 s = 0;
1883 s += (KINGED + 1) * AddEnemyKingDistanceBonus(sq);
1885 a2 = atk2[sq];
1886 if (a2 > 0)
1888 a1 = atk1[sq];
1889 if (a1 == 0 || a2 > ctlSp + 1)
1891 s += HUNGP;
1892 if (trapped (sq))
1893 hung[c1] += 2;
1894 hung[c1]++;
1896 else if (a2 >= ctlSp || a1 < ctlP)
1897 s += ATAKD;
1900 return (s);
1903 static inline int
1904 PBishopValue (register short int sq, short int side)
1906 * Calculate the positional value for a promoted bishop on 'sq'.
1910 register short s;
1911 long a2, a1;
1912 short mob;
1914 #if defined USE_PATTERN
1915 s = Mbishop[c1][sq];
1916 #else
1917 s = Mbishop[c1][csquare(c1,sq)];
1918 #endif
1920 if ( InPromotionZone(c1,sq) )
1921 s += KINGED * AddEnemyKingDistanceBonus(sq);
1923 s += BRLscan (sq, &mob);
1924 s += BMBLTY[mob];
1925 a2 = atk2[sq];
1926 if (a2 > 0)
1928 a1 = atk1[sq];
1929 if (a1 == 0 || a2 > ctlBp + 1)
1931 s += HUNGP;
1932 if (trapped (sq))
1933 hung[c1] += 2;
1934 hung[c1]++;
1936 else if (a2 >= ctlBp || a1 < ctlP)
1937 s += ATAKD;
1940 return (s);
1943 static inline int
1944 PRookValue (register short int sq, short int side)
1946 * Calculate the positional value for a promoted rook on 'sq'.
1950 register short s;
1951 register short fyle;
1952 long a2, a1;
1953 short mob;
1955 #if defined USE_PATTERN
1956 s = Mrook[c1][sq];
1957 #else
1958 s = Mrook[c1][csquare(c1,sq)];
1959 #endif
1961 if ( InPromotionZone(c1,sq) )
1962 s += KINGED * AddEnemyKingDistanceBonus(sq);
1964 s += BRLscan (sq, &mob);
1965 s += RMBLTY[mob];
1966 fyle = column (sq);
1967 if (PC1[fyle] == 0)
1968 s += RHOPN;
1969 if (PC2[fyle] == 0)
1970 s += RHOPNX;
1971 a2 = atk2[sq];
1972 if (a2 > 0)
1974 a1 = atk1[sq];
1975 if (a1 == 0 || a2 > ctlRp + 1)
1977 s += HUNGP;
1978 if (trapped (sq))
1979 hung[c1] += 2;
1980 hung[c1]++;
1982 else if (a2 >= ctlRp || a1 < ctlP)
1983 s += ATAKD;
1986 return (s);
1989 static inline int
1990 KingValue (register short int sq, short int side)
1992 * Calculate the positional value for a king on 'sq'.
1995 register short s;
1996 register short fyle;
1997 long a2, a1;
1999 #if defined USE_PATTERN
2000 s = Mking[c1][sq];
2001 #else
2002 s = Mking[c1][csquare(c1,sq)];
2003 #endif
2005 #ifdef DEBUG_EVAL
2006 if (debug_eval )
2007 fprintf(debug_eval_file,"inital value [%d] for king on %c%c: %d\n",
2008 csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
2009 #endif
2011 if (KSFTY > 0)
2012 s += KingScan (sq);
2014 if (Mvboard[kingP[c1]])
2015 s += KMOVD;
2017 fyle = column (sq);
2018 if (PC1[fyle] == 0)
2020 s += KHOPN;
2021 #ifdef DEBUG_EVAL
2022 if (debug_eval )
2023 fprintf(debug_eval_file,"adding %d for now own pawn on file\n",
2024 KHOPN);
2025 #endif
2027 if (PC2[fyle] == 0)
2029 s += KHOPNX;
2030 #ifdef DEBUG_EVAL
2031 if (debug_eval )
2032 fprintf(debug_eval_file,"adding %d for now opponents pawn on file\n",
2033 KHOPNX);
2034 #endif
2037 a2 = atk2[sq];
2038 if (a2 > 0)
2040 a1 = atk1[sq];
2041 if (a1 == 0 || a2 > ctlK + 1)
2043 s += HUNGP;
2044 #ifdef DEBUG_EVAL
2045 if ( debug_eval )
2046 fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
2047 #endif
2048 ++hung[c1];
2050 else
2052 s += ATAKD;
2053 #ifdef DEBUG_EVAL
2054 if ( debug_eval )
2055 fprintf(debug_eval_file,"adding %d for attacked piece\n",
2056 ATAKD);
2057 #endif
2061 if ( in_opening_stage ) {
2062 if ( GameType[c1] == STATIC_ROOK )
2064 /* Malus for king on right side or fifth file */
2065 short c;
2066 c = 4 - ccolumn(c1,sq);
2067 if ( c < 0 || (c == 0 && sq != kingP[c1]) ) {
2068 s += c + c + OPENWRONG;
2069 #ifdef DEBUG_EVAL
2070 if ( debug_eval )
2071 fprintf(debug_eval_file,"add %d for king on right side (Static)\n",
2072 c + c + OPENWRONG);
2073 #endif
2076 else if ( GameType[c1] == RANGING_ROOK )
2078 /* Malus for king on left side or fifth file */
2079 short c;
2080 c = 4 - ccolumn(c1,sq);
2081 if ( c > 0 || (c == 0 && sq != kingP[c1]) ) {
2082 s += c + c + OPENWRONG;
2083 #ifdef DEBUG_EVAL
2084 if ( debug_eval )
2085 fprintf(debug_eval_file,"add %d for king on left side (Ranging)\n",
2086 c + c + OPENWRONG);
2087 #endif
2089 /* Malus for king moved before rook switch */
2090 if ( sq != kingP[c1] )
2092 if ( on_csquare(c1,rook,16) ) {
2093 s += 4 * OPENWRONG;
2094 #ifdef DEBUG_EVAL
2095 if ( debug_eval )
2096 fprintf(debug_eval_file,"add %d for king moved before rook switch (Ranging)\n",
2097 4 * OPENWRONG);
2098 #endif
2101 else
2102 /* Malus for sitting king after rook switch */
2104 if ( !on_csquare(c1,rook,16) ) {
2105 s += 2 * OPENWRONG;
2106 #ifdef DEBUG_EVAL
2107 if ( debug_eval )
2108 fprintf(debug_eval_file,"add %d for sitting king after rook switch (Ranging)\n",
2109 2 * OPENWRONG);
2110 #endif
2113 /* Malus for defending general moved before king switch to right side */
2114 if ( ccolumn(c1,sq) < 6 )
2115 if ( Mvboard[csquare(c1,5)] || Mvboard[csquare(c1,6)] ) {
2116 s += 2 * OPENWRONG;
2117 #ifdef DEBUG_EVAL
2118 if ( debug_eval )
2119 fprintf(debug_eval_file,
2120 "add %d for defending general moved before king switch (Ranging)\n",
2121 2 * OPENWRONG);
2122 #endif
2127 return (s);
2133 #ifdef USE_PATTERN
2135 short
2136 ScorePatternDistance (register short int side)
2139 * Score distance to pattern regarding the game type which side plays.
2143 short ds, s = 0;
2144 OpeningPattern *p = NULL;
2146 #ifdef DEBUG_EVAL
2147 if ( debug_eval )
2148 fprintf(debug_eval_file,"scoring castle pattern distance for PCASTLE=%d\n",
2149 PCASTLE);
2150 #endif
2152 if ( PCASTLE != 0 && ((p = castle_pattern[side]) != NULL) )
2154 ds = board_to_pattern_distance(side,p,PCASTLE,GameCnt);
2155 if ( ds != 0) {
2156 s += ds;
2157 #ifdef DEBUG_EVAL
2158 if ( debug_eval && ds != 0 )
2159 fprintf(debug_eval_file,
2160 "add %d for max gain of %s to reachable castle patterns %s\n",
2161 ds, ColorStr[side], p->name);
2162 #endif
2165 #ifdef DEBUG_EVAL
2166 else if ( debug_eval && p == NULL )
2167 fprintf(debug_eval_file,"no castle pattern for %s\n",ColorStr[side]);
2168 #endif
2170 #ifdef DEBUG_EVAL
2171 if ( debug_eval )
2172 fprintf(debug_eval_file,"scoring attack pattern distance for PATTACK=%d\n",
2173 PATTACK);
2174 #endif
2176 if ( PATTACK != 0 && ((p = attack_pattern[side]) != NULL) )
2178 ds = board_to_pattern_distance(side,p,PATTACK,GameCnt);
2179 if ( ds != 0 ) {
2180 s += ds;
2181 #ifdef DEBUG_EVAL
2182 if ( debug_eval && ds != 0 )
2183 fprintf(debug_eval_file,
2184 "add %d for max gain of %s to reachable attack patterns %s\n",
2185 ds, ColorStr[side], p->name);
2186 #endif
2189 #ifdef DEBUG_EVAL
2190 else if ( debug_eval && p == NULL )
2191 fprintf(debug_eval_file,"no attack pattern for %s\n",ColorStr[side]);
2192 #endif
2194 return(s);
2198 static
2199 void
2200 UpdatePatterns (short int side, short int GameCnt)
2203 * Determine castle and attack pattern which should be reached next.
2204 * Only patterns are considered, which have not been reached yet.
2208 char s[12];
2209 short xside = side ^ 1;
2210 OpeningPattern *p;
2211 short i, n = 0;
2212 PatternSequence *sequence;
2214 strcpy(s,"CASTLE_?_?");
2215 s[7] = GameType[side];
2216 s[9] = GameType[xside];
2217 castle_pattern[side] = p = locate_opening_pattern(side,s,GameCnt);
2219 if ( flag.post && p )
2221 for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
2222 if ( sequence->distance[side] != CANNOT_REACH ) n++;
2225 #if defined USE_PATTERN
2226 if ( p ) update_advance_bonus (side,p);
2227 #endif
2229 #ifdef DEBUG_EVAL
2230 if ( debug_eval )
2231 if (p != NULL )
2233 fprintf(debug_eval_file,"castle pattern of %s is %s\n",
2234 ColorStr[side], p->name);
2235 fprintf(debug_eval_file,"reachable patterns: ");
2236 for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
2237 if ( sequence->distance[side] != CANNOT_REACH )
2238 fprintf(debug_eval_file,"%d ",i);
2239 fprintf(debug_eval_file,"\n");
2241 else
2243 fprintf(debug_eval_file,"no castle pattern %s for %s\n",
2244 s, ColorStr[side]);
2246 #endif
2248 strcpy(s,"ATTACK_?_?");
2249 s[7] = GameType[side];
2250 s[9] = GameType[xside];
2251 attack_pattern[side] = p = locate_opening_pattern(side,s,GameCnt);
2253 if ( flag.post && p )
2255 for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
2256 if ( sequence->distance[side] != CANNOT_REACH ) n++;
2260 #ifdef USE_PATTERN
2261 if ( flag.post )
2262 ShowPatternCount(side,n);
2263 if ( p ) update_advance_bonus (side,p);
2264 #endif
2266 #ifdef DEBUG_EVAL
2267 if ( debug_eval )
2268 if ( p != NULL )
2270 fprintf(debug_eval_file,"attak pattern of %s is %s\n",
2271 ColorStr[side], p->name);
2272 fprintf(debug_eval_file,"reachable patterns: ");
2273 for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
2274 if ( sequence->distance[side] != CANNOT_REACH )
2275 fprintf(debug_eval_file,"%d ",i);
2276 fprintf(debug_eval_file,"\n");
2278 else
2280 fprintf(debug_eval_file,"no attak pattern %s for %s\n",
2281 s, ColorStr[side]);
2283 #endif
2289 #endif
2292 short int
2293 ScorePosition (register short int side)
2296 * Perform normal static evaluation of board position. A score is generated
2297 * for each piece and these are summed to get a score for each side.
2301 register short int score;
2302 register short sq, i, xside;
2303 short int s;
2304 short int escore;
2305 #ifdef DEBUG_EVAL
2306 short int d;
2307 #endif
2309 UpdateWeights ();
2311 #ifdef DEBUG_EVAL
2312 if ( debug_eval )
2313 fprintf (debug_eval_file, "side = %d, stage = %d, in_opening = %d\n",
2314 side, stage, in_opening_stage );
2315 #endif
2317 xside = side ^ 1;
2318 hung[black] = hung[white] = pscore[black] = pscore[white] = 0;
2320 #ifdef CACHE
2321 #ifdef DEBUG_EVAL
2322 if (debug_eval || !ProbeEETable (side, &s))
2323 #else
2324 if (!ProbeEETable (side, &s))
2325 #endif
2327 #endif
2328 for (c1 = black; c1 <= white; c1++)
2330 c2 = c1 ^ 1;
2331 /* atk1 is array of atacks on squares by my side */
2332 atk1 = atak[c1];
2333 /* atk2 is array of atacks on squares by other side */
2334 atk2 = atak[c2];
2335 /* same for PC1 and PC2 */
2336 PC1 = PawnCnt[c1];
2337 PC2 = PawnCnt[c2];
2338 for (i = PieceCnt[c1]; i >= 0; i--)
2340 sq = PieceList[c1][i];
2341 switch (board[sq])
2343 case pawn:
2344 s = PawnValue (sq, side);
2345 break;
2346 case knight:
2347 s = KnightValue (sq, side);
2348 break;
2349 case bishop:
2350 s = BishopValue (sq, side);
2351 break;
2352 case rook:
2353 s = RookValue (sq, side);
2354 break;
2355 case lance:
2356 s = LanceValue (sq, side);
2357 break;
2358 case silver:
2359 s = SilverValue (sq, side);
2360 break;
2361 case gold:
2362 s = GoldValue (sq, side);
2363 break;
2364 case ppawn:
2365 s = PPawnValue (sq, side);
2366 break;
2367 case plance:
2368 s = PLanceValue (sq, side);
2369 break;
2370 case pknight:
2371 s = PKnightValue (sq, side);
2372 break;
2373 case psilver:
2374 s = PSilverValue (sq, side);
2375 break;
2376 case pbishop:
2377 s = PBishopValue (sq, side);
2378 break;
2379 case prook:
2380 s = PRookValue (sq, side);
2381 break;
2382 case king:
2383 s = KingValue (sq, side);
2384 break;
2385 default:
2386 s = 0;
2387 break;
2389 pscore[c1] += s;
2390 #if !defined SAVE_SVALUE
2391 svalue[sq] = s;
2392 #endif
2395 #ifdef DEBUG_EVAL
2396 if ( debug_eval ) {
2397 fprintf(debug_eval_file,"pscore[black] = %d, pscore[white] = %d\n",
2398 pscore[black], pscore[white]);
2399 #if !defined SAVE_SVALUE
2400 debug_svalue(debug_eval_file);
2401 #endif
2403 #endif
2404 if (hung[side] > 1) {
2405 #ifdef DEBUG_EVAL
2406 if ( debug_eval ) {
2407 fprintf(debug_eval_file,"adding %d to pscore for %d hung %d pieces.\n",
2408 HUNGX, hung[side], side);
2410 #endif
2411 pscore[side] += HUNGX;
2413 if (hung[xside] > 1) {
2414 #ifdef DEBUG_EVAL
2415 if ( debug_eval ) {
2416 fprintf(debug_eval_file,"adding %d to pscore for %d hung %d pieces.\n",
2417 HUNGX, hung[xside], xside);
2419 #endif
2420 pscore[xside] += HUNGX;
2423 for (c1=black,c2=white; c1<=white; c1++,c2--)
2425 #ifdef DEBUG_EVAL
2426 short ps0 = pscore[c1];
2427 #endif
2428 /* Score fifth rank */
2429 for ( sq = 36; sq <= 44; sq++ )
2430 if ( color[sq] == c1 || atak[c1][sq] != 0 )
2431 pscore[c1]++;
2433 #ifdef DEBUG_EVAL
2434 if ( debug_eval && ps0 != pscore[c1] )
2435 fprintf(debug_eval_file,"adding %d for %s's control of 5th rank\n",
2436 pscore[c1]-ps0, ColorStr[c1]);
2437 ps0 = pscore[c1];
2438 #endif
2440 /* Score holes */
2441 for ( sq = ((c1==black)?0:54); sq<=((c1==black)?26:80); sq++ )
2442 if ( board[sq] == no_piece && atak[c1][sq] == 0 )
2443 pscore[c1]--;
2445 #ifdef DEBUG_EVAL
2446 if ( debug_eval && ps0 != pscore[c1] )
2447 fprintf(debug_eval_file,"adding %d for holes in %s's camp\n",
2448 pscore[c1]-ps0, ColorStr[c1]);
2449 #endif
2451 /* Scoring depending whether in opening stage or not */
2453 if ( in_opening_stage )
2455 /* do not exchange bishops in ranging rook openings */
2456 if ( GameType[c1] == RANGING_ROOK )
2457 if ( Captured[c2][bishop] ) {
2458 pscore[c1] += BXCHG;
2459 #ifdef DEBUG_EVAL
2460 if ( debug_eval )
2461 fprintf(debug_eval_file,"adding %d for %s's bishop catched by opponent\n",
2462 BXCHG, ColorStr[c1]);
2463 #endif
2466 else
2468 short d1 = HasPiece[c1][silver] + HasPiece[c1][gold];
2469 short d2 = Captured[c1][silver] + Captured[c1][gold];
2470 pscore[c1] += (d1*2 + d2*3) * stage / 2;
2471 #ifdef DEBUG_EVAL
2472 if ( debug_eval )
2473 fprintf(debug_eval_file,"adding %d for more valuable %s generals\n",
2474 (d1*2 + d2*3) * stage / 2, ColorStr[c1]);
2475 #endif
2480 #ifdef USE_PATTERN
2481 /* Score pattern */
2483 if ( in_opening_stage ) {
2484 pscore[side] += ScorePatternDistance (side);
2485 pscore[xside] += ScorePatternDistance (xside);
2487 #endif
2489 score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
2490 if (dither)
2492 if (flag.hash)
2493 gsrand (starttime + (unsigned int) hashbd);
2494 score += urand () % dither;
2497 #ifdef CACHE
2498 if ( PUTVAR )
2499 PutInEETable(side,score);
2500 #endif
2501 #ifdef DEBUG_EVAL
2502 if ( debug_eval )
2503 fprintf (debug_eval_file, "score = %d\n", score);
2504 #endif
2505 return(score);
2506 #ifdef CACHE
2508 #ifdef DEBUG_EVAL
2509 else
2511 if ( debug_eval )
2512 fprintf (debug_eval_file, "Score cached!\n" );
2514 #endif
2516 #ifdef DEBUG_EVAL
2517 if ( debug_eval )
2518 fprintf (debug_eval_file, "s = %d\n", s);
2519 #endif
2520 return (s);
2521 #endif
2526 #if !defined USE_PATTERN
2529 #define SS 1
2530 #define RS 2
2531 #define SR 3
2532 #define RR 4
2535 static
2536 short int *PawnAdvance[2],*LanceAdvance[2],*KnightAdvance[2],
2537 *SilverAdvance[2],*GoldAdvance[2],*BishopAdvance[2],*RookAdvance[2],
2538 *KingAdvance[2];
2541 inline
2542 static
2543 void
2544 SetOpeningStrategy(short c, short s)
2546 #ifdef DEBUG_EVAL
2547 if ( debug_eval )
2548 fprintf(debug_eval_file,"strategy for %s is ",ColorStr[c]);
2549 #endif
2550 if ( s == RS ) {
2551 PawnAdvance[c] = PawnAdvanceRS;
2552 LanceAdvance[c] = LanceAdvanceRS;
2553 KnightAdvance[c] = KnightAdvanceRS;
2554 SilverAdvance[c] = SilverAdvanceRS;
2555 GoldAdvance[c] = GoldAdvanceRS;
2556 BishopAdvance[c] = BishopAdvanceRS;
2557 RookAdvance[c] = RookAdvanceRS;
2558 KingAdvance[c] = KingAdvanceRS;
2559 #ifdef DEBUG_EVAL
2560 if ( debug_eval )
2561 fprintf(debug_eval_file,"Ranging vs. Static\n");
2562 #endif
2563 } else if ( s == SR ) {
2564 PawnAdvance[c] = PawnAdvanceSR;
2565 LanceAdvance[c] = LanceAdvanceSR;
2566 KnightAdvance[c] = KnightAdvanceSR;
2567 SilverAdvance[c] = SilverAdvanceSR;
2568 GoldAdvance[c] = GoldAdvanceSR;
2569 BishopAdvance[c] = BishopAdvanceSR;
2570 RookAdvance[c] = RookAdvanceSR;
2571 KingAdvance[c] = KingAdvanceSR;
2572 #ifdef DEBUG_EVAL
2573 if ( debug_eval )
2574 fprintf(debug_eval_file,"Static vs. Ranging\n");
2575 #endif
2576 } else if ( s == RR ) {
2577 PawnAdvance[c] = PawnAdvanceRR;
2578 LanceAdvance[c] = LanceAdvanceRR;
2579 KnightAdvance[c] = KnightAdvanceRR;
2580 SilverAdvance[c] = SilverAdvanceRR;
2581 GoldAdvance[c] = GoldAdvanceRR;
2582 BishopAdvance[c] = BishopAdvanceRR;
2583 RookAdvance[c] = RookAdvanceRR;
2584 KingAdvance[c] = KingAdvanceRR;
2585 #ifdef DEBUG_EVAL
2586 if ( debug_eval )
2587 fprintf(debug_eval_file,"Ranging vs. Ranging\n");
2588 #endif
2589 } else {
2590 PawnAdvance[c] = PawnAdvanceSS;
2591 LanceAdvance[c] = LanceAdvanceSS;
2592 KnightAdvance[c] = KnightAdvanceSS;
2593 SilverAdvance[c] = SilverAdvanceSS;
2594 GoldAdvance[c] = GoldAdvanceSS;
2595 BishopAdvance[c] = BishopAdvanceSS;
2596 RookAdvance[c] = RookAdvanceSS;
2597 KingAdvance[c] = KingAdvanceSS;
2598 #ifdef DEBUG_EVAL
2599 if ( debug_eval )
2600 fprintf(debug_eval_file,"Static vs. Static\n");
2601 #endif
2608 #define AssignAdvance(b,w)\
2610 SetOpeningStrategy(black,b);\
2611 SetOpeningStrategy(white,w);\
2616 static inline void
2617 CopyBoard (small_short *a, small_short *b, short n, short d)
2619 register small_short *sqa, *sqb;
2620 register short i;
2622 if ( n == d ) {
2623 bcopy(a,b,NO_SQUARES*sizeof(short));
2624 } else
2625 for (sqa = a,sqb = b,i=0; i<NO_SQUARES; sqa++,sqb++,i++)
2626 if ( n == 1 )
2627 *sqb = (*sqa) / d;
2628 else
2629 if ( d == 1 )
2630 *sqb = n * (*sqa);
2631 else
2632 *sqb = (n * (*sqa)) / d;
2636 #endif /* USE_PATTERN */
2639 static inline void
2640 GuessGameType (void)
2643 * Try to determine the game type of "side".
2646 short side, sq, StaticRook[2] = {0,0}, RangingRook[2] = {0,0};
2648 for ( side=black; side<=white; side++ ) {
2650 /* static rook conditions */
2652 if ( on_column(side,rook,7) )
2653 StaticRook[side] += 3;
2654 if ( on_csquare(side,pawn,34) )
2655 StaticRook[side] += 6;
2656 else if ( on_csquare(side,pawn,43) )
2657 StaticRook[side] += 8;
2658 else if ( !on_column(side,pawn,7) )
2659 StaticRook[side] += 5;
2660 if ( empty_csquare(side,5) || empty_csquare(side,6) )
2661 StaticRook[side] += 2;
2662 if ( on_left_side(side,king) )
2663 StaticRook[side] += 2;
2665 /* ranging rook conditions */
2667 if ( on_left_side(side,rook) )
2668 RangingRook[side] += 5;
2669 else if ( !on_column(side,rook,7) )
2670 RangingRook[side] += 3;
2671 if ( on_csquare(side,pawn,25) )
2672 RangingRook[side] += 1;
2673 if ( on_csquare(side,pawn,30) )
2674 RangingRook[side] += 1;
2675 else
2676 RangingRook[side] -= 2;
2677 if ( !on_right_side(side,rook) )
2678 RangingRook[side] += 2;
2679 if ( on_right_side(side,king) )
2680 RangingRook[side] += 2;
2681 if ( on_csquare(side,bishop,20) )
2682 if ( on_csquare(side,silver,11) || on_csquare(side,silver,12) ||
2683 on_csquare(side,silver,21) )
2684 RangingRook[side] += 3;
2686 if ( StaticRook[side] > 5 || RangingRook[side] > 5 )
2687 GameType[side] = (StaticRook[side] > RangingRook[side])
2688 ? STATIC_ROOK : RANGING_ROOK;
2689 else
2690 GameType[side] = UNKNOWN;
2694 #ifdef DEBUG_EVAL
2695 #define StringOfGameType(side)\
2696 (GameType[side] == STATIC_ROOK ? "Static Rook" :\
2697 (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
2699 if ( debug_eval )
2700 fprintf(debug_eval_file,"guessing game type: %s vs. %s\n",
2701 StringOfGameType(black), StringOfGameType(white));
2702 #endif
2704 if ( GameType[black] == UNKNOWN || GameType[white] == UNKNOWN )
2706 for (side = black; side <= white; side++)
2707 if ( side == computer && GameType[side] == UNKNOWN ) {
2709 * Game type is UNKNOWN.
2710 * Make a decision what type of game to play.
2711 * To make computer games more interesting, make a
2712 * random decision.
2714 if ( !on_csquare(side,pawn,25) ) {
2715 /* Play static rook if rook pawn has been pushed! */
2716 GameType[side] = STATIC_ROOK;
2717 } else {
2718 unsigned int random = urand () % 100;
2719 short d = StaticRook[side] - RangingRook[side];
2720 switch ( GameType[side ^ 1] ) {
2721 case STATIC_ROOK:
2722 if ( random < 35 + d ) GameType[side] = STATIC_ROOK;
2723 else if ( random < 95 ) GameType[side] = RANGING_ROOK;
2724 break;
2725 case RANGING_ROOK:
2726 if ( random < 75 + d) GameType[side] = STATIC_ROOK;
2727 else if ( random < 95 ) GameType[side] = RANGING_ROOK;
2728 break;
2729 default:
2730 if ( random < 33 + d) GameType[side] = STATIC_ROOK;
2731 else if ( random < 66 ) GameType[side] = RANGING_ROOK;
2734 #ifdef DEBUG_EVAL
2735 if ( debug_eval )
2736 fprintf(debug_eval_file,"decide game type: %s vs. %s\n",
2737 StringOfGameType(black), StringOfGameType(white));
2738 #endif
2745 #ifdef DEBUG_EVAL
2747 #define StringOfGameType(side)\
2748 (GameType[side] == STATIC_ROOK ? "Static Rook" :\
2749 (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
2751 #endif
2754 static
2755 void
2756 DetermineGameType (void)
2758 short int side;
2760 GuessGameType();
2762 #if !defined XSHOGI
2763 if ( flag.post )
2764 ShowGameType();
2765 #endif
2767 #if defined USE_PATTERN
2769 memset ((char *)Mpawn, 0, sizeof(Mpawn));
2770 memset ((char *)Mlance, 0, sizeof(Mlance));
2771 memset ((char *)Mknight, 0, sizeof(Mknight));
2772 memset ((char *)Msilver, 0, sizeof(Msilver));
2773 memset ((char *)Mgold, 0, sizeof(Mgold));
2774 memset ((char *)Mbishop, 0, sizeof(Mbishop));
2775 memset ((char *)Mrook, 0, sizeof(Mrook));
2776 memset ((char *)Mking, 0, sizeof(Mking));
2778 #else
2780 if ( GameType[black] == STATIC_ROOK) {
2781 if ( GameType[white] == STATIC_ROOK ) {
2782 /* STATIC vs. STATIC */
2783 AssignAdvance(SS,SS);
2784 } else if ( GameType[white] == RANGING_ROOK ) {
2785 /* STATIC vs. RANGING */
2786 AssignAdvance(SR,RS);
2787 } else {
2788 /* STATIC vs. ??? */
2789 AssignAdvance(SS,SS);
2791 } else if ( GameType[black] == RANGING_ROOK ) {
2792 if ( GameType[white] == STATIC_ROOK ) {
2793 /* RANGING vs. STATIC */
2794 AssignAdvance(RS,SR);
2795 } else if ( GameType[white] == RANGING_ROOK ) {
2796 /* RANGING vs. RANGING */
2797 AssignAdvance(RR,RR);
2798 } else {
2799 /* RANGING vs. ???? */
2800 AssignAdvance(RS,SR);
2802 } else {
2803 if ( GameType[white] == STATIC_ROOK ) {
2804 /* ???? vs. STATIC */
2805 AssignAdvance(SS,SS);
2806 } else if ( GameType[white] == RANGING_ROOK ) {
2807 /* ???? vs. RANGING */
2808 AssignAdvance(SR,RS);
2809 } else {
2810 /* ???? vs. ???? */
2811 AssignAdvance(SS,SS);
2815 /* Weighted advance tables. Can be updated. */
2817 CopyBoard (PawnAdvance[black], Mpawn[black], PADVNCM, 10);
2818 CopyBoard (PawnAdvance[white], Mpawn[white], PADVNCM, 10);
2819 CopyBoard (SilverAdvance[black], Msilver[black], SADVNCM, 10);
2820 CopyBoard (SilverAdvance[white], Msilver[white], SADVNCM, 10);
2821 CopyBoard (GoldAdvance[black], Mgold[black], GADVNCM, 10);
2822 CopyBoard (GoldAdvance[white], Mgold[white], GADVNCM, 10);
2823 CopyBoard (KingAdvance[black], Mking[black], KADVNCM, 1);
2824 CopyBoard (KingAdvance[white], Mking[white], KADVNCM, 1);
2826 /* Tables without weighted advances. Must not be updated! */
2828 for ( side = black; side <= white; side++ ) {
2829 Mlance[side] = LanceAdvance[side];
2830 Mknight[side] = KnightAdvance[side];
2831 Mbishop[side] = BishopAdvance[side];
2832 Mrook[side] = RookAdvance[side];
2835 #ifdef DEBUG_EVAL
2836 if ( debug_eval ) {
2837 fprintf(debug_eval_file,"relative pawn table weigth: %d\n",PADVNCM);
2838 fprintf(debug_eval_file,"relative silver table weigth: %d\n",SADVNCM);
2839 fprintf(debug_eval_file,"relative gold table weigth: %d\n",GADVNCM);
2840 fprintf(debug_eval_file,"relative king table weigth: %d\n",KADVNCM);
2842 #endif
2844 #endif /* USE_PATTERN */
2846 #if defined USE_PATTERN
2847 if ( in_opening_stage ) {
2848 for (side = black; side <= white; side++)
2849 UpdatePatterns (side, GameCnt);
2850 } else {
2851 ShowPatternCount(black,-1);
2852 ShowPatternCount(white,-1);
2854 #endif
2860 void
2861 ExaminePosition (void)
2864 * This is done one time before the search is started. Set up arrays Mwpawn,
2865 * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
2866 * to determine the positional value of each piece.
2870 register short i, sq, msq;
2871 register short fyle;
2872 short wpadv, bpadv, z, side, pp, j, k, val, Pd, rank;
2874 #ifdef TEST_EXAMINE
2875 ShowMessage("begin of ExaminePosition");
2876 #endif
2878 ataks (black, atak[black]);
2879 ataks (white, atak[white]);
2881 #ifdef TEST_EXAMINE
2882 ShowMessage("after ataks");
2883 #endif
2885 #ifdef DEBUG_EVAL
2886 if ( debug_eval ) {
2887 debug_position (debug_eval_file);
2888 /* debug_ataks (debug_eval_file); */
2890 #endif
2892 UpdateWeights ();
2894 #ifdef TEST_EXAMINE
2895 ShowMessage("after UpdateWeights");
2896 #endif
2898 #ifdef NOMEMSET
2899 { short c, p;
2900 for ( c = black; c <= white; c++ )
2901 for ( p = pawn; p <= king; p++ )
2902 HasPiece[c][p] = 0;
2904 #else
2905 memset ((char *)HasPiece, 0,(unsigned long)sizeof(HasPiece));
2906 #endif
2908 for (side = black; side <= white; side++)
2909 for (i = PieceCnt[side]; i >= 0; i--)
2910 ++HasPiece[side][board[PieceList[side][i]]];
2912 DetermineGameType();
2914 /* Build up weighted enemy-king distance tables. */
2916 if ( KATAK == 0 )
2918 #if defined(NOMEMSET)
2919 #ifdef TEST_EXAMINE
2920 ShowMessage("just before 0 distance assignment");
2921 #endif
2922 for (sq = 0; sq < NO_SQUARES; sq++)
2923 Kfield[black][sq] = Kfield[white][sq] = 0;
2924 #else
2925 #ifdef TEST_EXAMINE
2926 ShowMessage("just before memset");
2927 #endif
2928 memset ((char *) Kfield, 0, (unsigned long)sizeof (Kfield));
2929 #endif /* NOMEMSET */
2931 else
2933 #ifdef TEST_EXAMINE
2934 ShowMessage("just before distance assignments");
2935 #endif
2936 for (sq = 0; sq < NO_SQUARES; sq++)
2938 Kfield[black][sq] = (distance(sq,WhiteKing)==1) ? KATAK : 0;
2939 Kfield[white][sq] = (distance(sq,BlackKing)==1) ? KATAK : 0;
2943 #ifdef DEBUG_EVAL
2944 if ( debug_eval )
2945 for (side=black; side<=white; side++)
2947 fprintf(debug_eval_file,"%s's pawn table\n\n",ColorStr[side]);
2948 debug_table(debug_eval_file,Mpawn[side]);
2949 fprintf(debug_eval_file,"%s's silver table\n\n",ColorStr[side]);
2950 debug_table(debug_eval_file,Msilver[side]);
2951 fprintf(debug_eval_file,"%s's gold table\n\n",ColorStr[side]);
2952 debug_table(debug_eval_file,Mgold[side]);
2953 fprintf(debug_eval_file,"%s's king table\n\n",ColorStr[side]);
2954 debug_table(debug_eval_file,Mking[side]);
2955 fprintf(debug_eval_file,"%s's distance to enemy king table\n\n",ColorStr[side]);
2956 debug_table(debug_eval_file,Kfield[side]);
2958 #endif
2960 #ifdef TEST_EXAMINE
2961 ShowMessage("end of ExaminePosition");
2962 #endif
2967 void
2968 UpdateWeights (void)
2971 * If material balance has changed, determine the values for the positional
2972 * evaluation terms.
2976 register short s1, dio, io, os;
2978 behind_in_material[black] = ((mtl[white] - mtl[black]) > valueB);
2979 behind_in_material[white] = ((mtl[black] - mtl[white]) > valueB);
2981 /* GameCnt = number of half moves */
2983 if (GameCnt < 21)
2984 s1 = 0; /* 0 <= GameCnt <= 20: stage = 0 */
2985 else if (GameCnt < 41)
2986 s1 = 1 + (GameCnt-20)/3; /* 21 <= GameCnt <= 40: stage = 1..7 */
2987 else if (GameCnt < 61)
2988 s1 = 8 + (GameCnt-40)/5; /* 41 <= GameCnt <= 60: stage = 8..11 */
2989 else
2990 s1 = 12 + (GameCnt-60)/7;
2992 if (s1 != stage)
2994 stage = stage2 = s1;
2996 os = (GameType[black] == STATIC_ROOK && GameType[white] == STATIC_ROOK) ? 10 : 8;
2997 dio = (in_opening_stage = io = (s1 < os)) ? (os - s1) : 0;
2999 #if defined USE_PATTERN
3000 ADVNCM[pawn] = io?2+s1:1; /* advanced pawn bonus increment*/
3001 ADVNCM[lance] = 1;
3002 ADVNCM[knight] = 1;
3003 ADVNCM[silver] = io?1+s1:1; /* advanced silver bonus increment */
3004 ADVNCM[gold] = io?1+s1:1; /* advanced gold bonus increment */
3005 ADVNCM[bishop] = 1;
3006 ADVNCM[rook] = 1;
3007 ADVNCM[king] = io?1+s1:1; /* advanced king bonus increment */
3008 #else
3009 PADVNCM = io?12+s1:1; /* advanced pawn multiplier */
3010 SADVNCM = io?15+s1:1; /* advanced silver multiplier */
3011 GADVNCM = io?14+s1:1; /* advanced gold multiplier */
3012 KADVNCM = io?1+s1:0; /* advanced king multiplier */
3013 #endif
3014 PMBLTY = 5; /* pawn mobility */
3015 PSTRONG = 3; /* pawn supported by rook/lance */
3016 BDCLOSED = -(dio*2); /* bishops diagonal closed by pawn */
3017 P2STRONG = 20; /* attacking pawn on 2nd col is strong */
3019 LHOPN = -4; /* no own pawn on lance file ahead */
3020 LHOPNX = 4; /* no enemy pawn on lance file ahead */
3021 LPROTECT = 6; /* protect own piece with lance */
3022 LDNGR = -6; /* lance is in danger */
3023 LXRAY = 8; /* lance Xray attack on piece */
3025 NDNGR = -4; /* knight is in danger */
3026 KNIGHTPOST = 2; /* knight near enemy pieces */
3027 KNIGHTSTRONG = 2; /* occupies pawn hole */
3028 NEDGE = io?-16:-8; /* knight is on edge file */
3030 SBEFOREG = 2; /* proverb: silver before gold */
3032 BISHOPSTRONG = 4; /* occupies pawn hole */
3033 BHCLSD = -3; /* first or second piece in a bishop's direction is an own pawn */
3034 BHCLSDX = -2; /* first or second piece in a bishop's direction is an opponents pawn */
3035 BRXRAY = 10; /* bishop or rook Xray attack on piece */
3036 BXCHG = -10; /* bishop exchange in ranging rook opening */
3038 RHOPN = 10; /* no own pawn on rook file ahead */
3039 RHOPNX = 8; /* no enemy pawn on rook file ahead */
3040 R2NDCOL = dio*2; /* rook is on 2nd column */
3042 PINVAL = 15; /* Pin */
3044 KHOPN = -8; /* no own pawn in kings file */
3045 KHOPNX = KHOPN * 2; /* no opponents pawn in kings file */
3046 KCASTLD = 20; /* king protected by castle */
3047 KMOVD = 4; /* proverb: a sitting king is a sitting duck */
3048 KATAK = io ? 1 : 8; /* B,R,L attacks near enemy king */
3049 KSFTY = /* king safety */
3050 io ? 0 : KINGSAFETY + s1 - 20;
3052 OPENOK = dio*3/2; /* corresponding to opening pattern */
3053 OPENWRONG = -dio*2; /* not correpsonding */
3055 KINGOD = 2+s1/4; /* distance to own king multiplier */
3056 KINGED = 3+s1/4; /* distance to enemy king multiplier */
3057 PROMD = 2+s1/4; /* distance to promotion zone multiplier */
3059 ATAKD = -15; /* defender > attacker */
3060 HUNGP = -14; /* each hung piece */
3061 HUNGX = -18; /* extra for >1 hung piece */
3063 #ifdef USE_PATTERN
3064 PATTACK = dio; /* attack pattern distance multiplier */
3065 PCASTLE = dio; /* castle pattern distance multiplier */
3066 #endif