#include<dos.h>
#include<stdio.h>
#include<conio.h>
int main()
{
_AX=0x13;
geninterrupt(0x10);
char far*B=(char far*)0xA0000000L;
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",
"000000000022222200000000",
"000000000222222220000000",
"000000002222221222000000",
"000000022222222122200000",
"000000222211222212200000",
"000000222212222212200000",
"000002222222222212220000",
"000022222222222212220000",
"000222222222222212220000",
"002212222222212221222000",
"002122222222122221222000",
"000222222001222221222000",
"000002200022222221222000",
"000000000022222221222000",
"000000000222222221222000",
"000000000222222221222000",
"000000002222222221222000",
"000000002222222222222000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000222222222222200000000",
"000022222222222220000000",
"000002222111111222000000",
"000000221222222122200000",
"000000002222222212220000",
"000000122222222221222000",
"000001212222222222122000",
"000012221211222222122000",
"000122122122122222122000",
"001221222212122222122000",
"000122122122122222122000",
"000012221211222222122000",
"000001212222222222222000",
"000000122222222220022000",
"000000002222222200022000",
"000000000222222000002000",
"000000022222222220000000",
"000000222222222222200000",
"000002222222000222220000",
"000022222000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000002220022220022200000",
"000002220022220022200000",
"000002220022220022200000",
"000002222222222222200000",
"000002222222222222200000",
"000002222222222222200000",
"000000021111111120000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000022222222220000000",
"000000211111111112000000",
"000002222222222222200000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000002200002200000000",
"000000022220022220000000",
"000220022220022220022000",
"002222002200002200222200",
"002222000200002000222200",
"000220000220022000022000",
"000022000220022000220000",
"000002200220022002200000",
"000002220222222022200000",
"000002222222222222200000",
"000002222222222222200000",
"000002222222222222200000",
"000002111111111111200000",
"000022222222222222220000",
"000222222222222222222000",
"000022222222222222220000",
"000002111111111111200000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000",
"000000000000000000000000",
"000000000002200000000000",
"000000000002200000000000",
"000000000222222000000000",
"000222200222222002222000",
"002222220002200022222200",
"002211122002200221112200",
"002122212222222212221200",
"002122221222222122221200",
"002212222122221222212200",
"000221222212212222122000",
"000022122222222221220000",
"000002222222222222200000",
"000002111111111111200000",
"000022222222222222220000",
"000222222222222222222000",
"000022222222222222220000",
"000002111111111111200000",
"000002222222222222200000",
"000022222222222222220000",
"000022222222222222220000",
"000022222222222222220000",
"000000000000000000000000",
"000000000000000000000000"};
int Q[]={00,
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 k[]={00,
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 n[65][8][8]; //Casilla de origen, direccion, alcance = Casilla destino
int h[8][65][8]; //Tipo de pieza, casilla, direccion = Alcance
int a[33],c[33],t[33]; //Tipo, bando y casilla de pieza (0vacia,1PB,2PN,3C,4A,5T,6D,7R)
int s[201][3],j[9][9],jj[201][9]; //Control de jugadas
int f[65]={1}; //Color de fondo
int e[8][8]; //Direcciones de ataque
int x[65],y[65]; //Coordenadas para casillas
int aa[9],dd[9],gg[9],hh[9]; //Rutina principal
int c0[9],c1[9],c2[9],c3[9],c4[9]; //Casillas
int p[65],pc1[9],pc2[9],pc3[9],pc4[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,0,0,0,0,15,0,15,0}; //Perfil
int L[]={0,1,-1,1,-1,1,-1,1,-1};
int LL[]={0,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 z[]={0,0,0,1,2,3,4,5};
int g[]={0,1,1,0,1,1,1,1};
int d[]={0,2,0,0,0,1,0,0}; //Peon al frente
int d1[]={1,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,JQ=0,X=0,Y=33;
int A,D,H,J,N;
int C,C1,C2,C3,b,v,w;
char E;
gotoxy(26,1);
printf("Blancas Negras");
gotoxy(26,2);
printf("------- ------");
for(v=9;v--;)
aa[v]=gg[v]=c0[v]=c1[v]=c2[v]=c3[v]=c4[v]=0;
for(v=8;v--;) for(w=8;w--;)
for(e[v][w]=C=0;C<65;C++)
p[C]=h[v][C][w]=n[C][v][w]=0;
for(v=33;v--;) a[v]=c[v]=t[v]=0;
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]<1) e[3-A][D]=2;
for(v=0;v<8;v++)
for(w=9;--w;){C=56-8*v+w;
A=k[8*v+w];
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;
for(;C<65;C++){k[C]=0;
Y=(C-1)/8;
X=C-8*Y;
y[C]=24*(7-Y);
x[C]=24*X-24;
f[C]=4-f[C-1];
if(X<2) f[C]=4-f[C];
A=a[p[C]];
i[t[p[C]]][0]=f[C];
b=x[C]+320*y[C];
for(v=24;v--;) for(w=24;w--;)
if(A<1) *(B+b+320*v+w)=f[C];
else *(B+b+320*v+w)=i[t[p[C]]][pieza[z[A]][v][w]-48];
for(D=0;D<16;D++){v=X;
w=Y;
for(H=0;H<7;H++){v+=ix[D];
w+=iy[D];
if(v<1||v>8||w<0||w>7) break;
if(D>7){n[C][D-8][0]=v+8*w;
h[3][C][D-8]=-1;
break;
}
n[C][D][H+1]=v+8*w;
}
if(H)
for(A=1;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+(Q[C]==3-A);
}
}
Inicio:
for(J=v=0;v<M;v++)
for(w=0;w++<M-v;) j[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]<1) 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]==0) goto Direccion;
gg[N]=g[aa[N]]; //Alcance inicial (0 para el caballo)
Destino:
c2[N]=n[c1[N]][dd[N]][gg[N]]; //Casilla destino
pc2[N]=p[c2[N]]; //Pieza en destino
if(t[pc2[N]]==T) goto Direccion; //Mismo bando
if(aa[N]<3)
if(d[dd[N]]==t[pc2[N]]){if(pc2[N]||Q[c1[N]]+T) goto Direccion;
if(aa[N-1]>2||gg[N-1]<2) goto Direccion;
if(c2[N]+c2[N]!=c1[N-1]+c2[N-1]) goto Direccion;
c3[N]=2; //Control
c4[N]=c2[N-1]; //Casilla del peon a capturar
pc4[N]=p[c4[N]]; //Simular captura
c[pc4[N]]=p[c4[N]]=0;
}
else if(Q[c1[N]]==T) a[pc1[N]]=c0[N]=6; //Promocion
if(aa[N]>6&&gg[N]>1){if(k[r[T]]>1||pc2[N]) goto Direccion;
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) JQ=D=7;
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]) JQ=H=D=7; //Jaque
else H=7;
if(JQ){JQ=0;
goto Direccion;
}
if(dd[N]==3){if(k[C+3]||p[C+3]!=pr[T]-3*L[T]) goto Direccion;
c3[N]=C+3;
c4[N]=C+1;
}
else{if(k[C-4]+p[C-3]||p[C-4]!=pr[T]+4*L[T]) goto Direccion;
c3[N]=C-4;
c4[N]=C-1;
}
pc3[N]=p[c3[N]]; //Simulacion de enroque
c[pc3[N]]=c4[N];
p[c3[N]]=0;
p[c4[N]]=pc3[N];
}
Simulacion:
c[pc1[N]]=c2[N];
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) JQ=D=7;
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]) JQ=H=D=7; //Jaque
else H=7;
if(N<M&&JQ<1){T=3-(TT=T);
pc1[++N]=p1[T];
goto Origen;
}
Restaurar:
c[pc2[N]]=c2[N];
p[c2[N]]=pc2[N];
if(c3[N]){if(c3[N]==2){c[pc4[N]]=c4[N];
p[c4[N]]=pc4[N];
}
else{c[pc3[N]]=c3[N]; //Enroque
p[c3[N]]=pc3[N];
p[c4[N]]=0;
}
c3[N]=0;
}
if(JQ<1){j[1][N]+=2; //Jugadas posibles
if(N==1){s[++J][0]=c0[1];
s[J][1]=c1[1];
s[J][2]=c2[1];
for(v=1;v<M;v++)
if(j[v][v+1]<2) jj[J][v]=j[v][v+1]-1;
else jj[J][v]=j[v][v+1]/2;
}
else for(v=0;v++<M-N;)
if(L[v]==(j[v+1][N+v]>j[v][N+v])-(j[v+1][N+v]<j[v][N+v]))
j[v+1][N+v]=j[v][N+v];
}
else if(aa[N]>6) hh[N]=1; //No hay enroque
for(v=N;v<M;v++)
for(w=0;w++<M-v;) j[w][v+w]=LL[w];
if(c0[N])
if((a[pc1[N]]=--c0[N])>2&&JQ<1) goto Simulacion;
else a[pc1[N]]=T;
c0[N]=JQ=0;
if(pc2[N]<1&&gg[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(j[1][N]<1){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) JQ=D=7;
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]) JQ=H=D=7; //Jaque
else H=7;
j[1][N]=JQ<7;
JQ=0;
}
if(--N){T=3-(TT=T);
goto Restaurar;
}
C1=r[T]; //Casilla del rey en origen
Cursor:
for(v=1;v<M+2;v++){gotoxy(34-v%2*7,(v+5)/2);
if(v!=T) printf(" ");
else{if(J) printf("%4d ",J);
if(j[1][1]<1)
if(T<2) printf("(0-1)");
else printf("(1-0)");
if(j[1][1]==1) printf("(1/2)");
}
}
C=C1; //Origen
C2=Y=0;
A=a[p[C]]; //Pieza
i[t[p[C]]][0]=6+T;
b=x[C]+320*y[C];
for(v=24;v--;) for(w=24;w--;)
if(A<1) *(B+b+320*v+w)=6+T;
else *(B+b+320*v+w)=i[t[p[C]]][pieza[z[A]][v][w]-48];
while((E=getch())<1);
if(E==27&&J<1) 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);
i[t[p[C]]][0]=f[C];
for(v=24;v--;) for(w=24;w--;)
if(A<1) *(B+b+320*v+w)=f[C];
else *(B+b+320*v+w)=i[t[p[C]]][pieza[z[A]][v][w]-48];
X=M+(E=='+'&&M<8)-(E=='-'&&M>2);
if(X==M) goto Cursor;
M=X;
goto Inicio;
}
Eleccion:
do{if(E==75) if(--Y<1)
if(C2<1) goto Cursor;
else Y=J;
if(E!=75) if(++Y>J)
if(C2<1) goto Cursor;
else Y=1;
}while(s[Y][1]!=C1);
A=a[p[C1]];
if(s[Y][0]) A=s[Y][0];
C2=s[Y][2];
i[T][0]=9-T;
b=x[C2]+320*y[C2];
for(v=24;v--;) for(w=24;w--;)
*(B+b+320*v+w)=i[T][pieza[z[A]][v][w]-48];
C2=s[Y][2]; //Destino
X=C3=0;
if(A>6&&C2-C1==2) C3=C2+1;
if(A>6&&C1-C2==2) C3=C2-2;
for(v=1;v<M;v++){gotoxy(34-(v+T)%2*7,(v+T+5)/2);
if(X) printf(" ");
else if(jj[Y][v]>0) printf("%4d ",jj[Y][v]);
else if(jj[X=Y][v]==0) printf("(1/2)");
else if((v+T)%2) printf("(0-1)");
else printf("(1-0)");
}
while((E=getch())<1);
A=a[p[C2]]; //Pieza
i[t[p[C2]]][0]=f[C2];
b=x[C2]+320*y[C2];
for(v=24;v--;) for(w=24;w--;)
if(A<1) *(B+b+320*v+w)=f[C2];
else *(B+b+320*v+w)=i[t[p[C2]]][pieza[z[A]][v][w]-48];
if(E==27) goto Cursor;
if(E!=13) goto Eleccion;
aa[0]=a[p[C1]];
gg[0]=0; //Control al paso
if(aa[0]<3){if(s[Y][0]) a[p[C1]]=s[Y][0]; //Promocion
gg[0]=L[T]*(C2-C1)/8; //Al paso posible
if((C1-C2)%8&&p[C2]<1){C=c2[0];
p[C]=a[p[C]]=c[p[C]]=0;
b=x[C]+320*y[C];
for(v=24;v--;) for(w=24;w--;)
*(B+b+320*v+w)=f[C];
}
}
c1[0]=C1; //Casilla origen
c2[0]=C2; //Casilla destino
k[C1]=k[C2]=1; //Casilla origen usada
do{c[p[C1]]=C2;
c[p[C2]]=0;
p[C2]=p[C1];
p[C1]=0;
b=x[C1]+320*y[C1];
for(v=24;v--;) for(w=24;w--;)
*(B+b+320*v+w)=f[C1];
A=a[p[C2]]; //Pieza
i[t[p[C2]]][0]=f[C2];
b=x[C2]+320*y[C2];
for(v=24;v--;) for(w=24;w--;)
*(B+b+320*v+w)=i[t[p[C2]]][pieza[z[A]][v][w]-48];
C2=(C1+C2)/2;
C1=C3;
}while(A>6&&C3);
T=3-(TT=T);
goto Inicio;
}