Ajedrez modo texto. 18º IOCCC. Best Game.

Este es el programa que dio inicio a todo, lo escribí con el fin de ganar el 18º IOCCC (International Obfuscated C Code Contest), un concurso que premia los programas más complicados escritos en lenguaje C, tiene un límite de tamaño y personas muy brillantes emplean sus mentes para realizar trucos nunca antes vistos. Algunas de las participaciones ganadoras son clásicas y valiosos objetos de estudio.
Mi objetivo fue encajar un programa completo de ajedrez en los límites del concurso y darle una forma elegante.
Este es el código fuente, escrito en lenguaje C:

#define    F getchar())
 #define H(z)*n++=z;
       #include        <setjmp.h>
    #define v main(0,0,0
           #define Z while(
                                                 #define _ if(
#define o(d)(S=63,u[l]=0,l[d]=6^e,q=1e4>v,0),l[d]=0,u[l]=e^6,S=b,q)
#define I(H,n) { _ r=l[x=H],!r|(r^e)<-1){ _ j=u[l],-7==r|6==r\
){ n; e=~e; return 1e5-443*f; } u[l]=0,t=j+1,i=j-1; _!i&89<\
x)i=j,t=6; _-1==t&30>x)t=j,i=-7; Z++i<t){ d =0; S&= 63; \
a=((j^e)!=1?6!=(j^e)?O[32+x/10]-O[u/10+32]-q:(S|=6!=j?8\
:1,2==u-x)*9+9*(x-u==2):(d=1==j?x-u:u-x)/8+!(!((x-u)%\
10)|r)*99+(j==1?90<x:29>x)*(9*O[28+i]-288))+O[r+28\
]*9-288+O[x%10+33]-f-O[33+u%10]; x[l]=i; S|=(21=\
=u|21==x)*2+(u==28|28==x)*4+(91==u|x==91)*16+32\
*(u==98|x==98)+(20==d)*64*x; a-=k>f?main(a,f+1\
,M,k):0; _ i==c&u==h&!f&N&a>-1e4&x==y)longjm\
p(z,1); S=b; _!N|f&&(a>M||!f&a==M&&1&rand()\
)){ _!f){ _ k){ c=i; h=u; y=x; } } else _ \
L-a<N){ n; e=~e; u[l]=j; x[l]=r; return\
 a; } M=a; } } x[l]=r; u[l]=j; n; } }
typedef int G; char J [ 78 ], O [ ]
=   "HRQAMS#-smaqrh[UTZYTU[|TBA("
"$#(ABT|ba`gg`ab8>GK[_`fFDZXEYR"         "L\t####"
"##B#A#@#G#F#E#D#K\t\3Zlv#tjm"         "\3J#tjm\3Pwb"
"ofnbwf\3Joofdbo\3)&`&`.&`&`"         "#+&g*\t"; G y,
c,h,e,S,*s,l[149]; jmp_buf z         ; G main(G L,G f,
G N,G k){ G u=99,p,q,r,j,i,x         ,t,a,b=S,d,M=-1e9
; char *n; if( *l){ e=~e; Z       u >21){ q= l[--u]^e;
_!-- q){ _!l[p=e?u-10:u+10]){   I(p,)_ e?u>80   & !l[p
-=10]:u<39&!l[p+=10])I(p,)} _ l[p=e?u-11:9+u]   )I(p,)
else _ u-1==S>>6){ l[u-1]=0; I(p,l[u-1]=-2^e);  } _ l[
p=e?u-9:11+u])I(p,)else _ S>>6==1+u){ l[1+u]=0; I(p,l
[1+u]=e^-2); } } _!--q){ n=O+41; Z++n<50+O)I(u+80-*n,
)} _ 0<q&4>q){  n=q==2?53+O:O+49; Z++n<O+(q!=1)*4+54
){ p=u; do I(p-=*n-80,)Z!p[l]); } } _ 4==q){ n=49+O
 ; Z++n<O+58)I(u-*n+80,)_ e&!(S&24)|!e&!(S&3)   &&
 !l[u-2]&!l[u-1]&!l[u-3]&&o(u)&&o(u-1)){ l[u-1]=4
  ^e; l[u-4]=0; I(u-2,l[u-1]=0; l[u-4]=e^4); } _
  e&!(S&40)|!e&!(S&5)  &&!l[u+1]&!l[2+u]&&o(u)&&
   o(1+u)){ l[u+1]=e^4; l[3+u]=0;   I(u+2,l[1+u
   ]=0; l[u+3]=4^e); } } } e=~e;   return M; }
    Z h<130){l[h]=-(21>h|98<h|2       >(h+1 )%
    10); O[h++]^=3; } n=O +14;       s=20+l; Z
     ++s<29+l){ 10[s]=1; 70[s]=~    ( * s = *
      n++ -+84); 60 [ s] =-2; } Z  n=J){ puts
       (58+O); u=19; Z++u<100){ H(32)_!( u%10
       ))H(32)H(O[7+l[u]])_(9+u)%10>7){ H(58
        -u/10)H(32)_ u&1)puts(n=J); } } puts
         (O+58); _-1e4 >v , 1)){ e=~e; puts
          (O+(v,0)> 1e4?e?90:82:96)); break
           ; } _ 1<L&e) { d=v,2+L); printf
            (O+114,h%10+64,58-h/10,y%10+64
             ,58 -y/10,d); } else{ putchar
              (62+e); h= (95 & F-44; c=l[h
                +=(56-F *10]; y=(95&F-44; y
                   +=(56-F*10; Z 10!=(u=(95
                    &F)){ c=5; Z--c>1&&u!=c
                      [O]); c=e^c-7; } } _!
                         setjmp(z)){ v+1,1);
                               puts(   106+
                                O); }   } Z
                                 10!=
                                  F; }

Como compilarlo

Primero, descargue el código fuente desde aquí.
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.c -o toledo
Por constante petición del amable público también es posible compilarlo con el antiquísimo Turbo C o como C++, vea las instrucciones en el FAQ.
El Ajedrez Toledo 1 funcionando

Como utilizarlo

Este programa de ajedrez pueden funcionar en dos modos: dos jugadores, o un jugador (siempre blancas) contra la máquina. Para el primer modo, ejecute el programa sin argumentos:
    toledo
El otro modo es accesible ejecutando el programa con un argumento (análisis a nivel 5):
    toledo a
Dos argumentos para análisis a nivel 6:
    toledo a b
Y cada argumento sucesivo analizará un nivel más. No hay límite de nivel, pero más allá de 7 niveles puede ser lento, pruébelo bajo su propio riesgo y tiempo de computación.

Introduciendo movimientos

Cuando sea su turno, usted puede introducir su movimiento, por ejemplo, como D2D4 y oprimir la tecla Enter, la computadora verificará que el movimiento sea legal y le advertirá de movimientos ilegales. Todos los movimientos legales del ajedrez están permitidos.
Un caso especial es cuando se realiza coronación, debe introducir el movimiento junto con una letra extra que indica la pieza deseada. El programa requiere la letra de la pieza, y no seleccionará automáticamente una reina, así que no se sorprenda si no acepta su movimiento.
Por ejemplo F7F8N (suponiendo que tiene un peón en F7), lo coronará a un caballo, substituya N por la pieza deseada (N=Caballo, Q=Reina, R=Torre, B=Alfil).

Estado del juego

La computadora detectará jaquemate y mate ahogado, y después de cada movimiento suyo mostrará la puntuación de la posición, un número alto es mejor para la computadora, idem. peor para usted.

Operación del programa

Este es un buen ejemplo de un programa de ajedrez reducido a lo esencial. Para mantenerlo dentro de los límites del concurso, utilicé algoritmos cortos pero de difícil comprensión.
La interface ocupa solo una fracción del codigo, el núcleo realiza múltiples funciones, es llamado recursivamente para analizar y evaluar cada nivel, realiza corte alfa-beta, generación de movimientos, movimiento de la computadora, detección de jaque, verificación de movimientos ilegales y realiza los movimientos después de verificarlos.
También pone una norma para ultra-mini-programas de ajedrez, el jugador y la computadora pueden realizar todos los movimientos legales, otras características son:

Trucos de confusión

Revisiones anteriores

El programa anterior enviado al IOCCC tenía dos defectos, uno de ellos convertía un peón del jugador a un peón de la computadora, al estilo del lado obscuro de la fuerza :), y el otro permitía enrocar estando en jaque y sobre cuadros atacados, y sí, a la computadora le «encantaba» romper esa regla cada vez que podía.
Corregí silenciosamente el primer bug, de hecho nadie lo detectó, o eso era lo que yo pensaba, recientemente vino a mi conocimiento que el programador alemán Valentin Hilbig lo descubrió el 12 de julio del 2007.
El otro defecto fue reportado por Andreas, probablemente estaba muy avergonzado de probar código ofuscado, por eso no dijo su apellido.
Y aquí está el código:

Hechos curiosos

Algunas personas no distinguen la figura del caballo en el código fuente, ¡de verdad!, pruébelo con sus amigos, puede servir como un tipo de lectura de la mente o prueba de Rorschach.
El programa juega relativamente rápido, algunas personas se sienten forzadas a responder rápido, ¡y pierden el juego!

Ligas relacionadas

Última modificación: 10-mar-2013