1 /****************************
2  * evaluate() function decides if given position is terminal (checkmate,
3  * stalemate, ...) , if not, seeks it in the hash table, if not
4  * present, calls dynamic (search()) or static (static_eval()) evaluation.
5  * This also handles extensions.
6  ******************/
7 
8 #include "phalanx.h"
9 
10 #define EXTENSION_BASE 80
11 
12 #define NULL_MOVE_PRUNING
13 
14 #define RECAPTURE_EXTENSIONS
15 #define PEE_EXTENSIONS     /* entering kings+pawns endgame extends */
16 #define CHECK_EXTENSIONS
17 #define PAWNPUSH_EXTENSIONS
18 
19 #define minmv (P_VALUE)
20 
21 /* 12 moves to draw: the static evaluation goes to zero */
22 #define RULE_50_CLOSE 24
23 
24 /**
25 ***   Phalanx uses very simple implementation of static-eval cache.
26 ***   It eats 512 kB and makes it about 10% faster on a 486.
27 **/
28 #undef CACHE
29 #ifdef CACHE
30 unsigned * C; /* 64k entries of 4 bytes: 256kB */
31 #endif
32 
33 
34 
initcache(void)35 void initcache(void)
36 {
37 #ifdef CACHE
38 C = malloc(0x10000*sizeof(unsigned)); /* 64k entries of 8 bytes: 512kB */
39 if( C==NULL ) { puts("cannot alloc static eval cache!"); exit(0); }
40 #endif
41 }
42 
43 
44 tsearchnode S[MAXPLY];
45 
approx_eval(void)46 static inline int approx_eval(void)
47 {
48 S[Ply].psnl = - S[Ply-1].psnl;
49 
50 S[Ply].devi = S[Ply-1].devi*2/3 + abs(S[Ply].psnl)/8;
51 if( G[Counter-1].m.in2 ) S[Ply].devi += 60; else S[Ply].devi += 40;
52 
53 /* pawn promotions should mostly trigger full static eval in the child node,
54  * and avoid the lazy one, otherwise the engine delays promotions due to
55  * the high bonus for the pawn on the 7th row. */
56 if(
57 	( G[Counter-1].m.in1 == WP && G[Counter-1].m.to >= A7 )
58 	||
59 	( G[Counter-1].m.in1 == BP && G[Counter-1].m.to <= H2 )
60   )
61 	S[Ply].devi += 3*P_VALUE;
62 
63 return G[Counter].mtrl - G[Counter].xmtrl + S[Ply].psnl;
64 }
65 
66 
67 
static_eval(void)68 int static_eval(void)
69 {
70 
71 int positional;
72 int r50 = 100 - G[Counter].rule50;
73 int material = G[Counter].mtrl-G[Counter].xmtrl;
74 
75 #ifdef CACHE
76 if( ( ( C[ 0x0000FFFF & G[Counter].hashboard ] ^ G[Counter].hashboard )
77     & 0xFFFF0000 ) == 0 )
78 {
79 unsigned * cc = C + ( 0x0000FFFF & G[Counter].hashboard );
80 Wknow.prune = (((*cc)&0x00004FFF)!=0);
81 Bknow.prune = (((*cc)&0x00008FFF)!=0);
82 return ( (*cc) & 0x00003FFF ) ;
83 }
84 #endif
85 
86 positional = score_position();
87 
88 if( r50 < RULE_50_CLOSE )
89 { positional = positional * r50 / RULE_50_CLOSE;
90   material = material * r50 / RULE_50_CLOSE;
91 }
92 
93 #undef RAISE
94 #ifdef RAISE
95 /* Inbalanced material: take positional bonus seriously */
96 if( abs(material) > 200 )
97 {
98 	int m = abs(material) - 200;
99 	if( m > 1000 ) m=1000;
100 #ifdef SCORING
101 	if( Scoring )
102 		printf(
103 		" (   ) inbalanced material, positional raised: %i -> %i\n",
104 		positional, positional + positional*m/500 );
105 #endif
106 	positional =        positional + positional*m/500;
107 }
108 #endif
109 
110 #ifdef CACHE
111 {
112 unsigned * cc = C + ( 0x0000FFFF & G[Counter].hashboard );
113 *cc = ( 0xFFFF0000 & G[Counter].hashboard ) | ( material+positional );
114 if( Wknow.prune ) *cc |= 0x00004000; else *cc &= (0xFFFFFFFF-0x00004000);
115 if( Bknow.prune ) *cc |= 0x00008000; else *cc &= (0xFFFFFFFF-0x00008000);
116 }
117 #endif
118 
119 S[Ply].psnl = positional;
120 S[Ply].devi = 0;
121 
122 #undef debug
123 #ifdef debug
124 if(abs(positional)>600)
125 { Scoring = 1; score_position(); Scoring = 0;
126   printboard(); printf("[%i,%i,%i]",material,positional,score_position());
127   getchar();
128 }
129 #endif
130 
131 return material+positional;
132 
133 }
134 
135 
136 
repetition(int n)137 inline int repetition( int n )
138 {
139 	int i;
140 	int r=0;
141 	unsigned board = G[Counter].hashboard;
142 	for( i=Counter-2; i>=0; i-=2 )
143 	{
144 		if( G[i].hashboard == board ) if( ++r == n ) return 1;
145 		if( G[i].rule50 <= 1 ) break;
146 	}
147 	return 0;
148 }
149 
150 
151 
material_draw(void)152 int material_draw( void )
153 {
154 	int i, n=2;
155 
156 	for( i=L[WKP].next; i!=0; i=L[i].next )
157 	switch( B[i] )
158 	{	case WQ: case WR: case WP: return 0;
159 		default: n--; if( n==0 ) return 0;
160 	}
161 
162 	for( i=L[BKP].next; i!=0; i=L[i].next )
163 	switch( B[i] )
164 	{	case BQ: case BR: case BP: return 0;
165 		default: n--; if( n==0 ) return 0;
166 	}
167 
168 	return 1;
169 }
170 
171 
172 
173 /*****************************************************************/
174 
evaluate(int Alpha,int Beta)175 int evaluate( int Alpha, int Beta )
176 {
177 
178 static int timeslice = 2000;
179 static int polslice = 4000;
180 int result;
181 tmove m[256]; int n;  /* moves and number of moves */
182 thashentry *t;
183 int check;
184 int lastiter;
185 int totmat = Totmat = G[Counter].mtrl+G[Counter].xmtrl;
186 
187 if(Ply%2) lastiter = -LastIter; else lastiter = LastIter;
188 
189 Nodes++;
190 
191 if( Flag.level == fixedtime || Flag.level == timecontrol )
192 if( ( Nodes % timeslice ) == 0 && !Flag.analyze )
193 {
194 	extern long T1;
195 	int t = Flag.centiseconds - ptime() + T1;
196 
197 	if( t < 0 ) { if( Flag.ponder >= 2 ) Flag.ponder = 3; else Abort = 2; }
198 	else
199 	if( t != Flag.centiseconds )
200 	timeslice =
201 	  Nodes * t / ( Flag.centiseconds - t ) * 2 / 3;
202 
203 	if( timeslice > 5*Flag.centiseconds ) timeslice = 5*Flag.centiseconds;
204 	if( timeslice < 50 ) timeslice=50;
205 }
206 
207 {
208 	static int64 lnodes = 0;
209 	if( lnodes + polslice < Nodes || Nodes == 1 )
210 	{
211 		static long lptime = 0;
212 		long nptime = ptime();
213 
214 		if( nptime == lptime ) nptime++;
215 
216 		if( nptime - lptime < 100 ) polslice = polslice*11/10;
217 		else { polslice = polslice*10/11; }
218 
219 		lptime = nptime;
220 
221 		if( Flag.post && !Flag.xboard ) verboseline();
222 
223 if(Flag.polling)
224 {
225 
226 #if defined(__GNUC__) && !defined(__MINGW32__)
227   static fd_set readfds;
228   static struct timeval tv;
229   int data;
230 
231   FD_ZERO (&readfds);
232   FD_SET (fileno(stdin), &readfds);
233   tv.tv_sec=0;
234   tv.tv_usec=0;
235   select(16, &readfds, 0, 0, &tv);
236   data=FD_ISSET(fileno(stdin), &readfds);
237   if(data)
238   {
239 	if(polslice<8000 || Flag.analyze) polslice=4000; else polslice/=2;
240 	interrupt(0);
241   }
242 
243 #else
244 
245  /* Credit here goes to Dr Oliver Brausch for the code from his
246   * program Olithink.  Some rewriting has been done by CMF, but not much
247   * as I have absolutely no idea whatsoever what this does.
248   * I think the original code is from Crafty by Prof. Robert Hyatt. [JA] */
249 
250   static int init = 0, pipe;
251   static HANDLE inh;
252   DWORD dw;
253 
254   /* If we're running under XBoard then we can't use _kbhit() as the input commands
255    * are sent to us directly over the internal pipe */
256   if (Flag.xboard>0) {
257 #if defined(FILE_CNT)
258     if (stdin->_cnt > 0) return stdin->_cnt;
259 #endif
260     if (!init) {
261       init = 1;
262       inh = GetStdHandle(STD_INPUT_HANDLE);
263       pipe = !GetConsoleMode(inh, &dw);
264       if (!pipe) {
265         SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
266         FlushConsoleInputBuffer(inh);
267       }
268     }
269     if (pipe) {
270       if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
271       return dw;
272     }
273     else {
274       GetNumberOfConsoleInputEvents(inh, &dw);
275       return dw <= 1 ? 0 : dw;
276     }
277   }
278   else return _kbhit();
279 
280 #endif
281 
282 }
283 
284 /*
285 		if( Flag.analyze )
286 		printf("stat01: %d %d %d %d %d\n",0,Nodes,A_d,A_i,A_n);
287 */
288 
289 		lnodes = Nodes;
290 	}
291 }
292 
293 if( Ply >= MAXPLY-2 )
294 { PV[Ply][Ply].from=0; return G[Counter].mtrl-G[Counter].xmtrl; }
295 
296 if( G[Counter].rule50 >= 100 ) /* 50 moves draw */
297 { PV[Ply][Ply].from=0; return DRAW; }
298 
299 /* insufficient material draw */
300 if( G[Counter].mtrl<400 && G[Counter].mtrl<400 )
301 if( material_draw() )
302 { PV[Ply][Ply].from=0; return DRAW; }
303 
304 if( G[Counter].rule50 >= 3 )
305 if( repetition(1) ) /* third rep. draw */
306 {
307 	int j;
308 	int ext=0;
309 	PV[Ply][Ply].from=0;
310 
311 	for( j=Counter-1; j>Counter-Ply; j-=2 )
312 	{ ext += G[j-1].m.dch - G[j].m.dch; }
313 
314 	if( ext > 0 )
315 	{
316 		if( ext > 500 ) ext=500;
317 		ext += Ply*20;
318 	}
319 	else if( ext < 0 )
320 	{
321 		if( ext < -500 ) ext=-500;
322 		ext -= Ply*20;
323 	}
324 
325 	/* Speculative drawscore
326 	 * Human players sometimes play a wild sacrifice leading to unclear
327 	 * lines, making sure they could achieve a repetition draw at least.
328 	 * This is the same speculative heuristics:
329 	 * Repetition draw is scored as a slight advantage to the side that
330 	 * forced the repetition, ie. that had less extensions in the path,
331 	 * that's why we count the cumulative extension above. The deeper
332 	 * in the tree this happens, the higher speculative bonus we give,
333 	 * that is the Ply*20 above. However, if the remaining Depth is large,
334 	 * we pull the score back closer to the DRAW score, because with
335 	 * the larger Depth we should be able to find something better
336 	 * than draw.
337 	 */
338 	return DRAW + ext/(15+max(-5,Depth/10));
339 }
340 
341 /********************************************************************
342  *     Now it is time to look into the hashtable.
343  ********************************************************************/
344 if( SizeHT == 0 || Depth<0 ) t = NULL;
345 else
346 if( (t=seekHT()) != NULL )
347 if( Age == t->age || Beta-Alpha == 1 )
348 if( t->depth >= Depth || ( Depth<300 && abs(t->value)>CHECKMATE-1000 ) )
349 {
350 	int val = t->value;
351 	if( val > CHECKMATE-1000 ) val -= Ply;
352 	else if( val < -CHECKMATE+1000 ) val += Ply;
353 
354 	switch( t->result )
355 	{
356 	case no_cut:                    /* `true value', good_score */
357 		PV[Ply][Ply].from=0; return val;
358 	break;
359 	case alpha_cut:                 /* `this or less', failed_low */
360 		if( val <= Alpha ) { PV[Ply][Ply].from=0; return Alpha; }
361 	break;
362 	case beta_cut:                  /* `this or more', failed_high */
363 		if( val >= Beta ) { PV[Ply][Ply].from=0; return Beta; }
364 	break;
365 	}
366 }
367 /***** End of hashtable stuff *****/
368 
369 #undef nodef
370 #ifdef nodef
371 {
372 static int64 int good=0, all=0;
373 if( t!=NULL && t->move!=0 ) good++;
374 all++;
375 if( all%100000 == 0 && all!=0 )
376 printf("hit percentage = %lld.%02lld%%\n",good*100/all,good*10000/all%100);
377 }
378 #endif
379 
380 if( Ply<2 )	/* called from rootsearch() */
381 	S[Ply].check = check = checktest(Color);
382 else		/* called from search() and the checktest() has been run */
383 	check = S[Ply].check;
384 
385 if( Depth>0 || check )
386 {
387 
388 	if(Depth<=0) result = approx_eval();
389 	else         result = static_eval();
390 
391 #define FORWARD_PRUNING
392 #ifdef  FORWARD_PRUNING
393 /*
394  * A simple forward pruning:
395  * The Depth is low and the static evaluation is over [Alpha plus margin]
396  * Our king is safe (khung<limit) and we don't have much hung material.
397  * Let's lift Alpha and prune if it gets >= Beta.
398  * This works quite fine for larger Depths than 200 (2 plies) as well,
399  * tested with limit 600 on a set of positions and it's still finding
400  * everything and in a shorter time, but I'm keeping the depth limit
401  * conservative for now.
402  * This is similar to what the old Phalanx XXII had, except now
403  * we use the margin.
404  */
405 	if(	!check
406 		&& Depth < 200
407 		&& (	Color==WHITE
408 			?
409 			( Wknow.hung<14 && Wknow.khung<6 )
410 			:
411 			( Bknow.hung<14 && Bknow.khung<6 )
412 		   )
413 	  )
414 	{
415 		int r = result - (P_VALUE+Depth)/10;
416 		if( r>=Beta ) { PV[Ply][Ply].from=0; return Beta; }
417 		if( r>Alpha ) Alpha=r;
418 	}
419 #endif /* FORWARD_PRUNING */
420 
421 
422 /*
423 if(    Depth<1500 && Depth>0
424     && Beta-Alpha==1 && !check
425     && result < Beta-P_VALUE-Depth )
426 {
427 	generate_legal_checks(m,&n);
428 	if( n==0 ) { result=Alpha; goto end; }
429 }
430 else
431 */
432 	generate_legal_moves(m,&n,check);
433 
434 	/** Return, if there is no legal move - checkmate or stalemate **/
435 	if(n==0)
436 	{
437 		PV[Ply][Ply].from=0;
438 		if(check) return Ply-CHECKMATE;
439 		else return DRAW;
440 	}
441 
442 #ifdef NULL_MOVE_PRUNING
443 	if(
444 		Depth > 100
445 		&& ( result >= Beta || Depth > 350 )
446 		&& ! FollowPV
447 		&& ! check
448 		&& n>4
449 		&& ( (Color==WHITE) ? (Wknow.q||Wknow.r||Wknow.b||Wknow.n>1)
450 		                    : (Bknow.q||Bknow.r||Bknow.b||Bknow.n>1) )
451 		&& G[Counter-1].m.special != NULL_MOVE  /* prev. node not nm */
452 		&& ( t==NULL || t->depth <= Depth-350
453 		  || t->result==beta_cut || t->value >= Beta )
454 	)
455 	{
456 		int value;
457 		int olddepth = Depth;
458 
459 		G[Counter].m.in1 = 0; /* disable en passant */
460 		G[Counter].m.special = NULL_MOVE;
461 		G[Counter].m.to = 2;
462 		Counter ++; Ply ++;
463 		G[Counter].castling = G[Counter-1].castling;
464 		G[Counter].rule50 = G[Counter-1].rule50 + 1;
465 		G[Counter].hashboard =
466 			HASH_COLOR ^ G[Counter-1].hashboard;
467 		G[Counter].mtrl = G[Counter-1].xmtrl;
468 		G[Counter].xmtrl = G[Counter-1].mtrl;
469 		Color = enemy(Color);
470 		S[Ply].check=0;
471 
472 		/* reduction depends on number of moves generated */
473 		/* n=20 ... R=2, n=40 ... R=3, n=50 ... R=3.5 */
474 		Depth -= 200 + n*5;
475 
476 		if(Depth<0) Depth=0; else Depth -= Depth/4;
477 		value = -evaluate(-Beta, -Beta+1);
478 
479 		Color = enemy(Color);
480 		Counter --; Ply --;
481 		Depth = olddepth;
482 		Totmat = totmat;
483 
484 		if( value >= Beta ) { result = Beta; goto end; }
485 	}
486 #endif
487 
488 #define PROBCUT
489 #ifdef PROBCUT
490 #define MRGN 190
491 /*
492  *  If we have a capture that can get us above Beta+MRGN, we try to
493  *  search the capturing move at a reduced depth and with raised Beta.
494  *  If we then get a fail high, the previous opponent move was likely
495  *  a blunder and we can prune this node.
496  *  This is complementary to null move pruning. Null move can prune many
497  *  weak moves, but not those that create a threat, e.g. unprotected rook
498  *  attacks queen - null move allows capturing the queen and thus cannot
499  *  prune the silly attack, whereas in ProbCut queen captures the rook,
500  *  confirms with the reduced search that the previous opponent move
501  *  was a blunder and prunes.
502  */
503 
504 if( Depth>350 && Beta-Alpha==1 && !check )
505 {
506 	int i;
507 	int r = Alpha;
508 	int olddepth = Depth;
509 
510 	Depth-= 350;
511 
512 	for( i=0; i!=n; i++ )
513 	if( m[i].in2 && result+Values[m[i].in2>>4] >= Beta+MRGN )
514 	{
515 		do_move(m+i); S[Ply].check=checktest(Color);
516 		r = - evaluate( -Beta-MRGN, -Beta-MRGN+1 );
517 		undo_move(m+i);
518 		if( r>=Beta+MRGN ) break;
519 	}
520 	Depth = olddepth;
521 
522 	if( r>= Beta+MRGN ) { result = Beta; goto end; }
523 }
524 
525 #endif /* PROBCUT */
526 
527 #ifdef CHECK_EXTENSIONS
528 	if( check && Depth>0 )
529 	{
530 		int newdch, i;
531 
532 		/* We compute the extension from the depth remaining (Depth)
533 		 * and number of legal moves available (n) */
534 		newdch =
535 			   EXTENSION_BASE - 20
536 			 - 3000/(Depth+100) /* 30..0 */
537 			 - 200/(n*(n+1)); /* 1~100,2~33,3~16,..0 */
538 
539 		if( result<=lastiter-50 || result <= -250 )  /* losing anyway */
540 			newdch = (newdch+100)/2; /* smaller extension, 50% */
541 
542 		for( i=0; i!=n; i++ )
543 			if( m[i].in2 ) m[i].dch = (newdch+100)/2; /* capture */
544 			else m[i].dch = newdch;
545 	}
546 #endif
547 
548 #ifdef PAWNPUSH_EXTENSIONS
549 	if( Totmat < 4000 )
550 	if(result<lastiter+50 && result<250)  /* winning anyway: dont extend */
551 	{
552 		int i;
553 		for( i=0; i!=n; i++ )
554 		if( piece(m[i].in2a) == PAWN
555 		 && m[i].special == 0
556 		 && ( ( Color==WHITE && m[i].to >= A6 )
557 		   || ( Color==BLACK && m[i].to <= H3 ) ) )
558 		{
559 			int j;
560 			int support=0;
561 			int newdch=EXTENSION_BASE;
562 
563 			if( Color == WHITE )
564 			{
565 
566 				for( j=m[i].to+10; j<=H7; j+=10 )
567 				if( B[j-1]==BP
568 				 || B[j]==BP
569 				 || B[j+1]==BP )
570 				goto no_push_extension;
571 
572 				for( j=m[i].to; j<=H8; j+=10 )
573 				{
574 					if( B[j] ) support--;
575 					if( see(B,m[i].from,j) < 0 )
576 						support--;
577 					else	support++;
578 				}
579 			}
580 			else
581 			{
582 				for( j=m[i].to-10; j>=A2; j-=10 )
583 				if( B[j-1]==WP
584 				 || B[j]==WP
585 				 || B[j+1]==WP )
586 				goto no_push_extension;
587 
588 				for( j=m[i].to; j>=A1; j-=10 )
589 				{
590 					if( B[j] ) support--;
591 					if( see(B,m[i].from,j) < 0 )
592 						support--;
593 					else	support++;
594 				}
595 			}
596 
597 			newdch += Depth/20 + Totmat/100 - 30*support;
598 
599 			switch( m[i].to/10 )
600 			{ case 8: case 3:
601 			  if(support>0) newdch -= 20*support+10; break; }
602 
603 			if( newdch < m[i].dch )
604 			{ m[i].dch = newdch; }
605 
606 			no_push_extension:;
607 		}
608 	}
609 #endif
610 
611 #ifdef RECAPTURE_EXTENSIONS
612 	if( Depth>0 && G[Counter-1].m.in2 )
613 	if( result<lastiter+50 && result<250 )   /* winning anyway: dont */
614 	{
615 		int i, t=G[Counter-1].m.to;
616 		int v1 = Values[ G[Counter-1].m.in1 >> 4 ];
617 		int v2 = Values[ G[Counter-1].m.in2 >> 4 ];
618 		int newdch;
619 
620 		if( Depth <= 200 )
621 			newdch = EXTENSION_BASE-30;
622 		else
623 			newdch = EXTENSION_BASE-20;
624 
625 		if( min(v1,v2) > 400 || G[Counter].mtrl < Q_VALUE )
626 			newdch -= 70;
627 		else
628 		if( min(v1,v2) > 200 || G[Counter].mtrl < (Q_VALUE+N_VALUE) )
629 			newdch -= 45;
630 
631 		/* recaptures depth bonus */
632 		for( i=0; i!=n; i++ )
633 		if( m[i].to == t )
634 		if( m[i].dch > newdch )
635 /*		if( Depth<=100 || see(B,m[i].from,m[i].to) >= v1 ) */
636 			m[i].dch = newdch;
637 	}
638 #endif
639 
640 #ifdef PEE_EXTENSIONS
641 	if( Depth > 200
642 	 && G[Counter].mtrl <= (8*P_VALUE)
643 	 && G[Counter].xmtrl <= (8*P_VALUE+Q_VALUE)
644 	 && G[Counter-1].m.in2 > KNIGHT )
645 	{
646 		int i;
647 		int target=0;
648 		int cdch;
649 
650 		for( i=L[L[Color].next].next; i!=0; i=L[i].next )
651 		if( B[i] >= KNIGHT ) goto nopee;
652 
653 		for( i=L[L[enemy(Color)].next].next; i!=0; i=L[i].next )
654 		if( B[i] >= KNIGHT )
655 		{ if( target ) goto nopee; else target=i; }
656 
657 		if( ! target ) goto nopee;
658 
659 		if( G[Counter-1].m.in2 >= QUEEN ) cdch = min(Depth,450);
660 		else cdch = min(Depth*2/3,350);
661 
662 		for( i=0; i!=n; i++ )
663 		if( m[i].to == target )
664 		{ m[i].dch -= cdch;
665 		  /* printboard(NULL); printm(m[i],NULL); getchar(); */ }
666 
667 		nopee:;
668 	}
669 #endif
670 
671 #ifdef ETTC
672 if( Depth > 200 && SizeHT != 0 )
673 {
674 	extern void do_hash(tmove *), undo_hash(tmove *);
675 
676 	int i;
677 	for( i=0; i!=n; i++ )
678 	{
679 		thashentry *t;
680 		do_hash(m+i);
681 
682 		if( (t=seekHT()) != NULL )
683 		if( t->depth >= Depth )
684 		if( t->result != beta_cut )
685 		{
686 			int val = -t->value;
687 			if( val > CHECKMATE-100 ) val -= Ply;
688 			else if( val < -CHECKMATE+100 ) val += Ply;
689 
690 			if( val > Alpha )
691 			{
692 				if( val >= Beta )
693 				{
694 					undo_hash(m+i);
695 					G[Counter].m = m[i];
696 					PV[Ply][Ply] = m[i];
697 					PV[Ply][Ply+1].from = 0;
698 					result = Beta; goto end;
699 				}
700 				Alpha=val;
701 			}
702 		}
703 		undo_hash(m+i);
704 	}
705 }
706 #endif
707 
708 }
709 else
710 {	/*** Quiescence search ***/
711 
712 	result = approx_eval();
713 
714 	if( ( result < Beta+S[Ply].devi && result > Alpha-S[Ply].devi )
715 	 || Totmat<=(B_VALUE+P_VALUE) || Ply<2 )
716 	result = static_eval();
717 
718 	if( result >= Beta ) return result;
719 
720 	if( result <= Alpha-(Q_VALUE+minmv) && Depth <= -100 )
721 	{ return Alpha; }
722 
723 #ifdef QCAPSONLY
724 	generate_legal_captures(m,&n,Alpha-result-minmv);
725 #else
726 	/* What to generate? Only captures or also safe checks? */
727 	if(    G[Counter].mtrl-G[Counter].xmtrl < 400
728 	    && Depth > -100
729 	)
730 		generate_legal_checks(m,&n);
731 	else
732 		generate_legal_captures(m,&n,Alpha-result-minmv);
733 #endif
734 }
735 
736 /*** Compute heuristic values of moves ***/
737 add_killer( m, n, t );
738 
739 PV[Ply][Ply].from = 0;
740 
741 if( Flag.nps )
742 {
743 	if( Flag.easy )
744 	{ if( n>10 && Flag.easy<=100 ) blunder(m,&n); }
745 
746 	/* timecontrol fix */
747 	if( polslice > Flag.easy+200 ) polslice=Flag.easy+200;
748 
749 	/* Now limit the NPS, lowest value is 100.
750 	 * For higher values of nps levels like 50000 nps, there's no need
751 	 * to check for the limit and call ptime() at every node,
752 	 * hence the condition below */
753 	if( Nodes%(1+Flag.nps/500)==0 )
754 	{
755 		int nps_actual = Nodes*100/max(ptime()-T1,1);
756 		if( nps_actual > Flag.nps && !Abort ) usleep(100000);
757 	}
758 }
759 
760 /*** Full-width search ***/
761 if( Depth>0 || check )
762 {
763 	result = search(m,n,Alpha,Beta);
764 }
765 else /*** Quiescence ***/
766 {
767 	if( result > Alpha )
768 		result = search(m,n,result,Beta);
769 	else
770 		result = search(m,n,Alpha,Beta);
771 }
772 
773 end:
774 
775 if( result>=Beta && Depth>0 )
776 	write_killer( G[Counter].m.from, G[Counter].m.to );
777 
778 if( SizeHT != 0 && Depth >= 0 && Abort == 0 ) writeHT( result, Alpha, Beta );
779 
780 /**
781 ***    Check learning file.
782 ***    This should be done before search.  It is here only for
783 ***    timing heuristics stability problem that needs better
784 ***    solution.
785 **/
786 if( Depth > 300 && Flag.learn )
787 if( Depth > 400 || Ply<3 )
788 {
789 	int lresult = rlearn();
790 	if( lresult != NOVALUE )
791 	{ PV[Ply][Ply].from=0;
792 	  if( lresult > CHECKMATE-1000 )  lresult -= Ply;
793 	  if( lresult < -CHECKMATE+1000 ) lresult += Ply;
794 	  result = lresult;
795 	}
796 }
797 
798 return result;
799 
800 }
801 
802 
803