Text-mode Chess. 18th IOCCC. Best Game.
This is the program that started it all, I wrote it in order
to win the
18th IOCCC
(International Obfuscated C Code Contest), this contest awards the most
complicated programs written in C language, it has a size limit and very
brilliant people employs its minds to do tricks never seen before. Some of the
winning entries are classic and valuable object of study.
My objective was to fit a complete chess program in the
contest limits and give it a nice form.
Here is the source code, written in C language:
#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; }
How to compile it
First, download the source code from
here.
I suggest strongly to compile this chess program with the maximum
optimization allowed by your compiler, on GCC you can use:
gcc -O3 -fexpensive-optimizations toledo.c -o toledo
Because of kind requests of many readers, you can also
compile it with the old Turbo C Compiler or as C++, read the instructions
at the
FAQ.
How to use it
This chess program can work in two modes: two-players, and one player
(always white) against the machine. To get the first mode, run the program
without arguments:
toledo
The other mode is accesible running the program with one argument (5-ply
analysis):
toledo a
Two arguments for 6-ply analysis:
toledo a b
And each succesive argument will analyze one ply more. There is no ply
limit, but beyond 7 ply can be slow, try it at your own risk and computing
time.
Entering movements
When is your turn, you can enter your move, by example, as D2D4
and press the Enter key, the computer will check move legality and will warn
you of illegal moves. All legal chess moves are permitted.
One special case is when you are doing promotion, you must enter the move
with an extra letter indicating the desired piece. The program requires the
piece letter, it will not select automatically a queen, so don't be surprised
if it doesn't accept your move.
By example F7F8N (supossing you have a pawn on F7), will promote it
to a knight, substitute N for the desired piece (N/Q/R/B).
Game status
The computer will check for checkmate and stalemate, also after each machine
move it will show the score of the position, an higher number is better for the
computer, i.e. worst for you.
Program operation
This is a good example of a chess program reduced to the essential. In order
to get it into the contest limits, I used short but slow and unintelligible
algorithms.
The interface accounts for only a fraction of the code, the core does
multiples functions, it is called recursively to analyze and evaluate each ply,
does alpha-beta cutting, move generation, machine playing, check detection,
illegal move verification and does moves after they are verified.
Also sets an standard on ultra-mini-chess programs, the player and the
computer can do all legal chess moves, other features are:
- Illegal move verification.
- Checkmate detection.
- Stalemate detection.
- Even in 5 ply can give a surprise to amateur players.
Obfuscation tricks
- Only one C function, really modular.
- Extensive use of the trinary and comma operators, save a hard
drive today.
- Extensive use of C operator precedence, all good C programmers
remember it... I cannot.
- Exchanged operands every place is possible, someday someone will
understand it,
- Mixed and multifunction expressions on statements, in good
old-BASIC style.
- Macros used to hide C syntax, check unballanced parenthesis and
calls with empty arguments!
- Only includes strictly necessary standard headers, the linker
takes care, and compiles faster... but I'm still not seeing the
difference.
- Uses only one string, very easy to I18N ;)
Older revisions
The original program sent to the IOCCC had two bugs, one of
them converted one pawn of the player to a pawn of the computer, at the style
of the dark side of the force :), and the other allowed to the player and the
computer to castle when in check and over attacked squares, and yes, the
computer "loved" to break that rule every possible time.
I corrected silently the first bug, in fact nobody
detected it, or that was what I thought, recently came to my knowledge that the
German programmer Valentin Hilbig
discovered it by
Jul/12/2007.
The second bug was reported by Andreas, maybe he was very
embarrassed of testing obfuscated code, because he don't said
his last name.
So here is the code:
- toledo_rev0.c, the original program
with the two bugs. May/19/2005
- toledo_rev1.c, the program with the
pawn's bug corrected. Jan/01/2006
- toledo.c, the program with both bugs
corrected. Mar/28/2006.
Curious facts
Some people cannot see the knight's figure on
the source code, really!, try it with your friends, it can serve for some class
of mind reading or Rorschach test.
As the program plays relatively fast, some people feels
forced to play faster, and loses the game!.
Related links
Last modified: Mar/10/2013