1 /* the evaluation functions */
2 
3 #include "includes.h"
4 #include "knightcap.h"
5 #if LARGE_ETYPE
6 #include "large_coeffs.h"
7 #else
8 #include "small_coeffs.h"
9 #endif
10 
11 #define EVAL_ALL_DEPTH 2
12 
13 #define EVAL_SHORTCUT_THRESHOLD (2.0*STATIC_PAWN_VALUE)
14 #define EVAL_SHORTCUT_OFFSET (1.5*STATIC_PAWN_VALUE)
15 
16 /* coefficients we don't want changed by TD(lambda) (multiplicative factors,
17  the value of a pawn, the value of a king, and the value of a draw */
18 int dont_change[] = {};
19 
20 etype new_coefficients[__TOTAL_COEFFS__];
21 etype *coefficients;
22 
23 extern int learning;
24 extern int mulling;
25 extern struct state *state;
26 int debug;
27 
28 /* this is the value of pawns on open files as they move up the board
29    - it is doubled for passed pawns */
30 #define pawn_advance (coefficients + IPAWN_ADVANCE)
31 #define pawn_advance1 (coefficients + IPAWN_ADVANCE1)
32 #define pawn_advance2 (coefficients + IPAWN_ADVANCE2)
33 
34 /* the value of controlling the squares in front of a passed pawn */
35 #define passed_pawn_control (coefficients + IPASSED_PAWN_CONTROL)
36 
37 /* index into the passed_pawn_control array */
38 static etype passed_pawn_index[] = {0, 6, 11, 15, 18, 20};
39 
40 /* value of pawn configurations around the king */
41 #define pawn_defence (coefficients + IPAWN_DEFENCE)
42 static unsigned char black_pawn_loc[8];
43 static unsigned char white_pawn_loc[8];
44 
45 #define PAWN_LOC(player) (player>0?white_pawn_loc:black_pawn_loc)
46 
47 int pop_count[256];
48 
init_eval_tables(void)49 void init_eval_tables(void)
50 {
51         struct stat st;
52         static int initialised;
53         int fd;
54         extern char *coeffs_file;
55         int i;
56 
57         if (initialised) return;
58         initialised = 1;
59 
60         state->rating_change = -2;
61 
62         for (i=0;i<256;i++) {
63                 pop_count[i] = bit_count(i);
64         }
65 
66         if (sizeof(orig_coefficients) != __TOTAL_COEFFS__ *
67             sizeof(orig_coefficients[0])) {
68                 lprintf(0,"coefficients table corrupt! %d %d\n",
69                         __TOTAL_COEFFS__,
70                         sizeof(orig_coefficients) / sizeof(orig_coefficients[0]));
71                 exit(1);
72         }
73 
74 
75         memcpy(&(new_coefficients[0]), &(orig_coefficients[0]),
76 	       sizeof(orig_coefficients));
77 	coefficients = &(new_coefficients[0]);
78 
79         if (!coeffs_file) {
80                 td_dump("coeffs.dat");
81                 return;
82         }
83 
84         fd = open(coeffs_file, O_RDONLY);
85         if (fd == -1) {
86                 lprintf(0,"Failed to open %s\n", coeffs_file);
87                 td_dump("coeffs.dat");
88                 return;
89         }
90 
91         if (fstat(fd, &st) != 0 &&
92 	    st.st_size != __TOTAL_COEFFS__*sizeof(coefficients[0])) {
93                 lprintf(0,"%s is corrupt\n", coeffs_file);
94                 return;
95         }
96 
97         if (Read(fd, (char *)coefficients,st.st_size) != st.st_size) {
98                 lprintf(0,"failed to read coefficients\n");
99                 close(fd);
100                 return;
101         }
102 
103         lprintf(0,"Loaded coefficients from %s\n", coeffs_file);
104         close(fd);
105 
106 
107 }
108 
109 
110 #define pawn_pos_value (coefficients + IPAWN_POS)
111 
112 /* this corrects the unstoppable pawn evaluation on null moves */
update_pawns(Position * b)113 void update_pawns(Position *b)
114 {
115 	if (whites_move(b)) {
116 		b->eval_result += (pop_count32(b->null_stoppable_pawn & BPAWN_MASK) +
117 				   pop_count32(b->null_unstoppable_pawn & WPAWN_MASK))*
118 			UNSTOPPABLE_PAWN;
119 	} else {
120 		b->eval_result -= (pop_count32(b->null_stoppable_pawn & WPAWN_MASK) +
121 				   pop_count32(b->null_unstoppable_pawn & BPAWN_MASK))*
122 			UNSTOPPABLE_PAWN;
123 	}
124 }
125 
get_control(Position * b,uint32 topieces,int piece,Square sq)126 static int get_control(Position *b, uint32 topieces,
127 		       int piece, Square sq)
128 {
129 	int nw, nb;
130 	/* the following masks select pieces that are of lower than
131 	   value than a piece */
132 	static const uint32 masks[2*KING+1] =
133 	{0xFFFE, 0xFFFC, 0xFFF0, 0xFF00, 0xFF00, 0,
134 	 0,
135 	 0, 0xFF000000, 0xFF000000, 0xFFF00000, 0xFFFC0000, 0xFFFE0000};
136 
137 	if (!topieces) return 0;
138 
139 	if (topieces & masks[piece+KING])
140 		return -piece;
141 
142 	/* compare pawn counts */
143 	nw = pop_count[(topieces >> 8) & 0xFF];
144 	nb = pop_count[(topieces >> 24) & 0xFF];
145 	if (nw - nb) return nw - nb;
146 
147 	/* compare piece counts */
148 	nw = pop_count[topieces & 0xFF];
149 	nb = pop_count[(topieces >> 16) & 0xFF];
150 
151 #if USE_SLIDING_CONTROL
152 	nw += pop_count[b->xray_topieces[sq] & 0xFF];
153 	nb += pop_count[(b->xray_topieces[sq] >> 16) & 0xFF];
154 #endif
155 	return (nw - nb);
156 }
157 
158 #define weak_pawn_attack_value (coefficients + IWEAK_PAWN_ATTACK_VALUE)
159 /* this evaluates a pawn - its more valuable if its a passed
160    pawn or on an open file. In those cases it gains value
161    as it moves up the board */
eval_white_pawn(Position * b,int pi)162 static etype eval_white_pawn(Position *b, int pi)
163 {
164 	PieceStruct *piece = b->pieces + pi;
165 	etype ret=0;
166 	int num = 0;
167 	int x = XPOS(piece->pos);
168 	int y = YPOS(piece->pos);
169 	etype advance = 0;
170 	int weak = 0;
171 	Square pos;
172 
173 	b->wpassed_pawn_mask &= ~(1<<pi);
174 
175 	ret = pawn_pos_value[piece->pos];
176 
177 	if ((x != 0 && b->board[piece->pos+WEST] == PAWN) ||
178 	    (x != 7 && b->board[piece->pos+EAST] == PAWN)) {
179 		ret += ADJACENT_PAWN;
180 	}
181 
182 	/* a pawn is weak if it isn't supported by a pawn and can't
183 	   move to a place where it is supported by a pawn */
184 
185 	if (b->topieces[piece->pos] & WPAWN_MASK)
186 		goto not_weak;
187 
188 	/* penalize slightly unsupported pawns */
189 	ret -= UNSUPPORTED_PAWN;
190 	if (debug)
191 		lprintf(0,"unsupported %s\n", posstr(piece->pos));
192 
193 	if ((b->topieces[piece->pos+NORTH] & WPAWN_MASK) &&
194 	    abs(b->board[piece->pos+NORTH]) != PAWN)
195 		goto not_weak;
196 
197 	if (y == 1 && !(b->topieces[piece->pos+NORTH] & BPAWN_MASK) &&
198 	    (b->topieces[piece->pos+2*NORTH] & WPAWN_MASK) &&
199 	    (abs(b->board[piece->pos+NORTH]) != PAWN) &&
200 	    (abs(b->board[piece->pos+2*NORTH]) != PAWN))
201 		goto not_weak;
202 
203 	if (debug)
204 		lprintf(0,"weak %s\n", posstr(piece->pos));
205 	weak = 1;
206 
207 	ret -= WEAK_PAWN;
208 
209 	/* if its on a half open file then its even weaker */
210 	if (black_pawn_loc[x] == 0)
211 		ret -= MEGA_WEAK_PAWN;
212 
213 	/* attacks on weak pawns are worth something */
214 	if (((b->topieces[piece->pos] & ~b->pinned_mask)>>16) & 0xFF) {
215 		num = pop_count[((b->topieces[piece->pos] &
216 				   ~b->pinned_mask)>>16) & 0xFF];
217 		ret -= weak_pawn_attack_value[num];
218 	}
219 
220 not_weak:
221 
222 	if (black_pawn_loc[x] < y) {
223 		int n = 7-y;
224 		if (!weak) {
225 			advance = pawn_advance2[n];
226 		}
227 		if ((x==0 || black_pawn_loc[x-1] <= y) &&
228 		    (x==7 || black_pawn_loc[x+1] <= y)) {
229 			Square wkpos = WHITEPIECES(b)[IKING].pos;
230 			Square bkpos = BLACKPIECES(b)[IKING].pos;
231 			int a, control;
232 			uint32 rook_support = 0;
233 			uint32 topieces;
234 
235 			b->wpassed_pawn_mask |= (1<<pi);
236 			pos = piece->pos;
237 
238 			advance += pawn_advance[n];
239 
240 			if (YPOS(bkpos) >= y && abs(XPOS(bkpos) - x) <= 1)
241 				advance -= KING_PASSED_PAWN_DEFENCE;
242 
243 			if (YPOS(wkpos) >= y && abs(XPOS(wkpos) - x) <= 1)
244 				advance += KING_PASSED_PAWN_SUPPORT;
245 
246 			if (b->board[pos+NORTH] < 0)
247 				advance -= BLOCKED_PASSED_PAWN;
248 
249 			if ((b->topieces[pos] & ~b->pinned_mask & BKROOK_MASK) &&
250 			    XPOS(BLACKPIECES(b)[IKROOK].pos) == x &&
251 			    YPOS(BLACKPIECES(b)[IKROOK].pos) < y) {
252 				/* there is a black king rook
253 				   behind our passed pawn */
254 				advance -= PASSED_PAWN_ROOK_ATTACK;
255 			}
256 
257 			if ((b->topieces[pos] & ~b->pinned_mask & BQROOK_MASK) &&
258 			    XPOS(BLACKPIECES(b)[IQROOK].pos) == x &&
259 			    YPOS(BLACKPIECES(b)[IQROOK].pos) < y) {
260 				/* there is a black queen rook
261 				   behind our passed pawn */
262 				advance -= PASSED_PAWN_ROOK_ATTACK;
263 			}
264 
265 			if ((b->topieces[pos] & ~b->pinned_mask & WKROOK_MASK) &&
266 			    XPOS(WHITEPIECES(b)[IKROOK].pos) == x &&
267 			    YPOS(WHITEPIECES(b)[IKROOK].pos) < y) {
268 				/* there is a white king rook
269 				   behind our passed pawn */
270 				rook_support = WKROOK_MASK;
271 				advance += PASSED_PAWN_ROOK_SUPPORT;
272 			}
273 
274 			if ((b->topieces[pos] & ~b->pinned_mask & WQROOK_MASK) &&
275 			    XPOS(WHITEPIECES(b)[IQROOK].pos) == x &&
276 			    YPOS(WHITEPIECES(b)[IQROOK].pos) < y) {
277 				/* there is a white queen rook
278 				   behind our passed pawn */
279 				rook_support = WQROOK_MASK;
280 				advance += PASSED_PAWN_ROOK_SUPPORT;
281 			}
282 
283 			a = passed_pawn_index[y-1];
284 			while (!off_board(pos,NORTH)) {
285 				pos += NORTH;
286 				/* if rook_support == 1 we have to adjust the control
287 				   of the squares in front of the pawn */
288 				if (!rook_support) {
289 					control = b->cont[pos];
290 				} else {
291 					topieces = b->topieces[pos] & (~b->pinned_mask);
292 					topieces |= rook_support;
293 					control = get_control(b, topieces, b->board[pos], pos);
294 				}
295 				if (control >= 0) {
296 					advance += passed_pawn_control[a];
297 					++a;
298 				} else {
299 					break;
300 				}
301 			}
302 
303 			if (x != 0 && white_pawn_loc[x-1] &&
304 			    abs(y - white_pawn_loc[x-1]) <= 1) {
305 				advance += pawn_advance1[n];
306 			}
307 
308 			if (x != 7 && white_pawn_loc[x+1] &&
309 			    abs(y - white_pawn_loc[x+1]) <= 1) {
310 				advance += pawn_advance1[n];
311 			}
312 
313 
314 			/* a special case - is it unstoppable? */
315 			if ((b->piece_mask & BLACK_MASK) == BKING_MASK) {
316 				int kpos = BLACKPIECES(b)[IKING].pos;
317 				int kmoves = imax(abs(XPOS(kpos) - x), 7-YPOS(kpos));
318 				int pmoves = 7-y;
319 				if (blacks_move(b)) kmoves--;
320 				if (kmoves > pmoves) {
321 					/* its a candidate for unstopppability, but we need to
322 					   count all pieces that have to move out of the way,
323 					   except those on the queening square. If we find a pawn
324 					   in front then we assume the current pawn is stoppable */
325 
326 					Square pos = piece->pos;
327 
328 					while (!off_board(pos+NORTH,NORTH)) {
329 						pos += NORTH;
330 						if (b->board[pos]) {
331 							if (b->board[pos] == PAWN)
332 								pmoves += 10;
333 							else
334 								++pmoves;
335 							if (pmoves >= kmoves)
336 								break;
337 						}
338 					}
339 					if (kmoves > pmoves) {
340 						ret += UNSTOPPABLE_PAWN;
341 						if (debug)
342 							lprintf(0,"unstoppable %s\n",
343 								posstr(piece->pos));
344 						/* would it become stoppable after a null move? */
345 						if (whites_move(b) && kmoves == pmoves+1) {
346 							b->null_stoppable_pawn |= (1<<pi);
347 							if (debug)
348 								lprintf(0,"null stoppable %s\n",
349 									posstr(piece->pos));
350 						}
351 						/* would it become unstoppable after a null move? */
352 					} else if (blacks_move(b) && kmoves == pmoves) {
353 						b->null_unstoppable_pawn |= (1<<pi);
354 						if (debug)
355 							lprintf(0,"null unstoppable %s\n",
356 								posstr(piece->pos));
357 					}
358 				}
359 			}
360 
361 			if (n < 4 && (ret + advance < pawn_advance[5])) {
362 				/* passed pawns always have some value */
363 				advance = pawn_advance[5] - ret;
364 			}
365 		}
366 		ret += advance;
367 	}
368 
369 	if (white_pawn_loc[x] != y)
370 		ret -= DOUBLED_PAWN;
371 
372 	if (x==0 && white_pawn_loc[x+1] == 0)
373 		ret -= ISOLATED_PAWN;
374 	else if (x==7 && white_pawn_loc[x-1] == 0)
375 		ret -= ISOLATED_PAWN;
376 	else if (white_pawn_loc[x-1] == 0 && white_pawn_loc[x+1] == 0)
377 		ret -= ISOLATED_PAWN;
378 
379 	/* get rid of this because its not calculated incrementally and not clear
380 	   that its really useful */
381 #if 0
382 	if (b->stage == ENDING) {
383 		if ((b->piece_mask & WBISHOP_MASK) == WKBISHOP_MASK) {
384 			if (!white_square(piece->pos)) ret += ODD_BISHOPS_PAWN_POS;
385 		} else if ((b->piece_mask & WBISHOP_MASK) == WQBISHOP_MASK) {
386 			if (white_square(piece->pos)) ret += ODD_BISHOPS_PAWN_POS;
387 		}
388 	}
389 #endif
390 	return ret;
391 }
392 
eval_black_pawn(Position * b,int pi)393 static etype eval_black_pawn(Position *b, int pi)
394 {
395 	PieceStruct *piece = b->pieces + pi;
396 	etype ret=0;
397 	int num = 0;
398 	int x = XPOS(piece->pos);
399 	int y = YPOS(piece->pos);
400 	etype advance = 0;
401 	int weak = 0;
402 	Square pos;
403 
404 	b->bpassed_pawn_mask &= ~(1<<pi);
405 
406 	ret = pawn_pos_value[mirror_square(piece->pos)];
407 
408 	/* a pawn is weak if it isn't supported by a pawn and can't
409 	   move to a place where it is supported by a pawn */
410 
411 	if ((x != 0 && b->board[piece->pos+WEST] == -PAWN) ||
412 	    (x != 7 && b->board[piece->pos+EAST] == -PAWN)) {
413 		ret += ADJACENT_PAWN;
414 	}
415 
416 	if (b->topieces[piece->pos] & BPAWN_MASK)
417 		goto not_weak;
418 
419 	ret -= UNSUPPORTED_PAWN;
420 	if (debug)
421 		lprintf(0, "unsupported %s\n", posstr(piece->pos));
422 
423 	if ((b->topieces[piece->pos+SOUTH] & BPAWN_MASK) &&
424 	    abs(b->board[piece->pos+SOUTH]) != PAWN)
425 		goto not_weak;
426 
427 
428 	if (y == 6 && !(b->topieces[piece->pos+SOUTH] & WPAWN_MASK) &&
429 	    (b->topieces[piece->pos+2*SOUTH] & BPAWN_MASK) &&
430 	    (abs(b->board[piece->pos+SOUTH]) != PAWN) &&
431 	    (abs(b->board[piece->pos+2*SOUTH]) != PAWN))
432 		goto not_weak;
433 
434 	if (debug)
435 		lprintf(0,"weak %s\n", posstr(piece->pos));
436 	weak = 1;
437 	ret -= WEAK_PAWN;
438 
439 	/* if its on a half open file then its even weaker */
440 	if (white_pawn_loc[x] == 0)
441 		ret -= MEGA_WEAK_PAWN;
442 
443 	/* attacks on weak pawns are worth something */
444 	if (b->topieces[piece->pos] & ~b->pinned_mask & 0xFF) {
445 		num = pop_count[b->topieces[piece->pos] &
446 				~b->pinned_mask & 0xFF];
447 		ret -= weak_pawn_attack_value[num];
448 	}
449 
450  not_weak:
451 
452 	if (white_pawn_loc[x] == 0 || white_pawn_loc[x] > y) {
453 		int n = y;
454 		if (!weak) {
455 			advance = pawn_advance2[n];
456 		}
457 		if ((x==0 || white_pawn_loc[x-1]==0 ||
458 		     white_pawn_loc[x-1] >= y) &&
459 		    (x==7 || white_pawn_loc[x+1]==0 ||
460 		     white_pawn_loc[x+1] >= y)) {
461 			Square wkpos = WHITEPIECES(b)[IKING].pos;
462 			Square bkpos = BLACKPIECES(b)[IKING].pos;
463 			int a, control;
464 			uint32 rook_support = 0;
465 			uint32 topieces;
466 
467 			b->bpassed_pawn_mask |= (1<<pi);
468 			pos = piece->pos;
469 
470 			advance += pawn_advance[n];
471 
472 
473 			if (YPOS(wkpos) <= y && abs(XPOS(wkpos) - x) <= 1)
474 				advance -= KING_PASSED_PAWN_DEFENCE;
475 
476 			if (YPOS(bkpos) <= y && abs(XPOS(bkpos) - x) <= 1)
477 				advance += KING_PASSED_PAWN_SUPPORT;
478 
479 			if (b->board[piece->pos+SOUTH] > 0) {
480 				advance -= BLOCKED_PASSED_PAWN;
481 			}
482 
483 			if (x != 0 && black_pawn_loc[x-1] &&
484 			    abs(y - black_pawn_loc[x-1]) <= 1) {
485 				advance += pawn_advance1[n];
486 			}
487 
488 			if (x != 7 && black_pawn_loc[x+1] &&
489 			    abs(y - black_pawn_loc[x+1]) <= 1) {
490 				advance += pawn_advance1[n];
491 			}
492 
493 			if ((b->topieces[piece->pos] & ~b->pinned_mask & WKROOK_MASK) &&
494 			    XPOS(WHITEPIECES(b)[IKROOK].pos) == x &&
495 			    YPOS(WHITEPIECES(b)[IKROOK].pos) > y) {
496 				/* there is a white king rook
497 				   behind our passed pawn */
498 				advance -= PASSED_PAWN_ROOK_ATTACK;
499 			}
500 
501 			if ((b->topieces[piece->pos] & ~b->pinned_mask & WQROOK_MASK) &&
502 			    XPOS(WHITEPIECES(b)[IQROOK].pos) == x &&
503 			    YPOS(WHITEPIECES(b)[IQROOK].pos) > y) {
504 				/* there is a white queen rook
505 				   behind our passed pawn */
506 				advance -= PASSED_PAWN_ROOK_ATTACK;
507 			}
508 
509 
510 			if ((b->topieces[piece->pos] & ~b->pinned_mask & BKROOK_MASK) &&
511 			    XPOS(BLACKPIECES(b)[IKROOK].pos) == x &&
512 			    YPOS(BLACKPIECES(b)[IKROOK].pos) > y) {
513 				/* there is a black king rook
514 				   behind our passed pawn */
515 				rook_support = BKROOK_MASK;
516 				advance += PASSED_PAWN_ROOK_SUPPORT;
517 			}
518 
519 			if ((b->topieces[piece->pos] & ~b->pinned_mask & BQROOK_MASK) &&
520 			    XPOS(BLACKPIECES(b)[IQROOK].pos) == x &&
521 			    YPOS(BLACKPIECES(b)[IQROOK].pos) > y) {
522 				/* there is a black queen rook
523 				   behind our passed pawn */
524 				rook_support = BQROOK_MASK;
525 				advance += PASSED_PAWN_ROOK_SUPPORT;
526 			}
527 
528 
529 			a = passed_pawn_index[7-y-1];
530 			while (!off_board(pos,SOUTH)) {
531 				pos += SOUTH;
532 				if (!rook_support) {
533 					control = b->cont[pos];
534 				} else {
535 					topieces = b->topieces[pos] & (~b->pinned_mask);
536 					topieces |= rook_support;
537 					control = get_control(b, topieces, b->board[pos], pos);
538 				}
539 				if (control <= 0) {
540 					advance += passed_pawn_control[a];
541 					++a;
542 				} else {
543 					break;
544 				}
545 			}
546 
547 			/* a special case - is it unstoppable? */
548 			if ((b->piece_mask & WHITE_MASK) == WKING_MASK) {
549 				int kpos = WHITEPIECES(b)[IKING].pos;
550 				int kmoves = imax(abs(XPOS(kpos) - x), YPOS(kpos));
551 				int pmoves = y;
552 				if (whites_move(b)) kmoves--;
553 				if (kmoves > pmoves) {
554 					/* its a candidate for unstopppability, but we need to
555 					   count all pieces that have to move out of the way,
556 					   except those on the queening square. */
557 
558 					Square pos = piece->pos;
559 
560 					while (!off_board(pos+SOUTH,SOUTH)) {
561 						pos += SOUTH;
562 						if (b->board[pos] != 0) {
563 							if (b->board[pos] == -PAWN)
564 								pmoves += 10;
565 							else
566 								++pmoves;
567 							if (pmoves >= kmoves)
568 								break;
569 						}
570 					}
571 					if (kmoves > pmoves) {
572 						ret += UNSTOPPABLE_PAWN;
573 						if (debug)
574 							lprintf(0,"unstoppable %s %d %d\n",
575 								posstr(piece->pos),
576 								kmoves, pmoves);
577 						/* would it become stoppable after a null move? */
578 						if (blacks_move(b) && kmoves == pmoves+1) {
579 							b->null_stoppable_pawn |= (1<<pi);
580 							if (debug)
581 								lprintf(0,"null stoppable %s\n",
582 									posstr(piece->pos));
583 						}
584 						/* would it become unstoppable after a null move? */
585 					} else if (whites_move(b) && kmoves == pmoves) {
586 						b->null_unstoppable_pawn |= (1<<pi);
587 						if (debug)
588 							lprintf(0,"null unstoppable %s\n",
589 								posstr(piece->pos));
590 					}
591 				}
592 			}
593 			if (n < 4 && (ret + advance < pawn_advance[5])) {
594 				/* passed pawns always have some value */
595 				advance = pawn_advance[5] - ret;
596 			}
597 		}
598 		if (debug)
599 			lprintf(0,"%s advance: %e\n", posstr(piece->pos), advance);
600 		ret += advance;
601 	}
602 
603 	if (black_pawn_loc[x] != y)
604 		ret -= DOUBLED_PAWN;
605 
606 	if (x==0 && black_pawn_loc[x+1] == 0)
607 		ret -= ISOLATED_PAWN;
608 	else if (x==7 && black_pawn_loc[x-1] == 0)
609 		ret -= ISOLATED_PAWN;
610 	else if (black_pawn_loc[x-1] == 0 && black_pawn_loc[x+1] == 0)
611 		ret -= ISOLATED_PAWN;
612 
613 #if 0
614 	if (b->stage == ENDING)
615 		if ((b->piece_mask & BBISHOP_MASK) == BKBISHOP_MASK) {
616 			if (white_square(piece->pos)) ret += ODD_BISHOPS_PAWN_POS;
617 		} else if ((b->piece_mask & BBISHOP_MASK) == BQBISHOP_MASK) {
618 			if (!white_square(piece->pos)) ret += ODD_BISHOPS_PAWN_POS;
619 		}
620 #endif
621 	return ret;
622 }
623 
624 
625 /* these are adjustments for king position in the opening and
626    ending - they try to encourage a central king in the ending */
627 #define ending_kpos (coefficients + IENDING_KPOS)
628 #define opening_king_advance (coefficients + IOPENING_KING_ADVANCE)
629 #define mid_king_advance (coefficients + IMID_KING_ADVANCE)
630 #define king_proximity (coefficients + IKING_PROXIMITY)
631 /* the king likes to be near an edge at the start of the game and
632    near the middle at the end */
eval_white_king(Position * b,int pi)633 static etype eval_white_king(Position *b, int pi)
634 {
635 	PieceStruct *piece = b->pieces + pi;
636 	etype ret=0;
637 
638 	if (b->piece_mask & BQUEEN_MASK) {
639 		if (b->stage == OPENING) {
640 			if (YPOS(piece->pos) != 0)
641 				ret -= opening_king_advance[YPOS(piece->pos)];
642 		} if (b->stage == MIDDLE) {
643 			if (YPOS(piece->pos) != 0)
644 				ret -= mid_king_advance[YPOS(piece->pos)];
645 		}
646 	} else {
647 		if (b->stage == MATING) {
648 			if (b->w_material < b->b_material - STATIC_PAWN_VALUE) {
649 				ret += 10*(ending_kpos[XPOS(piece->pos)] +
650 					   ending_kpos[YPOS(piece->pos)]);
651 			} else {
652 				int kpos = BLACKPIECES(b)[IKING].pos;
653 				int kmoves = imax(abs(XPOS(kpos) - XPOS(piece->pos)),
654 						  abs(YPOS(kpos) - YPOS(piece->pos)));
655 				ret -= king_proximity[kmoves];
656 			}
657 
658 		} else {
659 			ret += ending_kpos[XPOS(piece->pos)] +
660 				ending_kpos[YPOS(piece->pos)];
661 		}
662 	}
663 
664 	if (b->stage >= ENDING)
665 		return ret;
666 
667 	if (b->flags & WHITE_CASTLED) {
668 		ret += CASTLE_BONUS;
669 	} else if (!(b->flags & (WHITE_CASTLE_SHORT|WHITE_CASTLE_LONG))) {
670 		ret -= CASTLE_BONUS;
671 	}
672 
673 	/* forget about pawn defence once the queens are off! */
674 	if (!(b->material_mask & BQUEEN_MASK))
675 		return ret;
676 
677 	if (YPOS(piece->pos) == 0 &&
678 	    (XPOS(piece->pos) > 4 || (b->flags & WHITE_CASTLE_SHORT))) {
679 		if (b->board[F2] == PAWN)
680 			ret += pawn_defence[FPAWN];
681 		if (b->board[G2] == PAWN)
682 			ret += pawn_defence[GPAWN];
683 		if (b->board[H2] == PAWN)
684 			ret += pawn_defence[HPAWN];
685 		if (b->board[H3] == PAWN && b->board[G2] == PAWN)
686 			ret += pawn_defence[HGPAWN];
687 		if (b->board[G3] == PAWN && b->board[H2] == PAWN &&
688 		    !(b->material_mask & BQBISHOP_MASK))
689 			ret += pawn_defence[GHPAWN];
690 		if (b->board[F3] == PAWN && b->board[G2] == PAWN &&
691 		    !(b->material_mask & BKBISHOP_MASK))
692 			ret += pawn_defence[FGPAWN];
693 	}
694 
695 	if (YPOS(piece->pos) == 0 && XPOS(piece->pos) < 3) {
696 		if (b->board[A2] == PAWN)
697 			ret += pawn_defence[APAWN];
698 		if (b->board[B2] == PAWN)
699 			ret += pawn_defence[BPAWN];
700 		if (b->board[C2] == PAWN)
701 			ret += pawn_defence[CPAWN];
702 		if (b->board[A3] == PAWN && b->board[B2] == PAWN)
703 			ret += pawn_defence[ABPAWN];
704 		if (b->board[B3] == PAWN && b->board[A2] == PAWN &&
705 		    !(b->material_mask & BKBISHOP_MASK))
706 			ret += pawn_defence[BAPAWN];
707 		if (b->board[C3] == PAWN && b->board[B2] == PAWN &&
708 		    !(b->material_mask & BQBISHOP_MASK))
709 			ret += pawn_defence[CBPAWN];
710 	}
711 
712 	return ret;
713 }
714 
715 
eval_black_king(Position * b,int pi)716 static etype eval_black_king(Position *b, int pi)
717 {
718 	PieceStruct *piece = b->pieces + pi;
719 	etype ret=0;
720 
721 	if (b->piece_mask & WQUEEN_MASK) {
722 		if (b->stage == OPENING) {
723 			if (YPOS(piece->pos) != 7)
724 				ret -= opening_king_advance[7-YPOS(piece->pos)];
725 		} if (b->stage == MIDDLE) {
726 			if (YPOS(piece->pos) != 7)
727 				ret -= mid_king_advance[7-YPOS(piece->pos)];
728 		}
729 	} else {
730 		if (b->stage == MATING) {
731 			if (b->b_material < b->w_material - STATIC_PAWN_VALUE) {
732 				ret += 10*(ending_kpos[XPOS(piece->pos)] +
733 					   ending_kpos[YPOS(piece->pos)]);
734 			} else {
735 				int kpos = WHITEPIECES(b)[IKING].pos;
736 				int kmoves = imax(abs(XPOS(kpos) - XPOS(piece->pos)),
737 						  abs(YPOS(kpos)-YPOS(piece->pos)));
738 				ret -= king_proximity[kmoves];
739 			}
740 		} else {
741 			ret += ending_kpos[XPOS(piece->pos)] +
742 				ending_kpos[YPOS(piece->pos)];
743 		}
744 	}
745 
746 	if (b->stage >= ENDING)
747 		return ret;
748 
749 	if (b->flags & BLACK_CASTLED) {
750 		ret += CASTLE_BONUS;
751 	} else if (!(b->flags & (BLACK_CASTLE_SHORT|BLACK_CASTLE_LONG))) {
752 		ret -= CASTLE_BONUS;
753 	}
754 
755 	/* forget about pawn defence once the queens are off! */
756 	if (!(b->material_mask & WQUEEN_MASK))
757 		return ret;
758 
759 	if (YPOS(piece->pos) == 7 &&
760 	    (XPOS(piece->pos) > 4 || (b->flags & BLACK_CASTLE_SHORT))) {
761 		if (b->board[F7] == -PAWN)
762 			ret += pawn_defence[FPAWN];
763 		if (b->board[G7] == -PAWN)
764 			ret += pawn_defence[GPAWN];
765 		if (b->board[H7] == -PAWN)
766 			ret += pawn_defence[HPAWN];
767 		if (b->board[H6] == -PAWN && b->board[G7] == -PAWN)
768 			ret += pawn_defence[HGPAWN];
769 		if (b->board[G6] == -PAWN && b->board[H7] == -PAWN &&
770 		    !(b->material_mask & WQBISHOP_MASK))
771 			ret += pawn_defence[GHPAWN];
772 		if (b->board[F6] == -PAWN && b->board[G7] == -PAWN &&
773 		    !(b->material_mask & WKBISHOP_MASK))
774 			ret += pawn_defence[FGPAWN];
775 	}
776 
777 	if (YPOS(piece->pos) == 7 && XPOS(piece->pos) < 3) {
778 		if (b->board[A7] == -PAWN)
779 			ret += pawn_defence[APAWN];
780 		if (b->board[B7] == -PAWN)
781 			ret += pawn_defence[BPAWN];
782 		if (b->board[C7] == -PAWN)
783 			ret += pawn_defence[CPAWN];
784 		if (b->board[A6] == -PAWN && b->board[B7] == -PAWN)
785 			ret += pawn_defence[ABPAWN];
786 		if (b->board[B6] == -PAWN && b->board[A7] == -PAWN &&
787 		    !(b->material_mask & WKBISHOP_MASK))
788 			ret += pawn_defence[BAPAWN];
789 		if (b->board[C6] == -PAWN && b->board[B7] == -PAWN &&
790 		    !(b->material_mask & WQBISHOP_MASK))
791 			ret += pawn_defence[CBPAWN];
792 	}
793 
794 	return ret;
795 }
796 
797 
798 
eval_queen(Position * b,int pi)799 static etype eval_queen(Position *b, int pi)
800 {
801 	PieceStruct *p = b->pieces + pi;
802 	etype ret=0;
803 
804 	/* penalize early queen movement */
805 	if (b->stage == OPENING) {
806 		if ((p->p > 0 && YPOS(p->pos) > 2) ||
807 		    (p->p < 0 && YPOS(p->pos) < 5))
808 			ret -= EARLY_QUEEN_MOVEMENT;
809 	}
810 
811 	return ret;
812 }
813 
eval_rook(Position * b,int pi)814 static etype eval_rook(Position *b, int pi)
815 {
816 	etype *pos_value = coefficients + IROOK_POS;
817 	PieceStruct *p = b->pieces + pi;
818 	etype ret=0;
819 	uint32 mask;
820 
821 	if (p->p > 0)
822 		ret += pos_value[p->pos];
823 	else
824 		ret += pos_value[mirror_square(p->pos)];
825 
826 	if (p->p > 0) {
827 		if ((mask = (b->topieces[p->pos] & ~b->pinned_mask & WROOK_MASK))) {
828 			ret += CONNECTED_ROOKS;
829 			if (YPOS(p->pos) == 6 && YPOS(b->pieces[ff_one(mask)].pos) == 6)
830 				ret += SEVENTH_RANK_ROOKS;
831 		}
832 	} else {
833 		if ((mask = (b->topieces[p->pos] & ~b->pinned_mask & BROOK_MASK))) {
834 			ret += CONNECTED_ROOKS;
835 			if (YPOS(p->pos) == 1 && YPOS(b->pieces[ff_one(mask)].pos) == 1)
836 				ret += SEVENTH_RANK_ROOKS;
837 		}
838 	}
839 
840 	return ret;
841 }
842 
843 
eval_bishop_xray(Position * b,int pi)844 static etype eval_bishop_xray(Position *b, int pi)
845 {
846 	PieceStruct *p = b->pieces + pi;
847 	etype ret=0;
848 	int xray=0;
849 	PieceStruct *p2;
850 	etype *xray_bonus = coefficients + IBISHOP_XRAY;
851 
852 	/* bishops get a bonus for Xray attacks on kings, queens or rooks */
853 	p2 = &PIECES(b, -p->p)[IKING];
854 	if (capture_map[p->p+KING][p->pos][p2->pos])
855 		xray++;
856 
857 	p2 = &PIECES(b, -p->p)[IQUEEN];
858 	if (p2->p && capture_map[p->p+KING][p->pos][p2->pos])
859 		xray++;
860 
861 	p2 = &PIECES(b, -p->p)[IQROOK];
862 	if (p2->p && capture_map[p->p+KING][p->pos][p2->pos])
863 		xray++;
864 
865 	p2 = &PIECES(b, -p->p)[IKROOK];
866 	if (p2->p && capture_map[p->p+KING][p->pos][p2->pos])
867 		xray++;
868 
869 	ret += xray_bonus[xray];
870 
871 	return ret;
872 }
873 
eval_bishop(Position * b,int pi)874 static etype eval_bishop(Position *b, int pi)
875 {
876 	etype ret=0;
877 	PieceStruct *p = b->pieces + pi;
878 	int x = XPOS(p->pos);
879 	int y = YPOS(p->pos);
880 
881 	/* bishops are good on outposts */
882 	if (p->p > 0) {
883 		if (y < 6 && y > 3 &&
884 		    (x == 0 || black_pawn_loc[x-1] <= y) &&
885 		    (x == 7 || black_pawn_loc[x+1] <= y)) {
886 			ret += BISHOP_OUTPOST;
887 			if ((x>0 && b->board[p->pos+SOUTH_WEST] == PAWN) ||
888 			    (x<7 && b->board[p->pos+SOUTH_EAST] == PAWN)) {
889 				ret += SUPPORTED_BISHOP_OUTPOST;
890 			}
891 		}
892 	} else {
893 		if (y > 1 && y < 4 &&
894 		    (x == 0 || white_pawn_loc[x-1] == 0 ||
895 		     white_pawn_loc[x-1] >= y) &&
896 		    (x == 7 || white_pawn_loc[x+1] == 0 ||
897 		     white_pawn_loc[x+1] >= y)) {
898 			ret += BISHOP_OUTPOST;
899 			if ((x>0 && b->board[p->pos+NORTH_WEST] == -PAWN) ||
900 			    (x<7 && b->board[p->pos+NORTH_EAST] == -PAWN)) {
901 			     ret += SUPPORTED_BISHOP_OUTPOST;
902 		     }
903 		}
904 	}
905 
906 
907 #if 1
908 	ret += eval_bishop_xray(b, pi);
909 #endif
910 	return ret;
911 }
912 
913 
eval_knight(Position * b,int pi)914 static etype eval_knight(Position *b, int pi)
915 {
916 	PieceStruct *p = b->pieces + pi;
917 	etype ret=0;
918 	int x = XPOS(p->pos);
919 	int y = YPOS(p->pos);
920         etype *pos_value = coefficients + IKNIGHT_POS;
921 
922 	if (p->p > 0)
923 		ret += pos_value[p->pos];
924 	else
925 		ret += pos_value[mirror_square(p->pos)];
926 
927 	/* knights are great on outposts */
928 	if (p->p > 0) {
929 		if (y < 6 && y > 3 &&
930 		    (x == 0 || black_pawn_loc[x-1] <= y) &&
931 		    (x == 7 || black_pawn_loc[x+1] <= y)) {
932 			ret += KNIGHT_OUTPOST;
933 			if ((x>0 && b->board[p->pos+SOUTH_WEST] == PAWN) ||
934 			    (x<7 && b->board[p->pos+SOUTH_EAST] == PAWN)) {
935 				ret += SUPPORTED_KNIGHT_OUTPOST;
936 			}
937 		}
938 	} else {
939 		if (y > 1 && y < 4 &&
940 		    (x == 0 || white_pawn_loc[x-1] == 0 ||
941 		     white_pawn_loc[x-1] >= y) &&
942 		    (x == 7 || white_pawn_loc[x+1] == 0 ||
943 		     white_pawn_loc[x+1] >= y)) {
944 			ret += KNIGHT_OUTPOST;
945 			if ((x>0 && b->board[p->pos+NORTH_WEST] == -PAWN) ||
946 			    (x<7 && b->board[p->pos+NORTH_EAST] == -PAWN)) {
947 			     ret += SUPPORTED_KNIGHT_OUTPOST;
948 		     }
949 		}
950 	}
951 
952 	return ret;
953 }
954 
955 
956 /* build a table of the most backward pawns in each file for each color */
build_pawn_loc(Position * b)957 static void build_pawn_loc(Position *b)
958 {
959 	int i;
960 	PieceStruct *p;
961 
962 	memset(white_pawn_loc, 0, sizeof(white_pawn_loc));
963 	memset(black_pawn_loc, 0, sizeof(black_pawn_loc));
964 
965 	p = &WHITEPIECES(b)[8];
966 	for (i=0;i<8;i++, p++)
967 		if (p->p == PAWN) {
968 			int x = XPOS(p->pos);
969 			int y = YPOS(p->pos);
970 			if (white_pawn_loc[x] == 0 ||
971 			    white_pawn_loc[x] > y)
972 				white_pawn_loc[x] = y;
973 		}
974 
975 	p = &BLACKPIECES(b)[8];
976 	for (i=0;i<8;i++, p++)
977 		if (p->p == -PAWN) {
978 			int x = XPOS(p->pos);
979 			int y = YPOS(p->pos);
980 			black_pawn_loc[x] = imax(black_pawn_loc[x], y);
981 		}
982 }
983 
984 
estimate_game_stage(Position * b,int root_node)985 void estimate_game_stage(Position *b, int root_node)
986 {
987 	int count;
988 	int last_stage = b->stage;
989 	if (!root_node)
990 		return;
991 
992 	count = pop_count[b->piece_mask & 0xFF] +
993 		pop_count[(b->piece_mask >> 16) & 0xFF];
994 
995 	if ((b->piece_mask & QUEEN_MASK) == QUEEN_MASK)
996 		count += 2;
997 
998 	if (b->piece_mask == b->material_mask) {
999 		b->stage = MATING;
1000 	} else if (count <= 6) {
1001 		b->stage = ENDING;
1002 	} else if (count >= 16 && (b->flags & FLAG_CAN_CASTLE)) {
1003 		b->stage = OPENING;
1004 	} else {
1005 		b->stage = MIDDLE;
1006 	}
1007 
1008 	coefficients = new_coefficients + b->stage*__COEFFS_PER_STAGE__;
1009 	b->piece_change |= KING_MASK;
1010 	b->piece_change |= (QUEEN_MASK & b->piece_mask);
1011 
1012 	if (b->stage != last_stage) {
1013 		lprintf(0, "*** Entering stage %d (%d)\n", b->stage, last_stage);
1014 		hash_reset();
1015 	}
1016 }
1017 
1018 
1019 /* try to discourage specific positional features - particularly in
1020    the opening */
specifics(Position * b)1021 static etype specifics(Position *b)
1022 {
1023 	etype ret = 0;
1024 
1025 	/* blocking the e or d pawn is a bad idea */
1026 	if (b->board[D3] && b->board[D2] == PAWN)
1027 		ret -= BLOCKED_DPAWN;
1028 
1029 	if (b->board[E3] && b->board[E2] == PAWN)
1030 		ret -= BLOCKED_EPAWN;
1031 
1032 	if (b->board[D6] && b->board[D7] == -PAWN)
1033 		ret -= -BLOCKED_DPAWN;
1034 
1035 	if (b->board[E6] && b->board[E7] == -PAWN)
1036 		ret -= -BLOCKED_EPAWN;
1037 
1038 
1039 	/* blocking in knights is a bad idea */
1040 	if (b->board[C3] && b->board[B1] == KNIGHT)
1041 		ret -= BLOCKED_KNIGHT;
1042 
1043 	if (b->board[F3] && b->board[G1] == KNIGHT)
1044 		ret -= BLOCKED_KNIGHT;
1045 
1046 	if (b->board[C6] && b->board[B8] == -KNIGHT)
1047 		ret -= -BLOCKED_KNIGHT;
1048 
1049 	if (b->board[F6] && b->board[G8] == -KNIGHT)
1050 		ret -= -BLOCKED_KNIGHT;
1051 
1052 	/* pairs of bishops are good */
1053 	if ((b->piece_mask & WBISHOP_MASK) == WBISHOP_MASK)
1054 		ret += BISHOP_PAIR;
1055 
1056 	if ((b->piece_mask & BBISHOP_MASK) == BBISHOP_MASK)
1057 		ret -= BISHOP_PAIR;
1058 
1059 	/* opposite bishops is drawish */
1060 	if ((b->piece_mask & BISHOP_MASK) == (WKBISHOP_MASK | BKBISHOP_MASK) ||
1061 	    (b->piece_mask & BISHOP_MASK) == (WQBISHOP_MASK | BQBISHOP_MASK)) {
1062 		if (b->b_material > b->w_material + STATIC_PAWN_VALUE/2)
1063 			ret += OPPOSITE_BISHOPS;
1064 		else if (b->w_material > b->b_material + STATIC_PAWN_VALUE/2)
1065 			ret -= OPPOSITE_BISHOPS;
1066 	}
1067 
1068 	/* these are some specialist endgame things */
1069 	if (b->w_material < b->b_material - STATIC_PAWN_VALUE &&
1070 	    b->stage == MATING) {
1071 		int kpos = WHITEPIECES(b)[IKING].pos;
1072 
1073 		ret -= NO_MATERIAL;
1074 
1075 		if ((b->piece_mask & BBISHOP_MASK) == BKBISHOP_MASK) {
1076 			ret -= (7-corner_distance(kpos)) * MATING_POSITION;
1077 		}
1078 		if ((b->piece_mask & BBISHOP_MASK) == BQBISHOP_MASK) {
1079 			ret -= (7-corner_distance(mirror_square(kpos))) * MATING_POSITION;
1080 		}
1081 	}
1082 
1083 	if (b->b_material < b->w_material - STATIC_PAWN_VALUE &&
1084 	    b->stage == MATING) {
1085 		int kpos = BLACKPIECES(b)[IKING].pos;
1086 
1087 		ret += NO_MATERIAL;
1088 
1089 		if ((b->piece_mask & WBISHOP_MASK) == WQBISHOP_MASK) {
1090 			ret += (7-corner_distance(kpos)) * MATING_POSITION;
1091 		}
1092 		if ((b->piece_mask & WBISHOP_MASK) == WKBISHOP_MASK) {
1093 			ret += (7-corner_distance(mirror_square(kpos))) * MATING_POSITION;
1094 		}
1095 	}
1096 
1097 
1098 	return ret;
1099 }
1100 
1101 
1102 #define base_pos_value (coefficients + IPOS_BASE)
1103 
1104 static etype null_pos_value[NUM_SQUARES];
1105 
1106 
1107 #define white_king_side (coefficients + IPOS_KINGSIDE)
1108 #define white_queen_side (coefficients + IPOS_QUEENSIDE)
1109 
1110 static etype black_king_side[NUM_SQUARES];
1111 static etype black_queen_side[NUM_SQUARES];
1112 
1113 static int new_pos_values;
1114 static etype *sq_p1, *sq_p2;
1115 
recalc_pos_values(Position * b)1116 static void recalc_pos_values(Position *b)
1117 {
1118 	Square wkpos, bkpos;
1119 	int flags = 0;
1120 
1121 	wkpos = WHITEPIECES(b)[IKING].pos;
1122 	bkpos = BLACKPIECES(b)[IKING].pos;
1123 
1124 	sq_p1 = null_pos_value;
1125 	sq_p2 = null_pos_value;
1126 
1127 	if (b->material_mask & QUEEN_MASK) {
1128 		if (XPOS(wkpos) > 3 && YPOS(wkpos) < 3) {
1129 			sq_p1 = white_king_side;
1130 			flags |= FLAG_WHITE_KINGSIDE;
1131 		} else if (XPOS(wkpos) < 3 && YPOS(wkpos) < 3) {
1132 			sq_p1 = white_queen_side;
1133 			flags |= FLAG_WHITE_QUEENSIDE;
1134 		}
1135 
1136 		if (XPOS(bkpos) > 3 && YPOS(bkpos) > 4) {
1137 			sq_p2 = black_king_side;
1138 			flags |= FLAG_BLACK_KINGSIDE;
1139 		} else if (XPOS(bkpos) < 3 && YPOS(bkpos) > 4) {
1140 			sq_p2 = black_queen_side;
1141 			flags |= FLAG_BLACK_QUEENSIDE;
1142 		}
1143 	}
1144 
1145 	if ((b->flags & FLAG_KQ_SIDE) == flags)
1146 		return;
1147 
1148 	invert(black_king_side, white_king_side);
1149 	invert(black_queen_side, white_queen_side);
1150 
1151 	new_pos_values = 1;
1152 
1153 	b->flags &= ~FLAG_KQ_SIDE;
1154 	b->flags |= flags;
1155 }
1156 
1157 
1158 /* this basically tries to answer the question "can one of the players
1159    profitably capture on that square, assuming there was something there
1160    to capture */
1161 
board_control1(Position * b)1162 static etype board_control1(Position *b)
1163 {
1164 	Square i, j;
1165 	int control;
1166 	etype total, v;
1167 	uint32 topieces, oldflight, fchange, mchange, old_pin_mask, pin_mask;
1168 	uint32 oldtopieces, xray_topieces, oldxray_topieces;
1169 	uint64 white_holes, black_holes, oldwhite_holes, oldblack_holes;
1170 	uint32 *top, *oldtop, *xray_top, *oldxray_top, *flight;
1171 	Piece *oldboard;
1172 
1173 	/* this is a mask which governs what piece can fly to a square
1174 	   given the smallest attacker on the square, so for example, the
1175 	   0x00FC0000 entry means that any black piece except a queen
1176 	   or king can fly to a square that is controlled by black if
1177 	   the square is covered by a white rook */
1178 	static const uint32 flight_mask[32] = {
1179 		0x00FE0000, 0x00FE0000, 0x00FC0000, 0x00FC0000,
1180 		0x00F00000, 0x00F00000, 0x00F00000, 0x00F00000,
1181 		0x00000000, 0x00000000, 0x00000000, 0x00000000,
1182 		0x00000000, 0x00000000, 0x00000000, 0x00000000,
1183 
1184 		0x00FE, 0x00FE, 0x00FC, 0x00FC,
1185 		0x00F0, 0x00F0, 0x00F0, 0x00F0,
1186 		0x0000, 0x0000, 0x0000, 0x0000,
1187 		0x0000, 0x0000, 0x0000, 0x0000
1188 	};
1189 
1190 	if (b->stage == MATING)
1191 		return 0;
1192 
1193 	top = b->topieces;
1194 #if USE_SLIDING_CONTROL
1195 	xray_top = b->xray_topieces;
1196 #endif
1197 	flight = b->flight;
1198 
1199 	white_holes = b->white_holes;
1200 	black_holes = b->black_holes;
1201 
1202 	recalc_pos_values(b);
1203 
1204 	if (b->oldb && (b->oldb->flags & FLAG_EVAL_DONE) && !new_pos_values) {
1205 		oldtop = b->oldb->topieces;
1206 #if USE_SLIDING_CONTROL
1207 		oldxray_top = b->oldb->xray_topieces;
1208 #endif
1209 		oldwhite_holes = b->oldb->white_holes;
1210 		oldblack_holes = b->oldb->black_holes;
1211 		oldboard = b->oldb->board;
1212 		old_pin_mask = ~b->oldb->pinned_mask;
1213 		memcpy(b->mobility, b->oldb->mobility, sizeof(b->mobility));
1214 	} else {
1215 		static uint32 dummy[64];
1216 		static Piece dummy2[64];
1217 #if USE_SLIDING_CONTROL
1218 		static uint32 xray_dummy[64];
1219 		oldxray_top = xray_dummy;
1220 #endif
1221 		oldtop = dummy;
1222 
1223 		oldboard = dummy2;
1224 		b->board_control = 0;
1225 		b->attacking_mask = 0;
1226 		old_pin_mask = ~0;
1227 		memset(b->cont, 0, sizeof(b->cont));
1228 		memset(b->control, 0, sizeof(b->control));
1229 		memset(b->flight, 0, sizeof(b->flight));
1230 		memset(b->mobility, 0, sizeof(b->mobility));
1231 		memset(b->safe_mobility, 0, sizeof(b->safe_mobility));
1232 		b->white_moves = b->black_moves = 0;
1233 		new_pos_values = 0;
1234 	}
1235 
1236 	pin_mask = ~b->pinned_mask;
1237 
1238 	total = b->board_control;
1239 
1240 	for (i=A1;i<=H8;i++) {
1241 		topieces = top[i] & pin_mask;
1242 		oldtopieces = oldtop[i] & old_pin_mask;
1243 #if USE_SLIDING_CONTROL
1244 		xray_topieces = xray_top[i];
1245 		oldxray_topieces = oldxray_top[i];
1246 #endif
1247 
1248 		if (topieces == oldtopieces && b->board[i] == oldboard[i]
1249 #if USE_SLIDING_CONTROL
1250 		    && xray_topieces == oldxray_topieces
1251 #endif
1252 		    ) {
1253 			continue;
1254 		}
1255 
1256 		/* if there is something on the square then recalc that piece
1257 		   as well */
1258 		if (b->board[i])
1259 			b->piece_change |= (1<<b->pboard[i]);
1260 
1261 		/* something has changed on the square - we need to recalculate
1262 		   everything */
1263 
1264 		oldflight = flight[i];
1265 
1266 		/* we define two control values, one taking into
1267 		   account whites pins,
1268 		   and the other taking into account blacks pins */
1269 		control = get_control(b, topieces, b->board[i], i);
1270 #if 0
1271 		if (debug)
1272 			lprintf(0,"control %s %d\n", posstr(i), control);
1273 #endif
1274 		/* now the trapped pieces stuff. we need to work out what
1275 		   pieces can flee to this square
1276 
1277 		   a square can be used as a flight square only if the
1278 		   piece would not be hung when it moves there.
1279 
1280 		   we use the flight mask to shortcut this calculation
1281 		   */
1282 		if (control > 0 && b->board[i] <= 0) {
1283 			if (topieces & BLACK_MASK) {
1284 				flight[i] = flight_mask[fl_one(topieces&BLACK_MASK)] & topieces & pin_mask;
1285 			} else {
1286 				flight[i] = WHITE_MASK & topieces & pin_mask;
1287 			}
1288 		} else if (control < 0 && b->board[i] >= 0) {
1289 			if (topieces & WHITE_MASK) {
1290 				flight[i] = flight_mask[fl_one(topieces&WHITE_MASK)] & topieces & pin_mask;
1291 			} else {
1292 				flight[i] = BLACK_MASK & topieces & pin_mask;
1293 			}
1294 		} else {
1295 			flight[i] = 0;
1296 		}
1297 
1298 		flight[i] &= b->piece_mask;
1299 
1300 		/* this xor tells us what pieces have changed in their
1301 		   safe mobility */
1302 		fchange = (oldflight ^ flight[i]) & b->piece_mask;
1303 
1304 		while (fchange & WHITE_MASK) {
1305 			j = ff_one(fchange & WHITE_MASK);
1306 			fchange &= ~(1<<j);
1307 			if (flight[i] & (1<<j)) {
1308 				b->safe_mobility[j]++;
1309 				b->white_moves++;
1310 			} else {
1311 				b->safe_mobility[j]--;
1312 				b->white_moves--;
1313 			}
1314 		}
1315 
1316 		while (fchange) {
1317 			j = ff_one(fchange);
1318 			fchange &= ~(1<<j);
1319 			if (flight[i] & (1<<j)) {
1320 				b->safe_mobility[j]++;
1321 				b->black_moves++;
1322 			} else {
1323 				b->safe_mobility[j]--;
1324 				b->black_moves--;
1325 			}
1326 		}
1327 
1328 		/* this xor tells us what pieces have changed in their
1329 		   mobility */
1330 		mchange = (oldtopieces ^ topieces) & b->piece_mask;
1331 
1332 		while (mchange & WHITE_MASK) {
1333 			j = ff_one(mchange & WHITE_MASK);
1334 			mchange &= ~(1<<j);
1335 			if (topieces & (1<<j)) {
1336 				b->mobility[j]++;
1337 			} else {
1338 				b->mobility[j]--;
1339 			}
1340 		}
1341 
1342 		while (mchange) {
1343 			j = ff_one(mchange);
1344 			mchange &= ~(1<<j);
1345 			if (topieces & (1<<j)) {
1346 				b->mobility[j]++;
1347 			} else {
1348 				b->mobility[j]--;
1349 			}
1350 		}
1351 
1352 		/* the board control itself */
1353 		if (control > 0) {
1354 			v = base_pos_value[i] + sq_p1[i];
1355 		} else if (control < 0) {
1356 			v = -(base_pos_value[mirror_square(i)] + sq_p2[i]);
1357 		} else {
1358 			v = 0;
1359 		}
1360 
1361 		b->cont[i] = SIGN(control);
1362 		if (control == 0)
1363 			b->cont[i] = 0;
1364 		total += v - b->control[i];
1365 		b->control[i] = v;
1366 	}
1367 
1368 	b->board_control = total;
1369 
1370 	return total;
1371 }
1372 
1373 #define attack_value (coefficients + IATTACK_VALUE)
board_control2(Position * b)1374 static etype board_control2(Position *b)
1375 {
1376 	Square i, j;
1377 	int numblack, numwhite;
1378 	etype ret;
1379 	uint32 hung, attacking;
1380 
1381 	numblack = 0;
1382 	numwhite = 0;
1383 	hung = 0;
1384 	attacking = 0;
1385 
1386 	if (b->stage == MATING)
1387 		return 0;
1388 
1389 	for (i=1;i<16;i++) {
1390 		if (!b->pieces[i].p) continue;
1391 		j = b->pieces[i].pos;
1392 
1393 		if (b->topieces[j] & BLACK_MASK) {
1394 			attacking |= b->topieces[j] & BLACK_MASK;
1395 			numblack += pop_count[(b->topieces[j]>>16) & 0xFF];
1396 			if (b->control[j] <= 0) {
1397 				if (b->control[j] < 0)
1398 					hung |= (1<<i);
1399 			}
1400 		}
1401 	}
1402 
1403 	for (i=17;i<32;i++) {
1404 		if (!b->pieces[i].p) continue;
1405 		j = b->pieces[i].pos;
1406 
1407 		if (b->topieces[j] & WHITE_MASK) {
1408 			attacking |= b->topieces[j] & WHITE_MASK;
1409 			numwhite += pop_count[b->topieces[j] & 0xFF];
1410 			if (b->control[j] >= 0) {
1411 				if (b->control[j] > 0)
1412 					hung |= (1<<i);
1413 			}
1414 		}
1415 	}
1416 
1417 	ret = attack_value[numwhite] - attack_value[numblack];
1418 
1419 	attacking &= b->piece_mask;
1420 	b->piece_change |= b->attacking_mask ^ attacking;
1421 	b->hung_mask = hung;
1422 	b->attacking_mask = attacking;
1423 
1424 	if (debug) {
1425 		lprintf(0,"attacking_mask=%08x\n", b->attacking_mask);
1426 		lprintf(0,"hung_mask=%08x\n", b->hung_mask);
1427 	}
1428 
1429 	return ret;
1430 }
1431 
1432 
empty_line(Position * b,int sq1,int sq2)1433 static int empty_line(Position *b, int sq1, int sq2)
1434 {
1435 	int dir, dx, dy;
1436 
1437 	dx = XPOS(sq1) - XPOS(sq2);
1438 	dy = YPOS(sq1) - YPOS(sq2);
1439 
1440 	dir = 0;
1441 	if (dy > 0)
1442 		dir += SOUTH;
1443 	else if (dy < 0)
1444 		dir += NORTH;
1445 
1446 	if (dx > 0)
1447 		dir += WEST;
1448 	else if (dx < 0)
1449 		dir += EAST;
1450 
1451 	sq1 += dir;
1452 
1453 	while (sq1 != sq2) {
1454 		if (b->board[sq1]) return 0;
1455 		sq1 += dir;
1456 	}
1457 
1458 	return 1;
1459 }
1460 
1461 #define trapped_step (coefficients + ITRAPPED_STEP)
1462 
mobility_fn(Position * b,int pi)1463 static etype mobility_fn(Position *b, int pi)
1464 {
1465 	static const int mobility_threshold[KING+1] = {0, 0, 6, 5, 4, 6, 0};
1466 	int mobility;
1467 	etype ret=0;
1468 	Piece p = abs(b->pieces[pi].p);
1469 	Square pos = b->pieces[pi].pos;
1470 	int y = YPOS(b->pieces[pi].pos);
1471 	etype *mobility_table[KING+1] = {NULL, NULL,
1472 					         &coefficients[IKNIGHT_MOBILITY],
1473 						 &coefficients[IBISHOP_MOBILITY],
1474 						 &coefficients[IROOK_MOBILITY],
1475 						 &coefficients[IQUEEN_MOBILITY],
1476 						 &coefficients[IKING_MOBILITY]};
1477 
1478 	etype *safe_mobility_table[KING+1] =
1479 	{NULL, NULL, &coefficients[IKNIGHT_SMOBILITY],
1480 		 &coefficients[IBISHOP_SMOBILITY],
1481 		 &coefficients[IROOK_SMOBILITY],
1482 		 &coefficients[IQUEEN_SMOBILITY],
1483 		 &coefficients[IKING_SMOBILITY]};
1484 
1485 	if (p != b->pieces[pi].p)
1486 		y = 7-y;
1487 
1488 	mobility = b->mobility[pi];
1489 	if (mobility >= 10) {
1490 		mobility = 9;
1491 	}
1492 
1493 	if (mobility_table[p]) {
1494 		ret = mobility_table[p][y*10+mobility];
1495 	}
1496 
1497 	if (b->mobility[pi] < mobility_threshold[p] &&
1498 	    !(b->attacking_mask & (1<<pi))) {
1499 		if (debug)
1500 			lprintf(0,"useless %s\n",
1501 				posstr(pos));
1502 		ret -= USELESS_PIECE;
1503 	}
1504 
1505 	mobility = b->safe_mobility[pi];
1506 	if (mobility >= 10) {
1507 		mobility = 9;
1508 	}
1509 
1510 	if (safe_mobility_table[p])
1511 		ret += safe_mobility_table[p][y*10+mobility];
1512 
1513 	if (b->safe_mobility[pi] == 0) {
1514 		if (b->pieces[pi].p > 0) {
1515 			ret -= trapped_step[YPOS(pos)];
1516 		} else {
1517 			ret -= trapped_step[(7-YPOS(pos))];
1518 		}
1519 	}
1520 
1521 	return ret;
1522 }
1523 
1524 
piece_values(Position * b)1525 static etype piece_values(Position *b)
1526 {
1527 	etype v;
1528 	etype total;
1529 	int i;
1530 	uint32 piece_change;
1531 
1532 	piece_change = b->piece_change;
1533 
1534 	total = 0;
1535 
1536 	for (i=0;i<32;i++) {
1537 		if (!b->pieces[i].p) continue;
1538 		if (!(piece_change & (1<<i)) && b->oldb) {
1539 			total += b->piece_values[i];
1540 		} else {
1541 			switch (b->pieces[i].p) {
1542 			case PAWN:
1543 				v = eval_white_pawn(b, i);
1544 				break;
1545 			case KNIGHT:
1546 				v = eval_knight(b, i);
1547 				break;
1548 			case BISHOP:
1549 				v = eval_bishop(b, i);
1550 				break;
1551 			case ROOK:
1552 				v = eval_rook(b, i);
1553 				break;
1554 			case QUEEN:
1555 				v = eval_queen(b, i);
1556 				break;
1557 			case KING:
1558 				v = eval_white_king(b, i);
1559 				break;
1560 			case -PAWN:
1561 				v = -eval_black_pawn(b, i);
1562 				break;
1563 			case -KNIGHT:
1564 				v = -eval_knight(b, i);
1565 				break;
1566 			case -BISHOP:
1567 				v = -eval_bishop(b, i);
1568 				break;
1569 			case -ROOK:
1570 				v = -eval_rook(b, i);
1571 				break;
1572 			case -QUEEN:
1573 				v = -eval_queen(b, i);
1574 				break;
1575 			case -KING:
1576 				v = -eval_black_king(b, i);
1577 				break;
1578 			default:
1579 				v = 0;
1580 				lprintf(0,"no piece? i=%d pos=%s p=%d\n",
1581 					i, posstr(b->pieces[i].pos),
1582 					b->pieces[i].p);
1583 #if 0
1584 				beep(20);
1585 				sleep(120);
1586 #endif
1587 				break;
1588 			}
1589 
1590 			total += v;
1591 			b->piece_values[i] = v;
1592 		}
1593 	}
1594 
1595 	if (debug) {
1596 		lprintf(0,"white pvalues:  \n");
1597 		for (i=0;i<16;i++)
1598 			if (b->pieces[i].p)
1599 				lprintf(0,"%+3d ", b->piece_values[i]);
1600 			else
1601 				lprintf(0,"*** ");
1602 		lprintf(0,"\n");
1603 		lprintf(0,"black pvalues: \n");
1604 		for (i=16;i<32;i++)
1605 			if (b->pieces[i].p)
1606 				lprintf(0,"%+3d ", -b->piece_values[i]);
1607 			else
1608 				lprintf(0,"*** ");
1609 		lprintf(0,"\n");
1610 	}
1611 
1612 	b->piece_change = 0;
1613 
1614 	return total;
1615 }
1616 
1617 
eval_mobility(Position * b)1618 static etype eval_mobility(Position *b)
1619 {
1620 	int i;
1621 	etype total;
1622 
1623 	total = 0;
1624 
1625 	if (b->stage == MATING)
1626 		return 0;
1627 
1628 	for (i=0;i<16;i++) {
1629 		if (!(b->piece_mask & (1<<i))) continue;
1630 		total += mobility_fn(b, i);
1631 	}
1632 
1633 	for (i=16;i<32;i++) {
1634 		if (!(b->piece_mask & (1<<i))) continue;
1635 		total -= mobility_fn(b, i);
1636 	}
1637 
1638 	if (debug) {
1639 		lprintf(0,"white safe mobility:  \n");
1640 		for (i=0;i<16;i++)
1641 			if (b->pieces[i].p)
1642 				lprintf(0,"%+3d ", b->safe_mobility[i]);
1643 			else
1644 				lprintf(0,"*** ");
1645 		lprintf(0,"\n");
1646 		lprintf(0,"black safe mobility: \n");
1647 		for (i=16;i<32;i++)
1648 			if (b->pieces[i].p)
1649 				lprintf(0,"%+3d ", b->safe_mobility[i]);
1650 			else
1651 				lprintf(0,"*** ");
1652 		lprintf(0,"\n");
1653 		lprintf(0,"white mobility:  \n");
1654 		for (i=0;i<16;i++)
1655 			if (b->pieces[i].p)
1656 				lprintf(0,"%+3d ", b->mobility[i]);
1657 			else
1658 				lprintf(0,"*** ");
1659 		lprintf(0,"\n");
1660 		lprintf(0,"black mobility: \n");
1661 		for (i=16;i<32;i++)
1662 			if (b->pieces[i].p)
1663 				lprintf(0,"%+3d ", b->mobility[i]);
1664 			else
1665 				lprintf(0,"*** ");
1666 		lprintf(0,"\n");
1667 	}
1668 
1669 	return total;
1670 }
1671 
egtb(Position * b)1672 int egtb(Position *b)
1673 {
1674 	int ret = 0;
1675 
1676 #if USE_EGTB
1677 	if (pop_count32(b->material_mask) < 5 ||
1678 	    (pop_count32(b->material_mask) == 5 &&
1679 	     ((b->w_material == KING_VALUE + ROOK_VALUE + KNIGHT_VALUE &&
1680 	       b->b_material == KING_VALUE + ROOK_VALUE) ||
1681 	      (b->b_material == KING_VALUE + ROOK_VALUE + KNIGHT_VALUE &&
1682 	       b->w_material == KING_VALUE + ROOK_VALUE) ||
1683 	      (b->w_material == KING_VALUE + ROOK_VALUE + BISHOP_VALUE &&
1684 	       b->b_material == KING_VALUE + ROOK_VALUE) ||
1685 	      (b->b_material == KING_VALUE + ROOK_VALUE + BISHOP_VALUE &&
1686 	       b->w_material == KING_VALUE + ROOK_VALUE))))
1687 		ret = 1;
1688 #endif
1689 	return ret;
1690 }
1691 
1692 
no_material(Position * b)1693 int no_material(Position *b)
1694 {
1695 
1696 	if (((b->material_mask & WHITE_MASK) == (b->piece_mask & WHITE_MASK) &&
1697 	     (b->w_material <= emax(KING_VALUE+BISHOP_VALUE, KING_VALUE+KNIGHT_VALUE) ||
1698 	      b->w_material == KING_VALUE+2*KNIGHT_VALUE)) &&
1699 	    ((b->material_mask & BLACK_MASK) == (b->piece_mask & BLACK_MASK) &&
1700 	     (b->b_material <= emax(KING_VALUE+BISHOP_VALUE, KING_VALUE+KNIGHT_VALUE) ||
1701 	      b->b_material == KING_VALUE+2*KNIGHT_VALUE))) {
1702 		return 1;
1703 	}
1704 
1705 	return 0;
1706 }
1707 
1708 #define piece_trade_bonus (coefficients + IPIECE_TRADE_BONUS)
1709 #define pawn_trade_bonus (coefficients + IPAWN_TRADE_BONUS)
1710 
1711 /* this is called only when there are no pawns on the board.
1712    eval_tactics must already have been called */
check_material(Position * b,etype ret0)1713 static etype check_material(Position *b, etype ret0)
1714 {
1715 	etype ret = ret0;
1716 	int num = 0;
1717 	etype v, vdraw = draw_value(b);
1718 
1719 #if USE_EGTB
1720 	if (pop_count32(b->material_mask) < 5 ||
1721 	    (pop_count32(b->material_mask) == 5 &&
1722 	     ((b->w_material == KING_VALUE + ROOK_VALUE + KNIGHT_VALUE &&
1723 	      b->b_material == KING_VALUE + ROOK_VALUE) ||
1724 	      (b->b_material == KING_VALUE + ROOK_VALUE + KNIGHT_VALUE &&
1725 	       b->w_material == KING_VALUE + ROOK_VALUE) ||
1726 	      (b->w_material == KING_VALUE + ROOK_VALUE + BISHOP_VALUE &&
1727 	       b->b_material == KING_VALUE + ROOK_VALUE) ||
1728 	      (b->b_material == KING_VALUE + ROOK_VALUE + BISHOP_VALUE &&
1729 	       b->w_material == KING_VALUE + ROOK_VALUE)))) {
1730 
1731 		EGInit();
1732 		if (EGTBScore(b, &v)) {
1733 			if (v == 0)
1734 				ret = vdraw;
1735 			else
1736 				ret = next_to_play(b)*v;
1737 			if (debug)
1738 				lprintf(0, "EGTB: %d\n", ret);
1739 			b->flags |= FLAG_EGTB_EVAL;
1740 			return ret - ret0;
1741 		}
1742 	}
1743 #endif
1744 
1745 	if (b->material_mask == b->piece_mask && b->tactics == 0) {
1746 		/* queen and king vs queen and king is probably a draw */
1747 		if (b->w_material == KING_VALUE+QUEEN_VALUE &&
1748 		    b->b_material == KING_VALUE+QUEEN_VALUE) {
1749 			ret = vdraw * 2;
1750 			b->flags |= FLAG_ACCEPT_DRAW;
1751 			return ret - ret0;
1752 		}
1753 
1754 		/* king and rook vs king and rook is almost always a draw */
1755 		if (b->w_material == KING_VALUE+ROOK_VALUE &&
1756 		    b->b_material == KING_VALUE+ROOK_VALUE) {
1757 			ret = vdraw * 2;
1758 			b->flags |= FLAG_ACCEPT_DRAW;
1759 			return ret - ret0;
1760 		}
1761 	}
1762 
1763 	/* rook vs bishop or knight (+ pawn) is not good for whoever has the rook */
1764 	if (b->w_material == KING_VALUE+ROOK_VALUE &&
1765 	    b->b_material <= KING_VALUE+ROOK_VALUE &&
1766 	    (b->piece_mask & BMINOR_MASK)) {
1767 		ret = -NEAR_DRAW_VALUE;
1768 		return ret - ret0;
1769 	}
1770 	if (b->b_material == KING_VALUE+ROOK_VALUE &&
1771 	    b->w_material <= KING_VALUE+ROOK_VALUE &&
1772 	    (b->piece_mask & WMINOR_MASK)) {
1773 		ret = NEAR_DRAW_VALUE;
1774 		return ret - ret0;
1775 	}
1776 
1777 	/* rook and minor vs rook and pawns is unlikely to be good
1778 	   for the guy with the rook and minor */
1779 	if ((b->w_material == KING_VALUE+ROOK_VALUE+BISHOP_VALUE ||
1780 	     b->w_material == KING_VALUE+ROOK_VALUE+KNIGHT_VALUE) &&
1781 	    b->b_material <=  KING_VALUE+ROOK_VALUE+BISHOP_VALUE &&
1782 	    (b->piece_mask & BROOK_MASK)) {
1783 		ret = -NEAR_DRAW_VALUE;
1784 		return ret - ret0;
1785 	}
1786 
1787 	if ((b->b_material == KING_VALUE+ROOK_VALUE+BISHOP_VALUE ||
1788 	     b->b_material == KING_VALUE+ROOK_VALUE+KNIGHT_VALUE) &&
1789 	    b->w_material <=  KING_VALUE+ROOK_VALUE+BISHOP_VALUE &&
1790 	    (b->piece_mask & WROOK_MASK)) {
1791 		ret = NEAR_DRAW_VALUE;
1792 		return ret - ret0;
1793 	}
1794 
1795 	if ((b->material_mask & WHITE_MASK) == (b->piece_mask & WHITE_MASK) &&
1796 	    (b->w_material <= emax(KING_VALUE+BISHOP_VALUE, KING_VALUE+KNIGHT_VALUE) ||
1797 	     b->w_material == KING_VALUE+2*KNIGHT_VALUE)) {
1798 		/* white has insufficient material to mate */
1799 		ret = emin(ret, vdraw);
1800 	}
1801 
1802 	if ((b->material_mask & BLACK_MASK) == (b->piece_mask & BLACK_MASK) &&
1803 	    (b->b_material <= emax(KING_VALUE+BISHOP_VALUE, KING_VALUE+KNIGHT_VALUE) ||
1804 	     b->b_material == KING_VALUE+2*KNIGHT_VALUE)) {
1805 		/* black has insufficient material to mate */
1806 		ret = emax(ret, vdraw);
1807 	}
1808 
1809 	if (ret == vdraw && ret0 != ret) {
1810 		b->flags |= FLAG_ACCEPT_DRAW;
1811 		if (debug)
1812 			lprintf(0,"will accept draw\n");
1813 		return ret - ret0;
1814 	} else {
1815 		b->flags &= ~FLAG_ACCEPT_DRAW;
1816 	}
1817 
1818 	/* push it nearer a draw as the fifty move mark approaches */
1819 	if (b->stage != MATING && ret != 0 && b->fifty_count > 20) {
1820 		ret = ((128 - (b->fifty_count-20)) * ret) / 128;
1821 	}
1822 
1823 	if (b->w_material >= b->b_material + (0.8*STATIC_PAWN_VALUE)) {
1824 		/* encourage piece trading but not pawn trading */
1825 		num = pop_count32(b->piece_mask);
1826 		ret += piece_trade_bonus[num];
1827 		num = pop_count32(b->material_mask & ~b->piece_mask);
1828 		ret -= pawn_trade_bonus[num];
1829 	}
1830 
1831 	if (b->b_material >= b->w_material + (0.8*STATIC_PAWN_VALUE)) {
1832 		/* encourage pawn trading but not piece trading */
1833 		num = pop_count32(b->piece_mask);
1834 		ret -= piece_trade_bonus[num];
1835 		num = pop_count32(b->material_mask & ~b->piece_mask);
1836 		ret += pawn_trade_bonus[num];
1837 	}
1838 
1839 	return ret - ret0;
1840 }
1841 
1842 #define q_king_attack_computer (coefficients + IQ_KING_ATTACK_COMPUTER)
1843 #define q_king_attack_opponent (coefficients + IQ_KING_ATTACK_OPPONENT)
1844 #define noq_king_attack_computer (coefficients + INOQ_KING_ATTACK_COMPUTER)
1845 #define noq_king_attack_opponent (coefficients + INOQ_KING_ATTACK_OPPONENT)
1846 
white_king_safety(Position * b)1847 static etype white_king_safety(Position *b)
1848 {
1849 	etype *king_attack_computer, *king_attack_opponent;
1850 	etype file_safety;
1851 	etype ret=0;
1852 	int num = 0;
1853 	Square x1, x2, y1, y2, kpos, x, y, pos;
1854 	uint32 mask=0;
1855 
1856 	if (!(b->piece_mask & BQUEEN_MASK)) {
1857 		king_attack_computer = q_king_attack_computer;
1858 		king_attack_opponent = q_king_attack_opponent;
1859 		file_safety = QUEEN_FILE_SAFETY;
1860 	} else {
1861 		king_attack_computer = noq_king_attack_computer;
1862 		king_attack_opponent = noq_king_attack_opponent;
1863 		file_safety = NOQUEEN_FILE_SAFETY;
1864 	}
1865 
1866 	/* the opponents queen is on the board, we need to worry about
1867 	   king safety. The major components is "king attack", which
1868 	   is proportional to the number of attacks made by enemy
1869 	   pieces on the king. To find this we need to loop over the squares
1870 	   around the king */
1871 
1872 	kpos = WHITEPIECES(b)[IKING].pos;
1873 
1874 	if (XPOS(kpos) == 0) {
1875 		x1 = 0; x2 = 1;
1876 	} else if (XPOS(kpos) == 7) {
1877 		x1 = 6; x2 = 7;
1878 	} else {
1879 		x1 = XPOS(kpos)-1; x2 = x1+2;
1880 	}
1881 
1882 	if (YPOS(kpos) == 0) {
1883 		y1 = 0; y2 = 1;
1884 	} else if (YPOS(kpos) == 7) {
1885 		y1 = 6; y2 = 7;
1886 	} else {
1887 		y1 = YPOS(kpos)-1; y2 = y1+2;
1888 	}
1889 
1890 	for (x=x1;x<=x2;x++)
1891 		for (y=y1;y<=y2;y++) {
1892 			pos = POSN(x, y);
1893 			mask |= ((b->topieces[pos] & ~BKING_MASK) >> 16) & 0xFF;
1894 #if USE_SLIDING_CONTROL
1895 			mask |= (b->xray_topieces[pos] >> 16) & 0xFF;
1896 #endif
1897 		}
1898 
1899 	num = pop_count[mask];
1900 	if ((BROOK_MASK >> 16) & mask)
1901 		++num;
1902 
1903 	if (b->flags & FLAG_COMPUTER_WHITE) {
1904 		ret = -king_attack_computer[num];
1905 	} else {
1906 		ret = -king_attack_opponent[num];
1907 	}
1908 
1909 	/* now check for open files next to the king */
1910 
1911 	for (x=x1; x<=x2; x++) {
1912 		if (white_pawn_loc[x] == 0 && black_pawn_loc[x] == 0)
1913 			ret -= file_safety;
1914 	}
1915 
1916 	return ret;
1917 }
1918 
black_king_safety(Position * b)1919 static etype black_king_safety(Position *b)
1920 {
1921 	etype *king_attack_computer, *king_attack_opponent;
1922 	etype file_safety;
1923 	etype ret=0;
1924 	int num = 0;
1925 	uint32 mask=0;
1926 	Square x1, x2, y1, y2, kpos, x, y, pos;
1927 
1928 	if (!(b->piece_mask & WQUEEN_MASK)) {
1929 		king_attack_computer = q_king_attack_computer;
1930 		king_attack_opponent = q_king_attack_opponent;
1931 		file_safety = QUEEN_FILE_SAFETY;
1932 	} else {
1933 		king_attack_computer = noq_king_attack_computer;
1934 		king_attack_opponent = noq_king_attack_opponent;
1935 		file_safety = NOQUEEN_FILE_SAFETY;
1936 	}
1937 
1938 	/* the opponents queen is on the board, we need to worry about
1939 	   king safety. The major components is "king attack", which
1940 	   is proportional to the number of attacks made by enemy
1941 	   pieces on the king. To find this we need to loop over the squares
1942 	   around the king */
1943 
1944 	kpos = BLACKPIECES(b)[IKING].pos;
1945 
1946 	if (XPOS(kpos) == 0) {
1947 		x1 = 0; x2 = 1;
1948 	} else if (XPOS(kpos) == 7) {
1949 		x1 = 6; x2 = 7;
1950 	} else {
1951 		x1 = XPOS(kpos)-1; x2 = x1+2;
1952 	}
1953 
1954 	if (YPOS(kpos) == 0) {
1955 		y1 = 0; y2 = 1;
1956 	} else if (YPOS(kpos) == 7) {
1957 		y1 = 6; y2 = 7;
1958 	} else {
1959 		y1 = YPOS(kpos)-1; y2 = y1+2;
1960 	}
1961 
1962 	for (x=x1;x<=x2;x++)
1963 		for (y=y1;y<=y2;y++) {
1964 			pos = POSN(x, y);
1965 			mask |= b->topieces[pos] & ~WKING_MASK & 0xFF;
1966 #if USE_SLIDING_CONTROL
1967 			mask |= b->xray_topieces[pos] & 0xFF;
1968 #endif
1969 		}
1970 
1971 	num = pop_count[mask];
1972 	if (mask & WROOK_MASK)
1973 		++num;
1974 
1975 	if (b->flags & FLAG_COMPUTER_WHITE)
1976 		ret = -king_attack_opponent[num];
1977 	else
1978 		ret = -king_attack_computer[num];
1979 
1980 	/* now check for open files next to the king */
1981 
1982 	for (x=x1; x<=x2; x++) {
1983 		if (black_pawn_loc[x] == 0 && white_pawn_loc[x] == 0)
1984 			ret -= file_safety;
1985 	}
1986 
1987 	return ret;
1988 }
1989 
king_safety(Position * b)1990 static etype king_safety(Position *b)
1991 {
1992 	return white_king_safety(b) - black_king_safety(b);
1993 }
1994 
1995 /* an overloaded piece p is one that defends more than one other piece
1996    or pawn that would become hung if p's support was removed */
1997 
1998 #define overloaded_penalty (coefficients + IOVERLOADED_PENALTY)
overloaded_pieces(Position * b)1999 static etype overloaded_pieces(Position *b)
2000 {
2001 	unsigned pi;
2002 	etype ret = 0;
2003 	int i;
2004 	Square pos;
2005 	uint32 mask;
2006 	int white_overloaded[8];
2007 	int black_overloaded[8];
2008 
2009 	memset(white_overloaded, 0, sizeof(white_overloaded));
2010 	memset(black_overloaded, 0, sizeof(black_overloaded));
2011 
2012 	for (i=0;i<32;i++) {
2013 		if (!b->pieces[i].p) continue;
2014 		pos = b->pieces[i].pos;
2015 		if (b->cont[pos] != 0 || b->topieces[pos] == 0)
2016 			continue;
2017 		if (b->board[pos] > 0) {
2018 			mask = b->topieces[pos] & WPIECE_MASK;
2019 			while (mask) {
2020 				pi = ff_one(mask);
2021 				mask &= ~(1<<pi);
2022 				++white_overloaded[pi];
2023 			}
2024 		} else {
2025 			mask = (b->topieces[pos] & BPIECE_MASK) >> 16;
2026 			while (mask) {
2027 				pi = ff_one(mask);
2028 				mask &= ~(1<<pi);
2029 				++black_overloaded[pi];
2030 			}
2031 		}
2032 	}
2033 
2034 	for (pi=0; pi<8; pi++) {
2035 		if (white_overloaded[pi] > 1) {
2036 			ret -= overloaded_penalty[white_overloaded[pi]-2];
2037 		}
2038 		if (black_overloaded[pi] > 1) {
2039 			ret += overloaded_penalty[black_overloaded[pi]-2];
2040 		}
2041 	}
2042 
2043 	return ret;
2044 }
2045 
2046 
2047 
2048 
draw_value(Position * b)2049 etype draw_value(Position *b)
2050 {
2051 	etype ret = DRAW_VALUE;
2052 
2053 #if (LEARN_EVAL && !NO_STALEMATE_LEARN)
2054 	if (state->computer > 0)
2055 		return ret;
2056 	else
2057 		return -ret;
2058 #endif
2059 	if (state->computer > 0)
2060 		ret += 0.05*STATIC_PAWN_VALUE*state->rating_change;
2061 	else
2062 		ret -= 0.05*STATIC_PAWN_VALUE*state->rating_change;
2063 
2064 	if (ABS(ret) > STATIC_PAWN_VALUE)
2065 		ret = SIGN(ret)*STATIC_PAWN_VALUE;
2066 
2067 	return ret;
2068 }
2069 
2070 
find_pins(Position * b)2071 static etype find_pins(Position *b)
2072 {
2073 	int i, j, k;
2074 	uint32 pinner_mask;
2075 
2076 	/* to find pins we loop over all pieces, looking for pieces
2077 	   that are under attack by sliding pieces (but not if they
2078 	   themselves are sliding pieces of the same type!). Then we
2079 	   check to see if the sliding piece would attack another
2080 	   piece, making it hung, if moved.
2081 
2082 	   This is an expensive procedure!  */
2083 
2084 	b->pinned_mask = 0;
2085 
2086 	if (b->stage == MATING)
2087 		return 0;
2088 
2089 	for (i=2;i<16;i++) {
2090 		if (!b->pieces[i].p) continue;
2091 
2092 		pinner_mask = b->topieces[b->pieces[i].pos] &
2093 			b->sliding_mask & BLACK_MASK;
2094 
2095 		while (pinner_mask) {
2096 			j = ff_one(pinner_mask);
2097 			pinner_mask &= ~(1<<j);
2098 
2099 			/* If the pinned piece is attacking the pinner then
2100 			   it isn't a pin! It might be a skewer tho.
2101 			   */
2102 			if (b->topieces[b->pieces[j].pos] & (1<<i))
2103 				continue;
2104 
2105 			/* look for a piece that this bit is pinned against */
2106 			for (k=0;k<8;k++) {
2107 				if (!b->pieces[k].p) continue;
2108 				if (k == i) continue;
2109 				if (!same_line(b->pieces[j].pos, b->pieces[i].pos,
2110 					       b->pieces[k].pos)) continue;
2111 				if (!empty_line(b, b->pieces[i].pos,
2112 						b->pieces[k].pos))
2113 				    continue;
2114 
2115 				/* we have a likely pin. Now we need
2116 				   to confirm that if the pinner could attack
2117 				   the pinnedto piece then that piece
2118 				   would be hung */
2119 				if (get_control(b,
2120 						b->topieces[b->pieces[k].pos] | (1<<j),
2121 						b->pieces[k].p,
2122 					        b->pieces[k].pos) < 0) {
2123 					b->pinned_mask |= (1<<i);
2124 					if (debug)
2125 						lprintf(0,"w pinned %s -> %s -> %s\n",
2126 							posstr(b->pieces[j].pos),
2127 							posstr(b->pieces[i].pos),
2128 							posstr(b->pieces[k].pos)
2129 							);
2130 				}
2131 			}
2132 		}
2133 	}
2134 
2135 
2136 	for (i=18;i<32;i++) {
2137 		if (!b->pieces[i].p) continue;
2138 
2139 		pinner_mask = b->topieces[b->pieces[i].pos] &
2140 			b->sliding_mask & WHITE_MASK;
2141 
2142 		while (pinner_mask) {
2143 			j = ff_one(pinner_mask);
2144 			pinner_mask &= ~(1<<j);
2145 
2146 			/* If the pinned piece is attacking the pinner then
2147 			   it isn't a pin! It might be a skewer tho.
2148 			   */
2149 			if (b->topieces[b->pieces[j].pos] & (1<<i))
2150 				continue;
2151 
2152 			/* look for a piece that this bit is pinned against */
2153 			for (k=16;k<24;k++) {
2154 				if (!b->pieces[k].p) continue;
2155 				if (k == i) continue;
2156 				if (!same_line(b->pieces[j].pos, b->pieces[i].pos,
2157 					       b->pieces[k].pos)) continue;
2158 				if (!empty_line(b, b->pieces[i].pos,
2159 						b->pieces[k].pos))
2160 				    continue;
2161 
2162 				/* we have a likely pin. Now we need
2163 				   to confirm that if the pinner could attack
2164 				   the pinnedto piece then that piece
2165 				   would be hung */
2166 				if (get_control(b,
2167 						b->topieces[b->pieces[k].pos] | (1<<j),
2168 						b->pieces[k].p,
2169 						b->pieces[k].pos) > 0) {
2170 					b->pinned_mask |= (1<<i);
2171 					if (debug)
2172 						lprintf(0,"b pinned %s -> %s -> %s\n",
2173 							posstr(b->pieces[j].pos),
2174 							posstr(b->pieces[i].pos),
2175 							posstr(b->pieces[k].pos)
2176 							);
2177 				}
2178 			}
2179 		}
2180 	}
2181 
2182 	return 0;
2183 }
2184 
2185 
eval_etype(Position * b,etype testv,int depth)2186 etype eval_etype(Position *b, etype testv, int depth)
2187 {
2188 	etype ret, v, pv, pinv;
2189 	int player = next_to_play(b);
2190 	etype material;
2191 	uint32 pieces_done;
2192 
2193 #if TEST_EVAL_SHORTCUT
2194 	etype shortcut_ret = INFINITY;
2195 	static int shortcut_total, shortcut_ok, eval_total;
2196 #endif
2197 	if (b->stage > MATING || b->stage < OPENING)
2198 		lprintf(0, "Stage error: %d\n", b->stage);
2199 
2200 	if ((b->flags & FLAG_EVAL_DONE)) {
2201 		return b->eval_result * player;
2202 	}
2203 
2204 	if (b->flags & FLAG_NEED_PART2) {
2205 		lprintf(0,"WARNING: NEED_PART2 in eval\n");
2206 	}
2207 
2208 	if (learning && !mulling) {
2209 		if ((b->flags & FLAG_FORCED_DRAW) && !debug) {
2210 			b->flags |= FLAG_EVAL_DONE;
2211 			b->eval_result = draw_value(b);
2212 			return b->eval_result * player;
2213 		}
2214 	}
2215 
2216 	init_eval_tables();
2217 
2218 	/* passed pawns always get reevaluated, so stopppability does also */
2219 	b->null_stoppable_pawn = 0;
2220 	b->null_unstoppable_pawn = 0;
2221 
2222 	if (b->oldb && !(b->oldb->flags & FLAG_EVAL_DONE)) {
2223 		eval(b->oldb, testv, 1);
2224 	}
2225 
2226 	material = b->w_material - b->b_material;
2227 
2228 	if (debug)
2229 		lprintf(0,"w_material=%e b_material=%e\n",
2230 			b->w_material, b->b_material);
2231 
2232 	if (material > MAX_MATERIAL)
2233 		material = MAX_MATERIAL;
2234 
2235 	if (material < -MAX_MATERIAL)
2236 		material = -MAX_MATERIAL;
2237 
2238 	if (testv == INFINITY) {
2239 		b->piece_change = b->material_mask;
2240 		b->oldb = NULL;
2241 	} else if (depth >= EVAL_ALL_DEPTH) {
2242 		b->piece_change = b->material_mask;
2243 	} else if (b->oldb) {
2244 		Square last_from = b->last_move.from;
2245 		Square last_to = b->last_move.to;
2246 		int fromy = YPOS(last_from);
2247 		int toy = YPOS(last_to);
2248 
2249 		/* we need to recalc a king if a pawn moves, as pawn
2250 		   defence is critical */
2251 		if ((b->oldb->board[last_from] == PAWN) ||
2252 		    (b->oldb->board[last_to] == PAWN))
2253 			b->piece_change |= WKING_MASK;
2254 
2255 		if ((b->oldb->board[last_from] == -PAWN) ||
2256 		    (b->oldb->board[last_to] == -PAWN))
2257 			b->piece_change |= BKING_MASK;
2258 
2259 		if (b->oldb->board[last_from] == KING)
2260 			b->piece_change |= (b->material_mask & ~b->piece_mask);
2261 
2262 		if (b->oldb->board[last_from] == -KING)
2263 			b->piece_change |= (b->material_mask & ~b->piece_mask);
2264 
2265 		if (b->oldb->board[last_to] == QUEEN)
2266 			b->piece_change |= BKING_MASK;
2267 
2268 		if (b->oldb->board[last_to] == -QUEEN)
2269 			b->piece_change |= WKING_MASK;
2270 
2271 		/* need to recalc king if bishops are captured */
2272 		if (b->oldb->board[last_to] == BISHOP)
2273 			b->piece_change |= BKING_MASK;
2274 
2275 		if (b->oldb->board[last_to] == -BISHOP)
2276 			b->piece_change |= WKING_MASK;
2277 
2278 #if 0
2279 		/* Changes in any pawn on the first rank may create
2280                    bishop or knight outosts on the two squares a
2281                    knight's move in front of the pawn */
2282 
2283 		if (b->oldb->board[last_from] == PAWN && fromy == 1 &&
2284 		    !(toy == 2 && tox == fromx)) {
2285 			if (tox > 0) {
2286 				b->piece_change |= (BMINOR_MASK &
2287 						    (1<<b->pboard[last_from+WEST+
2288 								 2*NORTH]));
2289 			}
2290 			if (tox < 7) {
2291 				b->piece_change |= (BMINOR_MASK &
2292 						    (1<<b->pboard[last_from+EAST+
2293 						     2*NORTH]));
2294 			}
2295 		} else if (b->oldb->board[last_to] == PAWN && toy == 1) {
2296 			if (tox > 0) {
2297 				b->piece_change |= (BMINOR_MASK &
2298 						    (1<<b->pboard[last_to+WEST+
2299 								 2*NORTH]));
2300 			}
2301 			if (tox < 7) {
2302 				b->piece_change |= (BMINOR_MASK &
2303 						    (1<<b->pboard[last_to+EAST+
2304 								 2*NORTH]));
2305 			}
2306 		}
2307 
2308 		if (b->oldb->board[last_from] == -PAWN &&
2309 		    fromy == 6 && !(toy == 5 && tox == fromx)) {
2310 			if (tox > 0) {
2311 				b->piece_change |= (WMINOR_MASK &
2312 						    (1<<b->pboard[last_from+WEST+
2313 						     2*SOUTH]));
2314 			}
2315 			if (tox < 7) {
2316 				b->piece_change |= (WMINOR_MASK &
2317 						    (1<<b->pboard[last_from+EAST+
2318 						     2*SOUTH]));
2319 			}
2320 		} else if (b->oldb->board[last_to] == -PAWN && toy == 6) {
2321 			if (tox > 0) {
2322 				b->piece_change |= (WMINOR_MASK &
2323 						    (1<<b->pboard[last_to+WEST+
2324 						     2*SOUTH]));
2325 			}
2326 			if (tox < 7) {
2327 				b->piece_change |= (WMINOR_MASK &
2328 						    (1<<b->pboard[last_to+EAST+
2329 						     2*SOUTH]));
2330 			}
2331 
2332 		}
2333 #endif
2334 		b->piece_change |= MINOR_MASK;
2335 
2336 		/* blocking and unblocking passed pawns */
2337 		if (toy>1 &&
2338 		    (b->wpassed_pawn_mask & (1<<b->pboard[last_to+SOUTH])) &&
2339 		    ((b->board[last_to] < 0 && b->oldb->board[last_to]==0) ||
2340 		     b->oldb->board[last_to])) {
2341 			b->piece_change |= (1<<b->pboard[last_to+SOUTH]);
2342 		}
2343 		if (toy<6 &&
2344 		    (b->bpassed_pawn_mask & (1<<b->pboard[last_to+NORTH])) &&
2345 		    ((b->board[last_to] > 0 && b->oldb->board[last_to]==0) ||
2346 		     b->oldb->board[last_to])) {
2347 			b->piece_change |= (1<<b->pboard[last_to+NORTH]);
2348 		}
2349 
2350 		if (fromy>1 &&
2351 		    (b->wpassed_pawn_mask & (1<<b->pboard[last_from+SOUTH])) &&
2352 		    b->board[last_to] < 0) {
2353 			b->piece_change |= (1<<b->pboard[last_from+SOUTH]);
2354 		}
2355 		if (fromy<6 &&
2356 		    (b->bpassed_pawn_mask & (1<<b->pboard[last_from+NORTH])) &&
2357 		    b->board[last_to] > 0) {
2358 			b->piece_change |= (1<<b->pboard[last_from+NORTH]);
2359 		}
2360 
2361 		/* unstoppable pawns can easily become stoppable, so
2362 		   we should recalculate all unstoppable pawns.
2363 		   Do this by recalculating all passed pawns */
2364 		if ((b->piece_mask & WHITE_MASK) == WKING_MASK) {
2365 			b->piece_change |= b->bpassed_pawn_mask;
2366 		}
2367 		if ((b->piece_mask & BLACK_MASK) == BKING_MASK) {
2368 			b->piece_change |= b->wpassed_pawn_mask;
2369 		}
2370 
2371 	}
2372 
2373 	ret = 0;
2374 
2375 	/* need pins to compute various attack values (e.g weak pawn
2376 	   attack) correctly */
2377 	pinv = find_pins(b);
2378 
2379 	build_pawn_loc(b);
2380 
2381 	v = specifics(b);
2382 	ret += v;
2383 	if (debug)
2384 		lprintf(0,"specifics = %e\n", v);
2385 
2386 	pieces_done = b->piece_change;
2387 	pv = v = piece_values(b);
2388 	ret += v;
2389 	if (debug)
2390 		lprintf(0,"piece values = %e\n", v);
2391 
2392 	v = king_safety(b);
2393 	ret += v;
2394 	if (debug)
2395 		lprintf(0,"king safety = %e\n", v);
2396 
2397 	v = eval_tactics(b);
2398 	ret += v;
2399 	if (debug)
2400 		lprintf(0,"tactics = %e\n", v);
2401 
2402 #if USE_EVAL_SHORTCUT
2403 	if (depth <= 0 &&
2404 	    b->oldb &&
2405 	    abs(b->expensive) < EVAL_SHORTCUT_THRESHOLD &&
2406 	    (ret + material + b->expensive) * player >
2407 	    testv + EVAL_SHORTCUT_THRESHOLD && !egtb(b)) {
2408 		etype ret2 = (ret + material + b->expensive) * player;
2409 
2410 		ret2 -= EVAL_SHORTCUT_OFFSET;
2411 		ret2 *= player;
2412 
2413 		ret2 += check_material(b, ret2);
2414 
2415 		ret2 *= player;
2416 
2417 		if (ret2 >= testv) {
2418 #if TEST_EVAL_SHORTCUT
2419 			shortcut_ret = ret2;
2420 #else
2421 			return ret2;
2422 #endif
2423 			}
2424 	}
2425 #endif
2426 
2427 	b->expensive = 0;
2428 
2429 	b->expensive += pinv;
2430 	ret += pinv;
2431 
2432 	v = board_control1(b);
2433 	b->expensive += v;
2434 	ret += v;
2435 	if (debug)
2436 		lprintf(0,"board control1 = %e\n", v);
2437 
2438 	v = board_control2(b);
2439 	b->expensive += v;
2440 	ret += v;
2441 	if (debug)
2442 		lprintf(0,"board control2 = %e\n", v);
2443 
2444 	b->piece_change &= ~pieces_done;
2445 	b->piece_change |= (b->wpassed_pawn_mask | b->bpassed_pawn_mask);
2446 	v = piece_values(b);
2447 	ret += (v - pv);
2448 
2449 	v = eval_mobility(b);
2450 	b->expensive += v;
2451 	ret += v;
2452 	if (debug)
2453 		lprintf(0,"mobility = %e\n", v);
2454 
2455 	if (debug)
2456 		lprintf(0,"pos value = %e\n", ret);
2457 
2458 #if USE_OVERLOADED
2459 	v = overloaded_pieces(b);
2460 	ret += v;
2461 	if (debug)
2462 		lprintf(0, "overloaded = %e\n", v);
2463 #endif
2464 	b->flags |= FLAG_EVAL_DONE;
2465 
2466 	ret += material;
2467 	ret += check_material(b, ret);
2468 
2469 	if (debug) {
2470 		lprintf(0,"eval = %e\n", ret);
2471 		if (b->flags & FLAG_ACCEPT_DRAW)
2472 			lprintf(0, "Will accept draw\n\n");
2473 	}
2474 
2475 #if TEST_EVAL_SHORTCUT
2476 	if (shortcut_ret != INFINITY) {
2477 		etype ret2 = ret * player;
2478 
2479 		shortcut_total++;
2480 
2481 		if ((ret2 < testv && shortcut_ret > testv) ||
2482 		    (ret2 > testv && shortcut_ret < testv)) {
2483 			lprintf(0,"shortcut: %d/%d/%d ret=%e shortcut_ret=%e testv=%d move=%s\n",
2484 				shortcut_ok, shortcut_total, eval_total,
2485 				ret2, shortcut_ret, testv,
2486 				short_movestr(b, &b->last_move));
2487 			print_board(b->board);
2488 		} else {
2489 			shortcut_ok++;
2490 		}
2491 	}
2492 	eval_total++;
2493 #endif
2494 
2495 	b->eval_result = ret;
2496 	return b->eval_result * player;
2497 }
2498 
2499 
eval(Position * b,etype testv,int depth)2500 Eval eval(Position *b, etype testv, int depth)
2501 {
2502 	Eval ret = makeeval(b, eval_etype(b, testv, depth));
2503 
2504 	if (!(b->flags & FLAG_EGTB_EVAL)) {
2505 		if (ret.v > MAX_EVAL)
2506 			ret.v = MAX_EVAL;
2507 		if (ret.v < -MAX_EVAL)
2508 			ret.v = -MAX_EVAL;
2509 	}
2510 	return ret;
2511 }
2512 
eval1(Position * b,etype testv,int depth)2513 Eval eval1(Position *b, etype testv, int depth)
2514 {
2515 	Eval ret1, ret2;
2516 	Position b1, b2, b3;
2517 
2518 	b1 = (*b);
2519 	b2 = (*b);
2520 	b3 = (*b);
2521 
2522 	ret1 = eval1(b, testv, depth);
2523 	ret2 = eval1(&b1, INFINITY, depth);
2524 
2525 	if (!(b->flags & FLAG_PROMOTE) &&
2526 	    ret1.v != ret2.v) {
2527 		lprintf(0,"****%d %d\n", ret1.v, ret2.v);
2528 
2529 		if (b->oldb)
2530 			print_board(b->oldb->board);
2531 		print_board(b->board);
2532 
2533 		debug = 1;
2534 		lprintf(0, "*** INCREMENTAL b ***\n");
2535 		ret1 = eval1(&b2, testv, depth);
2536 		lprintf(0, "*** NON-INCREMENTAL b ***\n");
2537 		b3.flags &= ~FLAG_EVAL_DONE;
2538 		ret2 = eval1(&b3, INFINITY, depth);
2539 		debug = 0;
2540 		exit(1);
2541 
2542 	}
2543 
2544 	return ret1;
2545 }
2546 
2547 
eval_debug(Position * b)2548 void eval_debug(Position *b)
2549 {
2550 	regen_moves(b);
2551 
2552 	debug = 1;
2553 
2554 	lprintf(0,"white_moves=%d black_moves=%d\n",
2555 		b->white_moves, b->black_moves);
2556 
2557 	b->flags |= FLAG_COMPUTER_WHITE;
2558 	b->flags &= ~FLAG_EVAL_DONE;
2559 	eval(b, INFINITY, MAX_DEPTH);
2560 	b->flags &= ~FLAG_COMPUTER_WHITE;
2561 	b->flags &= ~FLAG_EVAL_DONE;
2562 	eval(b, INFINITY, MAX_DEPTH);
2563 
2564 	debug = 0;
2565 }
2566 
2567 
eval_speed(Position * b,int loops)2568 void eval_speed(Position *b, int loops)
2569 {
2570 	int i;
2571 	float t;
2572 
2573 	t = gettime();
2574 
2575 	for (i=0;i<loops;i++) {
2576 		b->flags &= ~FLAG_EVAL_DONE;
2577 		eval(b, INFINITY, MAX_DEPTH);
2578 	}
2579 
2580 	t = gettime() - t;
2581 
2582 	lprintf(0,"%d full eval calls in %g secs - %g eval/sec\n",
2583 		loops, t, loops/t);
2584 }
2585