1 /****************************
2  * easy levels
3  ******************/
4 
5 #include "phalanx.h"
6 
7 
8 
blunder(tmove * m,int * n)9 void blunder( tmove *m, int *n )
10 {
11 int i;
12 int initp = Flag.easy * 4 + 150;
13 
14 /* quick look (small Depth) makes blunders */
15 initp -= Depth/5;
16 
17 /* full board means more blunders */
18 initp += (G[Counter].mtrl+G[Counter].xmtrl) / 200;
19 
20 if(Counter>2)
21 for( i=(*n)-1; i>=1 && (*n)>4; i-- )
22 {
23 	/* compute the probability this move is not seen */
24 	int p = initp;
25 
26 	/* missing PV moves is unlikely */
27 	if( m[i].from==PV[0][Ply].from && m[i].to==PV[0][Ply].to )
28 	p -= 200;
29 
30 	if( m[i].from==PV[Ply-1][Ply].from && m[i].to==PV[Ply-1][Ply].to )
31 	p -= 200;
32 
33 	/* target square far from the center is more difficult to spot */
34 	p += 2*dist[120*E4+m[i].to].taxi + dist[120*E4+m[i].to].max +
35 	   + 2*dist[120*D5+m[i].to].taxi + dist[120*D5+m[i].to].max
36 	/* so is target square far from previous opponents move */
37 	   + 2*dist[120*G[Counter-1].m.to+m[i].to].taxi;
38 
39 	if( m[i].in2 ) /* captures - we tend to see this */
40 	{
41 		/* the more valuable the captured piece,
42 		 * the more likely we see the move. */
43 		p -= 20 + Values[ m[i].in2 >> 4 ] / 20;
44 
45 		/* capture of last moved piece is spotted
46 		 * + extra bonus for recapture */
47 		if( m[i].to == G[Counter-1].m.to )
48 		{
49 			p -= 20 + Values[ m[i].in2 >> 4 ] / 30;
50 			if( G[Counter-1].m.in2 ) p -= 40; /* recapture */
51 		}
52 
53 		/* very short captures */
54 		switch( dist[120*m[i].from+m[i].to].max )
55 		{
56 			case 0: case 1: p -= 250; break;
57 	  		case 2: p -= 150; break;
58 	  		case 3: p -= 50; break;
59 		}
60 	}
61 	else /* noncaptures - prune or reduce with power table info */
62 	{
63 		int pp=0;
64 		unsigned short pf = P[m[i].from], pt = P[m[i].to];
65 		unsigned short xpm, xbnm, xrm, xqm; /* enemy power masks */
66 		int mpv = Values[m[i].in1 >> 4]; /* moving piece value */
67 
68 		if( Color == WHITE )
69 		{ xpm=BPM; xbnm=(BNM|BBM); xrm=BRM; xqm=BQM; }
70 		else
71 		{ xpm=WPM; xbnm=(WNM|WBM); xrm=WRM; xqm=WQM; }
72 
73 		/* leaving an attacked square - reduce probability of
74 		 * the move being skipped */
75 		if( pf&xpm ) pp -= (5 + mpv - P_VALUE)/10;
76 		if( pf&xbnm && mpv >= N_VALUE ) pp -= (5 + mpv - N_VALUE)/10;
77 		if( pf&xrm && mpv >= R_VALUE ) pp -= (5 + mpv - R_VALUE)/10;
78 		if( pf&(xqm|xrm|xbnm|xpm) ) pp -= mpv/100;
79 
80 		/* going to an attacked square - raise probability
81 		 * the move is skipped */
82 		if( pt&xpm ) pp += (10 + mpv - P_VALUE)/10;
83 		if( pt&xbnm && mpv >= N_VALUE ) pp += (10 + mpv - N_VALUE)/10;
84 		if( pt&xrm && mpv >= R_VALUE ) pp += (10 + mpv - R_VALUE)/10;
85 		if( pt&(xqm|xrm|xbnm|xpm) ) pp += mpv/50;
86 
87 		p += pp;
88 
89 		/* careless reductions to achieve depth at these low nps */
90 		if( pp>=0 ) m[i].dch += 50 + min( 2*pp, 90 );
91 	}
92 
93 	/* We focus on the piece that moved 2 plies ago and see the
94 	 * moves of the same piece */
95 	if( m[i].from == G[Counter-2].m.to ) p -= 55;
96 
97 	/* underpromotions? too precise! */
98 	if( m[i].in1 != m[i].in2a  &&  piece(m[i].in2a) != QUEEN )
99 	p += 15;
100 	else
101 	p -= 5;
102 
103 	/* dont see long moves, especially diagonal ones */
104 	p += dist[120*m[i].from+m[i].to].taxi * 3;
105 
106 	/* dont see some knight moves */
107 	if( piece(m[i].in1) == KNIGHT )
108 	p += 10;
109 
110 	/* going backward?  (white)Bf6xc3 is much more difficult
111 	 * to see than (white)Bc3xf6 ***/
112 	if( Color==WHITE )
113 		p += 4 * ( m[i].to/10 - m[i].from/10 );
114 	else
115 		p += 4 * ( m[i].from/10 - m[i].to/10 );
116 
117 	if( rand()%1000 < p )
118 	{ m[i] = m[(*n)-1]; (*n)--; }
119 }
120 }
121 
122 
123