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:
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

Logo de Toledo Nanochess
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.
ProgramaBytes de fuenteCaracteres no espacioCaracteres IOCCC
Toledo Picochess1009944942
Toledo Nanochess132612571255
Toledo Nanochess Winboard202519321927
Ajedrez Toledo 2347321222039
Ajedrez Toledo 1300421872045

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.
También disponible como eBook en mi tienda digital.
Toledo Nanochess book
Toledo Nanochess: The commented source code

Ligas relacionadas

Última modificación: 12-feb-2016