#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 e[8][8],k[65],p[65];
int main()
{
_AX=0x13;
geninterrupt(0x10);
time_t ti;
char far*Q=(char far*)0xA0000000;
char pieza[][24][24]={"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000022220000000000",
"000000000222222000000000",
"000000000222222000000000",
"000000000222222000000000",
"000000000022220000000000",
"000000000222222000000000",
"000000002222222200000000",
"000000002222222200000000",
"000000002222222200000000",
"000000000222222000000000",
"000000002222222200000000",
"000000022222222220000000",
"000000022222222220000000",
"000000222222222222000000",
"000000222222222222000000",
"000000222222222222000000",
"000000222222222222000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000020002000000000",
"000000000022022000000000",
"000000000022222000000000",
"000000000222222200000000",
"000000002222221220000000",
"000000022222222122000000",
"000000222211222212200000",
"000000222212222212200000",
"000002222222222212200000",
"000022222222222212220000",
"000222222222222221220000",
"002212222222222221220000",
"002112222222122221220000",
"000222222001222221220000",
"000002200022222221222000",
"000000000022222222122000",
"000000000222222222122000",
"000000000222222222122000",
"000000002222222222122000",
"000000002222222222222000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000002222222222220000000",
"000000222222222222000000",
"000000022211111122200000",
"000000000222222212220000",
"000000202222222221222000",
"000002212222222222122000",
"000022221211222222122000",
"000222122122122222122000",
"002221222212122222122000",
"000222122122122222122000",
"000022221211222222122000",
"000002212222222222222000",
"000000202222222220022000",
"000000000222222200022000",
"000000000022222000002000",
"000000002222222220000000",
"000000222222222222200000",
"000002222220000222220000",
"000022222000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000002220022220022200000",
"000002220022220022200000",
"000002220022220022200000",
"000002222222222222200000",
"000002222222222222200000",
"000000021111111120000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000211111111112000000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000002200002200000000",
"000000022220022220000000",
"000220022220022220022000",
"002222002200002200222200",
"002222000200002000222200",
"000220000220022000022000",
"000022000220022000220000",
"000002200220022002200000",
"000002220222222022200000",
"000002222222222222200000",
"000002222222222222200000",
"000002222222222222200000",
"000002111111111111200000",
"000022222222222222220000",
"000222222222222222222000",
"000022222222222222220000",
"000002111111111111200000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000002200000000000",
"000000000002200000000000",
"000000000222222000000000",
"000000000222222000000000",
"000222220002200022222000",
"002211122002200221112200",
"002122212221122212221200",
"002122221221122122221200",
"002212222122221222212200",
"000221222212212222122000",
"000022122222222221220000",
"000002222222222222200000",
"000002111111111111200000",
"000022222222222222220000",
"000222222222222222222000",
"000022222222222222220000",
"000002111111111111200000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000"};
char figura[][13][13]={"0000001010000",
"0000011110000",
"0000100001000",
"0001000010100",
"0010010001010",
"0010000001010",
"0100000001001",
"1000011000101",
"0111101000101",
"0000010000101",
"0000100000101",
"0001000000101",
"0001111111111",
"0011111111000",
"0001000000100",
"0000111110010",
"0001000001001",
"0010000000101",
"0101010000101",
"1000101000101",
"0101010000101",
"0010000000101",
"0001000001011",
"0000100010001",
"0001000111000",
"0011111000000",
"0111011101110",
"0101110111010",
"0100000000010",
"0111111111110",
"0001000001000",
"0001000001000",
"0001000001000",
"0001000001000",
"0001000001000",
"0001111111000",
"0010000000100",
"0100000000010",
"0111111111110",
"0001110111000",
"1101110111011",
"1100100010011",
"0100100010010",
"0100110110010",
"0110110110110",
"0101001001010",
"0100000000010",
"0010000000100",
"0011111111100",
"0100000000010",
"1000000000001",
"1111111111111",
"0000001000000",
"0000011100000",
"0111001001110",
"1000101010001",
"1010010100101",
"1001001001001",
"1000100010001",
"0100010100010",
"0010000000100",
"0011111111100",
"0100000000010",
"1000000000001",
"1111111111111"};
int B[]={00, //Casillas de promocion y captura al paso
00,00,00,00,00,00,00,00,
02,02,02,02,02,02,02,02,
00,00,00,00,00,00,00,00,
-2,-2,-2,-2,-2,-2,-2,-2,
-1,-1,-1,-1,-1,-1,-1,-1,
00,00,00,00,00,00,00,00,
01,01,01,01,01,01,01,01,
00,00,00,00,00,00,00,00};/*
int q[]={-5,-3,-4,-6,-7,-4,-3,-5,
-2,-2,-2,-2,-2,-2,-2,-2,
00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,
01,01,01,01,01,01,01,01,
05,03,04,06,07,04,03,05};*/
int q[]={00,00,00,00,00,00,05,00,
00,00,07,00,00,00,00,00,
00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,
00,00,00,00,00,-2,00,00,
00,00,00,00,00,00,-2,00,
00,06,00,00,00,03,-7,00,
00,00,00,00,00,00,00,00};/*
int q[]={00,00,00,00,00,00,00,00,
05,00,00,00,00,00,00,00,
00,00,00,00,-7,01,01,00,
00,00,00,-2,-2,-2,00,00,
00,00,00,04,00,01,00,00,
00,07,00,01,00,01,00,00,
00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00};*/
char E,P[6][576];
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 f[65]={1}; //Color de fondo
int x[65],y[576]; //Coordenadas para casillas
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,0}; //Blancas de 1 a X
int p2[]={0,0,32}; //Negras de Y a 32
int i[][3]={0,15,0,0,0,15,0,15,0}; //Perfil
int I[]={195,227,284,316}; // Tabulacion
int xx[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 T=1,TT=2,M=3,X=0,Y=33;
int A,D,H,J,N,V,W;
int C,C1,C2,b,v,w,z;
for(v=576;v--;)
for(y[v]=v/24*320+v%24,w=6;w--;)
P[w][v]=pieza[w][v/24][v%24]-48;
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=9;--w;){
C=56-8*v+w;
A=q[8*v+w-1];
if(A>0){
a[++X]=A;
c[X]=C;
p[C]=X;
t[X]=1;
if(A>6) pr[1]=X;
}
if(A<0){
a[--Y]=-A;
c[Y]=C;
p[C]=Y;
t[Y]=2;
if(-A>6) pr[2]=Y;
}
}
p1[2]=Y;
p2[1]=X;
do{
Y=(C-1)/8;
X=C-8*Y;
x[C]=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]]) i[t[p[C]]][0]=f[C];
z=A>2?A-2:0;
for(v=576;v--;)
*(Q+x[C]+y[v])=A?i[t[p[C]]][P[z][v]]:f[C];
for(D=16;D--;){
v=X;
w=Y;
H=0;
while((v+=ix[D])>0&&v<9&&(w+=iy[D])>-1&&w<8)
if(D<8) n[C][D][++H]=v+8*w;
else{
n[C][D-8][0]=v+8*w;
h[3][C][D-8]=-1;
break;
}
for(A=H?8:1;--A;)
if(A>6) h[A][C][D]=r[t[p[C]]]==C&&(D==3||D==7)?2:1;
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]=B[C]==3-A?2:1;
}
}while(++C<65);
printf("%c[2;26fBlancas Negras",27);
for(v=13;v--;)
for(D=4;D--;Y=X){
if(v) xx[v][D]=5120*v+I[D]+960;
X=xx[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
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[r[T]]>1||pc2[N]) goto Direccion;
else{
C=r[T]; //Casilla del rey en origen
for(D=0;D<8;D++)
if(t[X=p[n[C][D][0]]]==TT&&a[X]==3) D=8;
else for(H=0;H++<h[6][C][D];)
if(X=p[n[C][D][H]]) if(t[X]==TT&&H<e[a[X]][D]) H=D=8; //Jaque
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][0]]]==TT&&a[X]==3) D=8;
else for(H=0;H++<h[6][C][D];)
if(X=p[n[C][D][H]]) if(t[X]==TT&&H<e[a[X]][D]) H=D=8; //Jaque
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
if(N==1){
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;
for(v=0;++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;
}
}
else for(v=0;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];
}
}
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][0]]]==TT&&a[X]==3) D=8; //Jaque del caballo
else for(H=0;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=xx[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=A>2?A-2:0) for(V=13;V--;b-=320)
for(W=13;W--;)
*(Q+b+W)=i[0][figura[z-1][V][W]-48];
}
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
Cursor:
if(C2){
for(Y=M;Y--;)
for(D=3;D--;)
for(b=xx[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+x[C]+y[v])==f[C]) *(Q+x[C]+y[v])=6+T;
while(kbhit()) getch();
while(!(E=getch()));
if(E==27&&!J) return 0;
if(E!=13){
C1+=E==77&&C1<64;
C1-=E==75&&C1>1;
C1+=8*(E==72&&C1<57);
C1-=8*(E==80&&C1>8);
for(v=576;v--;)
if(*(Q+x[C]+y[v])==6+T) *(Q+x[C]+y[v])=f[C];
Y=M+(E=='+'&&M<8)-(E=='-'&&M>2);
if(Y==M) goto Cursor;
M=Y;
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=A>2?A-2:0) for(V=13;V--;b-=320)
for(W=13;W--;)
*(Q+b+W)=i[0][figura[z-1][V][W]-48];
i[T][0]=9-T;
for(v=576;v--;)
*(Q+x[C2]+y[v])=i[T][P[z][v]];
for(A=Y=0;++Y<M;){
gotoxy(37-(Y+T)%2*11,H=4+2*Y);
for(D=3;D--;)
for(b=xx[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=Y/100>2?Y/100-2:0) for(V=13;V--;b-=320)
for(W=13;W--;)
*(Q+b+W)=i[0][figura[z-1][V][W]-48];
}
while(!(E=getch()));
if(A=a[p[C2]]) i[t[p[C2]]][0]=f[C2]; //Pieza a capturar
z=A>2?A-2:0;
for(v=576;v--;)
*(Q+x[C2]+y[v])=A?i[t[p[C2]]][P[z][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){
C=c2[0];
p[C]=a[p[C]]=c[p[C]]=0;
for(v=576;v--;)
*(Q+x[C]+y[v])=f[C];
}
c1[0]=C1; //Casilla origen
c2[0]=C2; //Casilla destino
k[C1]=k[C2]=1; //Casilla usada
do{
c[p[C1]]=C2;
c[p[C2]]=0;
p[C2]=p[C1];
p[C1]=C=0;
for(v=576;v--;)
*(Q+x[C1]+y[v])=f[C1];
A=a[p[C2]]; //Pieza
i[T][0]=f[C2];
z=A>2?A-2:0;
for(v=576;v--;)
*(Q+x[C2]+y[v])=i[T][P[z][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;
}