\r
int M=136,S=128,I=8e3,Q,O,K,N,j,R,J,Z,LL,GT, /* M=0x88 */\r
BW,BH,sh,\r
-w[16]={0,2,2,-1,7,8,12,23,7,5}, /* relative piece values */\r
+w[32]={0,2,2,-1,7,8,12,23,7,5}, /* relative piece values */\r
o[256],\r
oo[32], /* initial piece setup */\r
of[256],\r
}\r
\r
\r
-D(k,q,l,e,E,z,n) /* recursive minimax search, k=moving side, n=depth*/\r
-int k,q,l,e,E,z,n; /* (q,l)=window, e=current eval. score, E=e.p. sqr.*/\r
+D(k,q,l,e,ev,E,z,n) /* recursive minimax search, k=moving side, n=depth*/\r
+int k,q,l,e,ev,E,z,n; /* (q,l)=window, e=current eval. score, E=e.p. sqr.*/\r
{ /* e=score, z=prev.dest; J,Z=hashkeys; return score*/\r
- int j,r,m,v,d,h,i,F,G,P,V,f=J,g=Z,C,s,flag,FF,*ps=sp,kk=S;\r
+ int j,r,m,v,d,h,i,F,G,P,V,f=J,g=Z,C,s,flag,FF,*ps=sp,kk=S,re;\r
signed char t,p,u,x,y,X,Y,H,B,gt;\r
struct _*a=A+(J+(k+S)*E&U); /* lookup pos. in hash table*/\r
*sp++=0;\r
- q-=q<e;l-=l<=e; /* adj. window: delay bonus */\r
+ q-=q<ev;l-=l<=ev; /* adj. window: delay bonus */\r
d=a->D;m=a->V;X=a->F;Y=a->Y; /* resume at stored depth */\r
if(a->K-Z|z&S | /* miss: other pos. or empty*/\r
!(m<=q|X&8&&m>=l|X&S)) /* or window incompatible */\r
(K=X,L=Y&~S,Score=m,d=3))) /* time's up: go do best */\r
{x=B=X; /* start scan at prev. best */\r
h=Y&S; /* request try noncastl. 1st*/\r
- P=d>2&&l+I?D(16-k,-l,1-l,-e,2*S,2*S,d-3):I; /* search null move */\r
- m=-P<l|R<5?d-2?-I:e:-P; /*** prune if > beta unconsidered:static eval */\r
+ P=d>2&&l+I?D(16-k,-l,1-l,-e,-ev,2*S,2*S,d-3):I; /* search null move */\r
+ m=-P<l|R<5?d-2?-I:ev:-P; /*** prune if > beta unconsidered:static eval */\r
SHAMAX( if(pl[k]<=1&pl[16-k]>1)m=I-1; ) /* bare king loses */\r
N++; /* node count (for timing) */\r
do{u=b[x]; /* scan board looking for */\r
if(i<0&&(pl[t&31]<2|| /* K capture, (of last K), */\r
t>>3&kk!=H&kk!=S||(kk=H,i=-i,0)))m=I,d=98;/* or duple check: cutoff*/\r
if(m>=l&d>1)goto C; /* abort on fail high */\r
- v=d-1?e:i-p; /*** MVV/LVA scoring if d=1**/\r
+ v=d-1?ev:i-p; /*** MVV/LVA scoring if d=1**/\r
if(d-!t>1) /*** all captures if d=2 ***/\r
{v=gt=0;G: /* retry move with gating */\r
v+=centr[p]?b[x+257]-b[y+257]:0; /* center positional pts. */\r
J+=J(0);Z+=J(4)+G-S;\r
pl[k]-=!!t; /* count pieces per side */\r
v+=e+i;V=m>q?m:q; /*** new eval & alpha ****/\r
+ re=v>>Fac(v>>15&16^k); /* Reduce eval if drawish for leading side */\r
if(z&S)V=m-margin>q?m-margin:q; /* multiPV */\r
C=d-1-(d>5&p>2&!t&!h); /* nw depth, reduce non-cpt.*/\r
C=R<EG|P-I|d<3||t&&p-3?C:d; /* extend 1 ply if in-check */\r
do\r
- s=C>2|v>V?-D(16-k,-l,-V,-v,/*** futility, recursive eval. of reply */\r
- F,y&255,C):v;\r
+ s=C>2|re>V?-D(16-k,-l,-V,/*** futility, recursive eval. of reply */\r
+ -v,-re,F,y&255,C):re;\r
W(s>q&++C<d); v=s; /* no fail:re-srch unreduced*/\r
if(v>V&v<l){int *p=sp;\r
sp=ps+1;\r
} /* encoded in X S,8 bits */\r
if(z&4*S)K=X,L=Y&~S;\r
sp=ps;\r
- return m+=m<e; /* delayed-loss bonus */\r
+ return m+=m<ev; /* delayed-loss bonus */\r
}\r
\r
+Fac(int k)\r
+{/* if mating potential in jeopardy, indicate score reduction (as shift) */\r
+ int m,h,i,j,e,f=0,r=0,n=pl[k+1]+pl[k+2]; /* k indicates strong side */\r
+ if(n<2){ /* less than 2 pawns */\r
+ r=1-n; /* reduce by 2 if no pawns */\r
+ m=pl[16-k]-n; /* my pieces (incl. King) */\r
+ if(m<4){ /* we have at most 2 pieces */\r
+ h=pl[k]-pl[17-k]-pl[18-k]; /* his pieces (incl. King) */\r
+ if(h<2)r=0; /* bare K easy even w.o. P */\r
+ j=h-n; /* defenders after sac for P*/\r
+ if(j<3&&j--){ /* can sac, <= 1 piece left */\r
+ i=18-k;W(!pl[++i]); /* get lowest piece */\r
+ e=abs(w[i--])*n; /* sac for Pawn (if any) */\r
+ W(h>1)h-=pl[++i],e-=pl[i]*w[i]; /* total value his remaining*/\r
+ if(!h)e+=3*w[i]; /* dual King, correct w[]<0 */\r
+ j&=pb[i]==-1; /* tough defenders left */\r
+ for(i=k+3,h=m;h>1;h-=pl[i++])e+=pl[i]*w[i],/* lead in piece material */\r
+ f|=pl[i]&pb[i]/*,printf("%d,%d,%d=%d,%d ",i,pl[i],pb[i],e,f)*/; /* detect mating minors */\r
+ if(!f&&e<350 /* non-mating minor ahead */\r
+ ||m-1&(pb[--i]>3|j) /* single color-bound or vs tough */\r
+ ||pl[i]==2&pb[i]<-1)r=3-n; /* non-mating pair */\r
+ }}}\r
+ return r;\r
+}\r
\r
/* Generic main() for Winboard-compatible engine */\r
/* (Inspired by TSCP) */\r
differs: ;\r
}\r
K=I;\r
- cnt = D(s,-I,I,Q,O,LL|4*S,3);\r
+ cnt = D(s,-I,I,Q,Q,O,LL|4*S,3);\r
#ifdef SHATRANJ\r
if(pl[s]==1 && pl[16-s]==1) {\r
printf("1/2-1/2 {Insufficient mating material}\n");\r
while(fscanf(f, "%d,%x", o+j, of+j)==2 ||\r
fscanf(f,"%c:%d",&c, w+i+1)==2)\r
{ if(c)\r
- { od[++i]=j; centr[i] = c>='a';\r
+ { od[++i]=j; centr[i] = c>='a'; w[i+16] = w[i];\r
blacktype[c&31]=i; piecename[i]=c&31;\r
if(piecetype[c&31]==0) piecetype[c&31]=i; // only first\r
pb[i] = pb[i+16] = w[i]>>3 & ~3; // pair bonus, for now 1/8 of piece value, leave low bits for flag\r
if(tlim>TimeLeft/15) tlim = TimeLeft/15;\r
PromPiece = 0; /* Always promote to Queen ourselves */\r
N=0;K=I;\r
- if (D(Side,-I,I,Q,O,LL|S,3)==I) {\r
+ if (D(Side,-I,I,Q,Q,O,LL|S,3)==I) {\r
Side ^= BLACK^WHITE;\r
m = GetTickCount() - Ticks;\r
printf("# times @ %u: real=%d cpu=%1.0f\n", m + Ticks, m,\r
}\r
if (!strcmp(command, "hint")) {\r
Ticks = GetTickCount(); tlim = 1000;\r
- D(Side,-I,I,Q,O,LL|4*S,6);\r
+ D(Side,-I,I,Q,Q,O,LL|4*S,6);\r
if (K==0 && L==0)\r
continue;\r
printf("Hint: ");\r
for(i=0; i<=U; i++) A[i].D = A[i].K = 0; // clear hash table\r
for(nr=0; nr<GamePtr; nr++) {\r
UNPACK_MOVE(GameHistory[nr]);\r
- D(Side,-I,I,Q,O,LL|S,3);\r
+ D(Side,-I,I,Q,Q,O,LL|S,3);\r
Side ^= BLACK^WHITE;\r
}\r
continue;\r
if(b[L] && (b[L]&16) == Side && w[b[L]&15] < 0) // capture own King: castling\r
{ i=K; K = L; L = i>L ? i-1 : i+2; }\r
if((b[K]&15) < 3) GT = 0; // Pawn => true promotion rather than gating\r
- if(D(Side,-I,I,Q,O,LL|S,3)!=I) {\r
+ if(D(Side,-I,I,Q,Q,O,LL|S,3)!=I) {\r
/* did have move syntax, but illegal move */\r
printf("Illegal move:%s\n", line);\r
} else { /* legal move, perform it */\r