#include<dos.h>
#include<time.h>
#include<stdio.h>
#include<conio.h>
char N[65][8][8]; //Casilla de origen, direccion, alcance=Casilla destino
char H[8][65][8]; //Tipo de pieza, casilla, direccion=Alcance
int A[33],C[33],T[33]; //Tipo,casilla y bando (0vacia,1PB,2PN,3C,4A,5T,6D,7R)
int G[9],C1[9],C2[9],C3[9];
int K[65],P[65],e[8][8],p[6][576];
int main()
{
_AX=0x13;
geninterrupt(0x10);
time_t ti;
char E,far*Q[65],far*q=(char far*)0xA0000000;
char pieza[][6][22]=
{" "," 2 2 "," "," "," 22 22 "," 22 ",
" "," 22 22 "," 222222222222 "," "," 2222 2222 "," 22 ",
" 2222 "," 22222 "," 222222222222 "," 222 2222 222 "," 22 2222 2222 22 "," 222222 ",
" 222222 "," 2222222 "," 222111111222 "," 222 2222 222 ","2222 22 22 2222"," 222222 ",
" 222222 "," 222222122 "," 22222221222 "," 222 2222 222 ","2222 2 2 2222"," 22222 22 22222 ",
" 222222 "," 22222222122 "," 2222222221222 "," 22222222222222 "," 22 22 22 22 ","2211122 22 2211122",
" 2222 "," 2222112222122 "," 2 2222222221222 "," 22222222222222 "," 22 22 22 22 ","21222122211222122212",
" 222222 "," 2222122222122 "," 2212222222222122 "," 2111111112 "," 22 22 22 22 ","21222212211221222212",
" 22222222 "," 22222222222122 "," 22221211222222122 "," 2222222222 "," 222 222222 222 ","22122221222212222122",
" 22222222 "," 2222222222221222 "," 222122122122222122 "," 2222222222 "," 22222222222222 "," 221222212212222122 ",
" 22222222 "," 22222222222222122 ","2221222212122222122 "," 2222222222 "," 22222222222222 "," 2212222222222122 ",
" 222222 ","221222222222222122 "," 222122122122222122 "," 2222222222 "," 22222222222222 "," 22222222222222 ",
" 22222222 ","211222222212222122 "," 22221211222222122 "," 2222222222 "," 21111111111112 "," 21111111111112 ",
" 2222222222 "," 222222 122222122 "," 2212222222222222 "," 2222222222 "," 2222222222222222 "," 2222222222222222 ",
" 2222222222 "," 22 22222221222 "," 2 222222222 22 "," 2222222222 "," 222222222222222222 "," 222222222222222222 ",
" 222222222222 "," 22222222122 "," 2222222 22 "," 2222222222 "," 2222222222222222 "," 2222222222222222 ",
" 222222222222 "," 222222222122 "," 22222 2 "," 211111111112 "," 21111111111112 "," 21111111111112 ",
" 222222222222 "," 222222222122 "," 222222222 "," 22222222222222 "," 22222222222222 "," 22222222222222 ",
" 222222222222 "," 2222222222122 "," 2222222222222 "," 2222222222222222 "," 2222222222222222 "," 2222222222222222 ",
" "," 2222222222222 "," 222222 22222 "," 2222222222222222 "," 2222222222222222 "," 2222222222222222 ",
" "," "," 22222 "," "," "," "};
char figura[][5][13]=
{" 1 1 "," 11111111 "," 111 111 111 "," 111 111 "," 1 ",
" 1111 "," 1 1 "," 1 111 111 1 ","11 111 111 11"," 111 ",
" 1 1 "," 11111 1 "," 1 1 ","11 1 1 11"," 111 1 111 ",
" 1 1 1 "," 1 1 1"," 11111111111 "," 1 1 1 1 ","1 1 1 1 1",
" 1 1 1 1 "," 1 1 1"," 1 1 "," 1 11 11 1 ","1 1 1 1 1 1",
" 1 1 1 "," 1 1 1 1 1"," 1 1 "," 11 11 11 11 ","1 1 1 1 1",
" 1 1 1","1 1 1 1 1"," 1 1 "," 1 1 1 1 1 ","1 1 1 1",
"1 11 1 1"," 1 1 1 1 1"," 1 1 "," 1 1 "," 1 1 1 1 ",
" 1111 1 1 1"," 1 1 1"," 1 1 "," 1 1 "," 1 1 ",
" 1 1 1"," 1 1 11"," 1111111 "," 111111111 "," 111111111 ",
" 1 1 1"," 1 1 1"," 1 1 "," 1 1 "," 1 1 ",
" 1 1 1"," 1 111 "," 1 1 ","1 1","1 1",
" 1111111111"," 11111 "," 11111111111 ","1111111111111","1111111111111"};
char posicion[][3][8]=
{"tcadract","......T.","........",
"pppppppp","..R.....","T.......",
"........","........","....rPP.",
"........","........","...ppp..",
"........",".....p..","...A.P..",
"........","......p.",".R.P.P..",
"PPPPPPPP",".D...Cr.","........",
"TCADRACT","........","........"};
int B[65],BB[8]={0,1,0,-1,-2,0,2,0}; //Promocion y al paso
int S[201][4],J[201][9],JJ[9][9]; //Control de jugadas
int m[201][6],mm[2][2][9][6]; //Secuencia de mate
int aa[9],dd[9],hh[9]; //Rutina principal
int pc1[9],pc2[9],pc3[9]; //Piezas
int pr[3],R[]={0,5,61}; //Casilla rey de inicio
int P1[]={0,1,33}; //Blancas de 1 a P2[1]
int P2[]={0,0,32}; //Negras de P1[2] a 32
int f[65]={1},F[][3]={0,15,0,0,0,15,0,15,0}; //Fondo, perfil
int i[576],I[]={195,227,284,316}; //Tabulacion
int X[13][4]={1155,1219,1219,1276};
int L[]={-1,1,-1,1,-1,1,-1,1,-1};
int LL[]={400,0,400,0,400,0,400,0,400};
int ix[]={-1,0,1,1,1,0,-1,-1,1,2,2,1,-1,-2,-2,-1};
int iy[]={1,1,1,0,-1,-1,-1,0,2,1,-1,-2,-2,-1,1,2};
int D[]={0,2,0,0,0,1,0,0}; //Peon al frente
int d1[]={0,0,4,0,0,1,0,0};
int d2[]={0,2,6,7,6,7,7,7};
int d3[]={0,1,1,1,2,2,1,1};
int Z1[256],Z[]={0,0,0,1,2,3,4,5};
int Z2[]={46,80,46,67,65,84,68,82,46,112,99,97,116,100,114};
int a=15,c=64,t=1,tt=2,M=3;
int b,d,h,j,n,v,w,z,x,y,c1,c2,V,W;
while(a--) Z1[Z2[a]]=a;
for(v=576;v--;i[v]=320*y+v%24)
if((y=v/24)>1&&y<22&&(x=v%24)>1&&x<22)
for(w=6;w--;) if(p[w][v]=pieza[y-2][w][x-2]-32)
p[w][v]-=16;
for(v=13;v--;)
for(a=5;a--;)
for(w=13;w--;) if(figura[v][a][w]-=32)
figura[v][a][w]-=16;
for(a=8;--a;)
for(d=d1[a];d<=d2[a];d+=d3[a])
if(a>6) e[7][d]=2;
else if(a>3) e[a][d]=8;
else if(a<3&&!D[d]) e[3-a][d]=2;
for(v=0;v<8;v++)
for(w=8;w--;B[c--]=BB[v])
if(a=Z1[posicion[v][2][w]]) //Eleccion de posicion[][?=0,1,2][]
if(a<8){
A[++P2[1]]=a;
P[C[P2[1]]=c]=P2[1];
T[P2[1]]=1;
if(a>6) pr[1]=P2[1];
}
else{
A[--P1[2]]=a-7;
P[C[P1[2]]=c]=P1[2];
T[P1[2]]=2;
if(a>13) pr[2]=P1[2];
}
do{
y=c++/8;
x=c-8*y;
Q[c]=q+7680*(7-y)+24*x+936;
f[c]=4-f[c-1];
if(x<2) f[c]=4-f[c];
if(a=A[P[c]]) F[T[P[c]]][0]=f[c];
for(v=576;v--;)
*(Q[c]+i[v])=a?F[T[P[c]]][p[Z[a]][v]]:f[c];
for(d=8;d--;){
if((v=x+ix[d+8])>0&&v<9&&(w=y+iy[d+8])>-1&&w<8)
N[c][d][H[3][c][d]--]=v+8*w;
h=1;
while((v=x+ix[d]*h)>0&&v<9&&(w=y+iy[d]*h)>-1&&w<8)
N[c][d][h++]=v+8*w;
if(--h)
for(a=8;--a;)
if(a>6) H[a][c][d]=1+(R[T[P[c]]]==c&&(d==3||d==7));
else if(a>3&&e[a][d]) H[a][c][d]=h;
else if(a<3) if(e[3-a][d]) H[a][c][d]=1;
else if(D[d]==3-a)
H[a][c][d]=1+(B[c]==3-a);
}
}while(c<64);
printf("%c[2;26fBlancas Negras",27);
for(v=13;v--;)
for(d=4;d--;y=x){
if(v) X[v][d]=5120*v+I[d]+960;
x=X[v][d];
if(v>11||d>2) continue;
for(w=y-x+1;w--;)
*(q+x+w)=*(q+x+w+5120)=7;
for(w=16;w--;)
*(q+x+320*w)=*(q+y+320*w)=7;
}
Inicio:
ti=time(NULL);
for(j=v=0;v<M;v++)
for(w=0;w++<M-v;JJ[w][v+w]=LL[w]);
pc1[n=1]=P1[t]; //Primera pieza
Origen:
C1[n]=C[pc1[n]]; //Casilla de la pieza
if(!C1[n]) goto Siguiente;
K[C1[n]]++; //Simulacion de origen
P[C1[n]]=0;
aa[n]=A[pc1[n]]; //Tipo de pieza
dd[n]=d1[aa[n]]; //Direccion inicial
Alcance:
hh[n]=H[aa[n]][C1[n]][dd[n]]; //Alcance total
if(!hh[n]) goto Direccion;
G[n]=aa[n]!=3; //Alcance inicial (0 para el caballo)
Destino:
C2[n]=N[C1[n]][dd[n]][G[n]]; //Casilla destino
pc2[n]=P[C2[n]]; //Pieza en destino
if(T[pc2[n]]==t) goto Direccion; //Mismo bando
if(aa[n]<3) //Peon
if(D[dd[n]]==T[pc2[n]]){
if(pc2[n]||B[C1[n]]+t) goto Direccion;
if(aa[n-1]>2||G[n-1]<2) goto Direccion;
if(2*C2[n]!=C1[n-1]+C2[n-1]) goto Direccion;
C3[n]--; //Simular captura al paso
pc3[n]=P[C2[n-1]];
C[pc3[n]]=P[C2[n-1]]=0;
}
else if(B[C1[n]]==t) A[pc1[n]]=6; //Promocion
if(aa[n]>6&&G[n]>1) //Enroque
if(K[c=R[t]]>1||pc2[n]) goto Direccion;
else{
for(d=0;d<8;d++)
if(T[x=P[N[c][d][h=0]]]==tt&&A[x]==3) d=8;
else while(h<H[6][c][d]) if(x=P[N[c][d][++h]])
if(T[x]==tt&&h<e[A[x]][d]) h=d=8;
else break;
if(d=d>8) goto Direccion;
if(c<C2[n]) if(K[c+3]||P[c+3]!=pr[t]-3*L[t]) goto Direccion;
else C3[n]=c+3; //Enroque corto
if(c>C2[n]) if(K[c-4]+P[c-3]||P[c-4]!=pr[t]+4*L[t]) goto Direccion;
else C3[n]=c-4;
pc3[n]=P[C3[n]]; //Simulacion de enroque
C[pc3[n]]=(c+C2[n])/2;
P[C3[n]]=0;
P[(c+C2[n])/2]=pc3[n];
}
Simulacion:
C[pc1[n]]=C2[n]; //Pieza a destino
C[pc2[n]]=0;
P[C2[n]]=pc1[n];
c=C[pr[t]]; //Casilla del rey
for(d=0;d<8;d++)
if(T[x=P[N[c][d][h=0]]]==tt&&A[x]==3) d=8;
else while(h<H[6][c][d]) if(x=P[N[c][d][++h]])
if(T[x]==tt&&h<e[A[x]][d]) h=d=8;
else break;
if(d<9&&n<M){ //Nivel siguiente
t=3-(tt=t);
pc1[++n]=P1[t];
goto Origen;
}
Restaurar:
C[pc2[n]]=C2[n];
P[C2[n]]=pc2[n];
if(C3[n]<0){ //Al paso
C[pc3[n]]=C2[n-1];
P[C2[n-1]]=pc3[n];
C3[n]++;
}
if(C3[n]){ //Enroque
C[pc3[n]]=C3[n];
P[C3[n]]=pc3[n];
P[(R[t]+C2[n])/2]=C3[n]=0;
}
if(d=d>8) hh[n]-=aa[n]>6; //No permite enroque
else{
JJ[1][n]+=2; //Jugadas posibles
v=0;
if(n>1)
while(v++<M-n){ //Minimax
x=JJ[v+1][n+v]-JJ[v][n+v];
if(L[v]!=(x>0)-(x<0)) continue;
JJ[v+1][n+v]=JJ[v][n+v]; //Confirma secuencia
if(v==3&&n<4)
for(y=2;y--;)
for(w=n+1;w--;)
mm[y][0][n+3][w]=mm[y][1][n+3][w];
}
else{
S[++j][0]=A[pc1[1]]>aa[1]?A[pc1[1]]:0;
S[j][1]=C1[1];
S[j][2]=C2[1];
S[j][3]=M-1;
while(++v<M)
if(JJ[v][v+1]>1) J[j][v]=JJ[v][v+1]/2;
else{
J[j][v]=JJ[v][v+1]-1;
J[j][v+1]=200-J[j][v];
S[j][3]=v+(L[v]==L[M]);
for(w=v-1;w--;)
m[j][w]=mm[J[j][v]+1][0][v+1][w];
break;
}
}
}
for(v=n;v<M;v++) //Reinicio de contadores
for(w=0;w++<M-v;JJ[w][v+w]=LL[w]);
if(A[pc1[n]]>aa[n]) if(--A[pc1[n]]>2) goto Simulacion;
else A[pc1[n]]=t; //Subpromocion
if(!pc2[n]&&G[n]++<hh[n]) goto Destino;
Direccion:
dd[n]+=d3[aa[n]];
if(dd[n]<=d2[aa[n]]) goto Alcance;
K[C1[n]]--; //Restaura origen
C[pc1[n]]=C1[n];
P[C1[n]]=pc1[n];
Siguiente:
if(pc1[n]++<P2[t]) goto Origen; //Pieza siguiente
if(!JJ[1][n]){
c=C[pr[t]]; //Casilla del rey
for(d=0;d<8;d++)
if(T[x=P[N[c][d][h=0]]]==tt&&A[x]==3) d=8; //Jaque del caballo
else while(h<H[6][c][d]) if(x=P[N[c][d][++h]])
if(T[x]==tt&&h<e[A[x]][d]) h=d=8;
else break;
y=JJ[1][n]=d=d<9;
for(v=0;v<n-2;v++) //Secuencia de mate o ahogado
if(aa[v+2]!=B[C1[v+2]]) mm[y][n>4][n][v]=100*aa[v+2]+C2[v+2];
else mm[y][n>4][n][v]=-100*A[pc1[v+2]]-C2[v+2];
}
if(--n){
t=3-(tt=t);
goto Restaurar;
}
for(v=11-M;v--;)
for(d=3;d--;)
for(b=X[v+M+2][d]+1,V=15;V--;)
for(b-=320,W=d==1?55:31;W--;*(q+b+W)=0);
h=4+2*M;
for(v=10-M;v--;)
if(v<j){ //Ordenar maximos o minimos
for(x=y=0;y++<j;)
if(S[y][3])
if(!x) x=y;
else if(L[M]==((V=J[x][S[x][3]])<(W=J[y][S[y][3]]))-(V>W))
x=y;
else if(V==W&&S[x][3]>S[y][3]) x=y;
y=J[x][S[x][3]++];
gotoxy(26+(t+M)%2*11,h+=2);
if(y>0&&y<200) printf("%3u",y);
else if(y==0||y==200) printf("1/2");
else if(y==LL[S[x][3]-t]/2-L[S[x][3]-t]) printf("1-0");
else printf("0-1");
printf("%c[%u;32f%c%c",27,h,97+(S[x][2]-1)%8,49+(S[x][2]-1)/8);
S[x][3]=0;
b=552+2560*h;
if(a=S[x][0]) b+=34;
else a=A[P[S[x][1]]];
if(z=Z[a]) for(V=13;V--;b-=320)
for(W=13;W--;)
*(q+b+W)=F[0][figura[V][z-1][W]];
}
printf("%c[%u;26fN=%u",27,4+2*M,M);
printf("%c[%u;30f%5.f%c",27,4+2*M,difftime(time(NULL)+1,ti),34);
c1=c2=R[t]; //Casilla del rey en origen
while(kbhit()) getch();
Cursor:
if(c2){
for(y=M;y--;)
for(d=3;d--;)
for(b=X[y+2][d]+1,V=15;V--;)
for(b-=320,W=d==1?55:31;W--;*(q+b+W)=0);
gotoxy(15+11*t,4);
if(j) printf("%3u",j);
else if(JJ[1][1]) printf("1/2");
else if(t<2) printf("0-1");
else printf("1-0");
}
c=c1; //Casilla de origen
c2=x=0;
for(v=576;v--;)
if(*(Q[c]+i[v])==f[c]) *(Q[c]+i[v])=6+t;
while(!(E=getch()));
if(E==27&&!j) return 0;
if(E!=13){
if(E==77&&c1<64) c1++;
if(E==75&&c1>1) c1--;
if(E==72&&c1<57) c1+=8;
if(E==80&&c1>8) c1-=8;
for(v=576;v--;)
if(*(Q[c]+i[v])==6+t) *(Q[c]+i[v])=f[c];
if(y=(E=='+'&&M<8)-(E=='-'&&M>2)) M+=y;
else goto Cursor;
goto Inicio;
}
Eleccion:
if((x+=E!=75)>j||(x-=E==75)<1) if(!c2) goto Cursor;
else x=x<1?j:1;
if(S[x][1]!=c1) goto Eleccion;
c2=S[x][2];
printf("%c[4;32f%c%c",27,97+(c2-1)%8,49+(c2-1)/8);
b=10792;
if(a=S[x][0]) b+=34;
else a=A[P[c1]];
if(z=Z[a]) for(V=13;V--;b-=320)
for(W=13;W--;)
*(q+b+W)=F[0][figura[V][z-1][W]];
F[t][a=y=0]=9-t;
for(v=576;v--;)
*(Q[c2]+i[v])=F[t][p[z][v]];
while(++y<M){
gotoxy(37-(y+t)%2*11,h=4+2*y);
for(d=3;d--;)
for(b=X[h/2][d]+1,V=15;V--;)
for(b-=320,W=d==1?55:31;W--;*(q+b+W)=0);
if(!a) if(J[x][y]>0) printf("%3u",J[x][y]);
else if(!J[x][a=y]) printf("1/2");
else if((y+t)%2) printf("0-1");
else printf("1-0");
}
while(--a>0){
b=586+2560*(h=4+2*a);
y=m[x][a-1];
if(y>0) b-=34;
else y=-y;
printf("%c[%u;32f%c%c",27,h,97+(y%100-1)%8,49+(y%100-1)/8);
if(z=Z[y/100]) for(V=13;V--;b-=320)
for(W=13;W--;)
*(q+b+W)=F[0][figura[V][z-1][W]];
}
while(!(E=getch()));
if(a=A[P[c2]]) F[T[P[c2]]][0]=f[c2]; //Pieza a capturar
for(v=576;v--;)
*(Q[c2]+i[v])=a?F[T[P[c2]]][p[Z[a]][v]]:f[c2];
if(E==27) goto Cursor;
if(E!=13) goto Eleccion;
if(S[x][0]) A[P[c1]]=S[x][0]; //Promocion
aa[0]=A[P[c1]]; //Posibilitar al paso
G[0]=L[t]*(c2-c1)/8;
if(!a&&aa[0]<3&&(c1-c2)%8){
P[c]=A[P[c]]=C[P[c=C2[0]]]=0;
for(v=576;v--;*(Q[c]+i[v])=f[c]);
}
K[C1[0]=c1]=K[C2[0]=c2]=1; //Casillas usadas
do{
C[P[c1]]=c2;
C[P[c2]]=0;
P[c2]=P[c1];
P[c1]=c=0;
for(v=576;v--;)
*(Q[c1]+i[v])=f[c1];
a=A[P[c2]]; //Pieza
F[t][0]=f[c2];
for(v=576;v--;)
*(Q[c2]+i[v])=F[t][p[Z[a]][v]];
if(a>6) if(c2-c1==2) c=c2+1;
else if(c1-c2==2) c=c2-2;
c2=(c1+c2)/2;
}while(c1=c);
t=3-(tt=t);
goto Inicio;
}