Toledo Nanochess
Seguí trabajando en el
Ajedrez Toledo 1
mejorando su núcleo para hacerlo más pequeño, esta versión reducida fue
utilizada como la arquitectura para el
Ajedrez Toledo
2, un programa de ajedrez que tiene interfaz gráfica y ¡puede imprimirse en
una sola hoja de papel!.
Este último núcleo se dividió en dos ramas, una
especializada para crear el más pequeño programa de ajedrez posible, sin
captura al paso, sin enroque y coronación solo a dama, este es Toledo
Picochess.
La otra rama tuvo el objetivo de crear el más pequeño
programa de ajedrez completo con una función de evaluación mejorada, este es
Toledo Nanochess.
En solo 1257 caracteres (sin contar espacios o
comentarios), Toledo Nanochess es actualmente el ajedrez más pequeño
del mundo en lenguaje C, hasta esta fecha (13-feb-2009) no tengo noticias de
ningún programa más pequeño con esta calidad de juego.
El competidor más cercano es H.G. Muller con
Micromax v1.6
de 1433 caracteres. Aunque Toledo Nanochess es más pequeño, se las arregla para
vencer a Micromax v1.6, vea el
juego 1 y el
juego 2, como ambos son programas determinísticos
(sin elementos aleatorios), estas son las únicas partidas posibles, y también
realicé un
torneo Nunn (formato PGN), una manera de
probar programas de ajedrez con diez posiciones iniciales predeterminadas y
alternando colores, de forma que pueda verse la fuerza real, el resultado fue
+5 =11 -4 con ventaja para Toledo Nanochess.
/**************************************************************************\
| Toledo Nanochess (c) Copyright 2009 Oscar Toledo G. All rights reserved |
| 1257 non-blank characters. Evolution from my winning IOCCC 2005 entry. |
| o Use D2D4 algebraic style for movements. biyubi@gmail.com Nov/20/2009 |
| o On promotion add a number for final piece (3=N, 4=B, 5=R, 6=Q) |
| o Press Enter alone for computer to play. |
| o Full legal chess moves. http://www.nanochess.org |
| o Remove these comments to get 1326 bytes source code (*NIX end-of-line) |
\**************************************************************************/
char*l="ustvrtsuqqqqqqqqyyyyyyyy}{|~z|{}"
" 76Lsabcddcba .pknbrq PKNBRQ ?A6J57IKJT576,+-48HLSU";
#define F getchar()&z
#define v X(0,0,0,21,
#define Z while(
#define _ ;if(
#define P return--G,y^=8,
B,i,y,u,b,I[411],*G=I,x=10,z=15,M=1e4;X(w,c,h,e,S,s){int t,o,L,E,d,O=e,N=-M*M,K
=78-h<<x,p,*g,n,*m,A,q,r,C,J,a=y?-x:x;y^=8;G++;d=w||s&&s>=h&&v 0,0)>M;do{_ o=I[
p=O]){q=o&z^y _ q<7){A=q--&2?8:4;C=o-9&z?q["& .$ "]:42;do{r=I[p+=C[l]-64]_!w|p
==w){g=q|p+a-S?0:I+S _!r&(q|A<3||g)||(r+1&z^y)>9&&q|A>2){_ m=!(r-2&7))P G[1]=O,
K;J=n=o&z;E=I[p-a]&z;t=q|E-7?n:(n+=2,6^y);Z n<=t){L=r?l[r&7]*9-189-h-q:0 _ s)L
+=(1-q?l[p/x+5]-l[O/x+5]+l[p%x+6]*-~!q-l[O%x+6]+o/16*8:!!m*9)+(q?0:!(I[p-1]^n)+
!(I[p+1]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^9)_ s>h||1<s&s==h&&L>z|d){p[I]=n,O
[I]=m?*g=*m,*m=0:g?*g=0:0;L-=X(s>h|d?0:p,L-N,h+1,G[1],J=q|A>1?0:p,s)_!(h||s-1|B
-O|i-n|p-b|L<-M))P y^=8,u=J;J=q-1|A<7||m||!s|d|r|o<z||v 0,0)>M;O[I]=o;p[I]=r;m?
*m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ s>1){_ h&&c-L<0)P L _!h)i=n,B=O,b=p;}N=L;}
n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-p]||I[p+=p-O]);}}}}Z!r&q>2||(p=O,q|A>2|o>z&
!r&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N>-K+1924|d?N:0;}main(){Z++B<121)*G
++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&31;Z B=19){Z B++<99)putchar(B%x?l[B[I]|16]:x)_
x-(B=F)){i=I[B+=(x-F)*x]&z;b=F;b+=(x-F)*x;Z x-(*G=F))i=*G^8^y;}else v u,5);v u,
1);}}
Como compilarlo
Primero, descargue el código fuente desde
aquí, también puede descargar versiones
previas:
- Rev. 10-ago-2009, defecto en
detección de jugadas ilegales, un caracter mayor.
- Rev. 25-mar-2009, 100% más lento, doce
caracteres mayor.
- Rev. 07-mar-2009, 66% más lento, un
caracter mayor.
- Rev. 13-feb-2009, 43% más lento, 3
caracteres mayor, tiene una falla al manejar enroque en casos especiales y no
funciona con Cygwin.
Sugiero con franqueza que compile este programa de ajedrez
con la máxima optimización permitida por su compilador, en GCC puede
utilizar:
gcc -O3 -fexpensive-optimizations toledo_nanochess.c -o toledo
Como ejecutarlo
Ejecutelo sin argumentos, introduzca sus movimientos como
D2D4 y Enter (la computadora rechazará movimientos ilegales), en coronación
agregue un número para la pieza final (3 para caballo, 4 para alfil, 5 para
torre y 6 para dama).
Oprima Enter por si solo para que la computadora juegue
(análisis a profundidad de 6 niveles). ¡Disfrutelo!
Interfaz WinBoard
Desarrollé una versión de Toledo Nanochess con mi propia
interfaz Winboard integrada, y su código fuente ¡mide solo 2 KB!, esto lo hace
hasta el momento el módulo de ajedrez más pequeño del mundo.
Está disponible ahora como un paquete completo con código
fuente, logo y ejecutables optimizados para Windows.
Admite control de tiempo y realiza un juego razonable
dado su pequeño tamaño, ha participado en varios torneos en Internet y ha hecho
morder el polvo a algunos programas más grandes.
Previamente H.G. Muller desarrolló Max2WB, un ingenioso
adaptador para utilizar la primera versión de Toledo Nanochess con
Winboard, y Jim Ablett lo compiló amablemente, es sólo de interés histórico:
Necesitará un programa que hable "WinBoard", mostrando un
tablero gráfico mientras llama a Toledo Nanochess, y también pueden visualizar
partidas en formato PGN, algunas interfaces Winboard conocidas son:
/**************************************************************************\
| Toledo Nanochess (c) Copyright 2010 Oscar Toledo G. All rights reserved |
| 1257 non-blank characters. biyubi@gmail.com Jan/11/2010 |
| o This version includes a minimal Winboard adapter (699 extra bytes) |
| o Full legal chess moves. http://www.nanochess.org |
| o Remove these comments to get 2025 bytes source code (*NIX end-of-line) |
\**************************************************************************/
#include <stdio.h>
#include <time.h>
char*l="ustvrtsuqqqqqqqqyyyyyyyy}{|~z|{}"
" 76Lsabcddcba .pknbrqmove %s\n\0?A6J57IKJT576,+-48HLSU";
#define v X(0,0,0,21,
#define Z while(
#define _ ;if(
#define P return--G,y^=8,
B,i,y,u,b,I[411],*G=I,x=10,z=15,M=1e4,f,j,m,n,t,o,L,E,D,O=100;X(w,c,h,e,S,s){
int t,o,L,E,d,O=e,N=-M*M,K=78-h<<x,p,*g,n,*m,A,q,r,C,J,a=y?-x:x;D++;y^=8;G++;d=
w||s&&s>=h&&v 0,0)>M;do{_ o=I[p=O]){q=o&z^y _ q<7){A=q--&2?8:4;C=o-9&z?q[
"& .$ "]:42;do{r=I[p+=C[l]-64]_!w|p==w){g=q|p+a-S?0:I+S _!r&(q|A<3||g)||(r+1&z
^y)>9&&q|A>2){_ m=!(r-2&7))P G[1]=O,K;J=n=o&z;E=I[p-a]&z;t=q|E-7?n:(n+=2,6^y);Z
n<=t){L=r?l[r&7]*9-189-h-q:0 _ s)L+=(1-q?l[p/x+5]-l[O/x+5]+l[p%x+6]*-~!q-l[O%x+
6]+o/16*8:!!m*9)+(q?0:!(I[p-1]^n)+!(I[p+1]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^
9)_ s>h||1<s&s==h&&L>z|d){p[I]=n,O[I]=m?*g=*m,*m=0:g?*g=0:0;L-=X(s>h|d?0:p,L-N,
h+1,G[1],J=q|A>1?0:p,s)_!(h||s-1|B-O|i-n|p-b|L<-M))P y^=8,u=J;J=q-1|A<7||m||!s|
d|r|o<z||v 0,0)>M;O[I]=o;p[I]=r;m?*m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ s>1){_ h
&&c-L<0)P L _!h)i=n,B=O,b=p;}N=L;}n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-p]||I[p+=
p-O]);}}}}Z!r&q>2||(p=O,q|A>2|o>z&!r&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N
>-K+1924|d?N:0;}
#define D(z)_!strcmp(g,#z))
main(){char*a,g[80];clock_t k;setbuf(stdout,0);Z fgets(g+x,69,stdin)){sscanf(g+
x,"%9s%d%d",g,&n,&D)D(quit)break D(force)f=1 D(post)j=1 D(nopost)j=0 D(level)o=
n,E=n?n:20,O=D*6e3/E D(time)O=n/(E-L%E+1)D(new){_*l-'u')l-=32;G=I;B=y=u=f=L=0;Z
++B<121)*G++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&31;}D(go)f=0 D(protover)puts(
"feature myname=\"Toledo Nanochess Jan/11/2010\" done=1")_ isalpha(*g)&&isdigit
(g[1])){a=g;B=*a++&z;B+=100-(*a++&z)*x;b=*a++&z;b+=100-(*a++&z)*x;i=(*a-'q'?*a-
'r'?*a-98?*a-'n'?I[B]&z^y:11:12:13:14)^y;v u,1)_!f)strcpy(g,"go");}D(go){k=
clock();D=0;n=O<50?4:5;B=21;do{m=X(0,0,0,B,u,n);t=(clock()-k)*1e2/
CLOCKS_PER_SEC;*g=B%x+96;g[1]=58-B/x;g[2]=b%x+96;g[3]=58-b/x;g[4]=I[B]-i&z?l[i&
7|16]:0;g[5]=0;n++;_ j)printf("%d %d %d %d %s\n",n,m,t,D,g);}Z m>-M&m<M&t*x<O);
_ o)L++;v u,1);printf(l+23,g);}}}
Toledo Picochess. Un ajedrez en 1K de C
Esta versión del código es similar
excepto que no hay captura al paso ni enroque, y solo se permite coronación
a dama. En 944 caracteres (sin contar espacios o comentarios) o 1009 bytes
(si se eliminan los comentarios) es probablemente
el programa en C más pequeño jamás escrito que juega ajedrez.
/**************************************************************************\
| Toledo Picochess (c) Copyright 2007 Oscar Toledo G. All rights reserved |
| 944 non-blank characters. Evolution from my winning IOCCC 2005 entry. |
| o Use D2D4 algebraic style for movements. biyubi@gmail.com Jan/21/2007 |
| o Only promotion to queen, no empassant or castling. www.nanochess.org |
| o Press Enter alone for computer to play (num.args+5 == depth of search) |
| o Remove these comments to get 1009-bytes source code (*NIX end-of-line) |
\**************************************************************************/
#define F (getchar()&15)
#define v main(0,0,0,0,
#define Z while(
#define P return y=~y,
#define _ ;if(
char*l="dbcefcbddabcddcba~WAB+ +BAW~ +-48HLSU?A6J57IKJT576,";B,y,
b,I[149];main(w,c,h,e,S,s){int t,o,L,E,d,O=*l,N=-1e9,p,*m=I,q,r,x=10 _*I){y=~y;
Z--O>20){o=I[p=O]_ q=o^y,q>0){q+=(q<2)*y,t=q["51#/+++"],E=q["95+3/33"];do{r=I[p
+=t[l]-64]_!w|p==w&&q>1|t+2<E|!r){d=abs(O-p)_!r&(q>1|d%x<1)|(r^y)<-1){_(r^y)<-6
)P 1e5-443*h;O[I]=0,p[I]=q<2&(89<p|30>p)?5^y:o;L=(q>1?6-q?l[p/x-1]-l[O/x-1]-q+2
:0:(p[I]-o?846:d/8))+l[r+15]*9-288+l[p%x]-h-l[O%x];L-=s>h||s==h&L>49&1<s?main(s
>h?0:p,L,h+1,e,N,s):0 _!(B-O|h|p-b|S|L<-1e4))return 0;O[I]=o,p[I]=r _ S|h&&(L>N
||!h&L==N&&1&rand())){N=L _!h&&s)B=O,b=p _ h&&c-L<S)P N;}}}t+=q<2&t+3>E&((y?O<
80:39<O)||r);}Z!r&q>2&q<6||(p=O,++t<E));}}P N+1e9?N:0;}Z I[B]=-(21>B|98<B|2>(B+
1)%x),++B<120);Z++m<9+I)30[m]=1,90[m]=~(20[m]=*l++&7),80[m]=-2;Z p=19){Z++p<O)
putchar(p%x-9?"KQRBNP .pnbrqk"[7+p[I]]:x)_ x-(B=F)){B+=O-F*x;b=F;b+=O-F*x;Z x-F
);}else v 1,3+w);v 0,1);}}
Como compilarlo
Primero, descargue el código fuente desde
aquí.
Nuevamente sugiero que compile este programa de ajedrez
con la máxima optimización permitida por su compilador, en GCC puede usar:
gcc -O3 -fexpensive-optimizations toledo_picochess.c -o toledo
Como ejecutarlo
Ejecutelo sin argumentos para obtener análisis a nivel 5,
con un argumento para análisis a nivel 6.
Introduzca sus movimientos como D2D4 y Enter (la computadora
rechazará movimientos ilegales), oprima Enter por si solo para que la
computadora juegue. ¡Disfrutelo!
Tabla de tamaños de los programas
Una pequeña tabla de tamaño de los programas
Nota: todos los tamaños fueron medidos sin comentarios.
Programa | Bytes de fuente | Caracteres no espacio | Caracteres IOCCC
|
Toledo Picochess | 1009 | 944 | 942
|
Toledo Nanochess | 1326 | 1257 | 1255
|
Toledo Nanochess Winboard | 2025 | 1932 | 1927
|
Ajedrez Toledo 2 | 3473 | 2122 | 2039
|
Ajedrez Toledo 1 | 3004 | 2187 | 2045
|
Versión Algol-68
El neozelandés Neville C. Dempsey, encargado del paquete de
un
intérprete de Algol-68,
ha convertido Toledo Nanochess a Algol-68 y amablemente ha consentido en
publicarlo aquí.
Necesitará el intérprete de Algol-68, coloque Toledo
Nanochess en el mismo directorio que el intérprete y desde la línea de órdenes
teclee (para Windows y Linux):
a68g nanochess.a68
Para mover las piezas introduzca en minúsculas la coordenada
del cuadro origen (p.ej. d2), oprima Enter, luego introduzca la coordenada del
cuadro destino (p.ej. d4) y oprima Enter.
Para Linux pueden activarse piezas Unicode, cheque dentro
del código fuente. Y por supuesto, este es el juego de ajedrez más pequeño
del mundo en Algol-68.
El lenguaje Algol-60 es el padre de los lenguajes Algol-68 y
Pascal, el número viene del año de aprobación de su estándar, o sea 1968,
a pesar de que solamente se utilizó hasta 1975, Algol-68 tuvo una gran
influencia en otros lenguajes de programación, un ejemplo es la sobrecarga de
operadores que se usa extensivamente en Ada y C++.
Actualmente existen varios entusiastas del Algol-68 que
mantienen vivo el lenguaje y crean ejemplos de código, algunos de estos
ejemplos están disponibles en
Rosettacode.org.
El libro
Como puede ver el código fuente de Toledo Nanochess es
extremadamente complicado. Para cada línea de código fuente hay múltiples
razones para las decisiones de programación.
Documenté todo esto y me di cuenta de que había suficiente
material para un libro. Así que por varios años recolecté toda la información
hasta que estuve satisfecho.
Incluí además una descripción de los fundamentos de los
programas de ajedrez, el código fuente comentado de mi participación con un
ajedrez en el JS1K 2010 (2do lugar), una discusión acerca de la interface
Winboard y otros elementos interesantes.
También puede ser de ayuda para estudiar las partes
complicadas del lenguaje C.
Lo he publicado como un libro de tapa dura de 170 páginas
que puede obtener de
lulu.com
o
Amazon.com.
Toledo Nanochess: The commented source code
Ligas relacionadas
Última modificación: 12-feb-2016