You are on page 1of 176

The commented source code

-fc-

,
The commented source code

scar Toledo Gutirrez

Traducido por:
Rubn Daro Jaramillo
Toledo Nanochess: The commented source code
Copyright@ 2009-2014 by Oscar Toledo Gutirrez.

ISBN: 978-l-304-86437-6

Official website: http://nanochess.org/

The author welcomes your comments, suggestions and errata reports, please
send them to: biyub@gmail.com

You can also follow him on Twitter as @nanochess

First published in 2014.

The font "Cheq" is Copyright (C) 1989 Adobe Systems, Inc. All rights
reserved. Design (D) 1989 John S. Renner, Adobe Systems, Inc.

Public domain illustration of chess goddess Caissa, courtesy of Wikipedia.

All rights reserved. No part of this book may be reproduced in any form by any
means, electronical, mechanical, photocopying, recording, or otherwise,
without the prior written permission of the author.

While every precaution has been taken in the preparation of the book, the
author assumes no responsibility for errors or omissions, or for damages
resulting from the use of the information contained herein.

Other trademarks and trade names may be used in this book to refer to either
the entities claiming the marks and names or their products. scar Toledo
Gutirrez disclaims any proprietary interest in trademarks and trade names
other than his own.

This book has been edited using the Publivision software running under the
Fenix Operating System on a Gll computer developed by Familia Toledo
organization (Www.byub.com)
Contents

Preface iv

Acknowledgnents vi

1. A brief history of chess and computers 1


l.l The first chess program 2
1.2 The first computer chess championship 3
2. The basics of chess programs
2.l Chessboard representation
2.2 The 8 >< 8 representation
2.3 The l0 >< l2 representation U1
\]\lU

2.4 The 16 >< 16 representation (also called 0x88) 8


2.5 Codes for the chessmen 10
2.6 Move generation 10
2.7 The static evaluation of the position 12
2.8 The search function 15
2.9 Quiescence search 17
2.10 More advanced techniques l7
3. Toledo Chess history 19
3.1 The beginning 19
3.2 Toledo Chess development 20
3.3 Architecture 24
3.4 Final development 25
3.5 How to use it 27
3.6 Entering movements 27
3.7 After winning 28
3.8 Time to make it smaller 33
3.9 Toledo Chess 2 35
Toledo Nanochess The commented source code

4 Toledo Nanochess
4.l Evaluation function
4.2 Toledo Picochess
4.3 Commented source code
Line 36
Line 38 divided in three parts
Line 40
Line 41
Line 42
Line 43
Line 44
Line 46
Line 47
Line 48
Line 49
Line 50
Line 51
Line 52
Line 53
Line 54
Line 55
Lines 6l-66
Line 68
Line 69
Line 70
Line 71
Line 72
Line 73
Line 74
Line 75
Line 76
Line 77
Line 78
Line 79
Line 80
Line 81
Line 82
Line 83
Line 84
Line 85
Line 86
Contents

Line 87 84
Line 88 85
Lines 89-90 86
Line 91-92 87
Line 93 88
Line 94 89
Lines 95-96 90
Line 97 91
Line 98 92
Line 99-102 93
Line 103-104 94
Line 105 95
Line 106 96
Lines 107-108 97
Line 109 98
Lines 110-111 99
Line 113 100
Lines 114-120 101
Line 121-126 102
Line 127 103
Line 128 104
Line 129-130 105
Line 131-134 1 06
Lines 135-140 107
Lines 141-142 108
Lines 143-150 109
Lines 151-154 110
Line 156 111
Line 158 112
-1
Lines 159-161
Line 162-163 -I
1

Line 165 J.
-1
_L

Lines 167-174
.-I .-il

-- .__

Line 178
.I .ii

Lines 179-181 118


Line 184 119
Lines 185-188 120
Lines 190-192 121
Lines 193-195 122
Line 196 123
Lines 197-198 124
Line 199 125
Toledo Nanochess: The commented source code

Line 200 126


Lines 201-202 127
Lines 203-204 128
Lines 205-206 129
Line 207-209 130
4.4 The Winboard interface 131

5. Toledo Javascript Chess 137


5.1 Source code forks 141
5.2 The JS1K contest 142

6. Toledo Java Chess 147

A. Bibliography 153

B. Recommended web sites 155

C. Toledo Nanochess games 157


C.1 Toledo Nanochess versus MicroMax v1.6 157
C.2 Nunn match 158
C.3 Some other games 164

About the author 169

iv
Preface

I n this book I will explain the operation of the small chess programs
that I've created since the year 2005, in languages C, Java and
Javascript. These source code files are published on the Internet without
comments on how they operate or what tricks are used to do specific
processing, so they are very hard to understand for non-expert
programmers, but now the mystery is revealed.
The program that gives its name to this book, Toledo Nanochess, is
the world's smallest chess program written in C language. In this book
you will discover the development history that led to its creation,
starting by Toledo Chess 1 (winner of the 18th International Obfuscated
C Code Contest), a chess program in text mode, and its evolution,
Toledo Chess 2 (winner of the 19th International Obfuscated C Code
Contest), where the reduction of code allowed the inclusion of a
graphical chessboard.
Then you will find the complete and commented source code of
Toledo Nanochess. Every single bit of code has a powerful reason to
exist, as the result of endless iterations of development for four years.
Although it is small, Toledo Nanochess is not weak. At the 14th
chess tournament ChessWar, it obtained the 129th position, ahead of 83
competitors (all of them bigger) with an estimated ELO of 1429 points.
Toledo Nanochess was also a participant in the OpenWar contest.
Following the above, the evolution of the program as Toledo Java
and Javascript Chess will be presented. Toledo Javascript Chess itself
evolved into Tiny Chess 1K that won 2nd place in the JS1K contest. A
Some pseudocode based on C language will be used to describe
some of the algorithms. Some basic knowledge of C language is
required to understand the source code of Toledo Nanochess.

V
Toledo Nanochess: The commented source code

Also some knowledge of assembly language could help but it is not


required.
Toledo Nanochess can be compiled properly, without changes,
using any good ANSI C compiler. There are some compilers of this
language freely available on the Internet.
Because of the complexity of the programs described here, instead
of typing them manually in a computer and introducing bugs, it is
recommended to download the source directly from my Web page at
http://nanochess.org/
Enjoy it!
scar Toledo Gutirrez.
February 2014

W
Acknowledgments
For all the good people

N o book is complete without including acknowledgments for the


people who made certain things possible. I don't want to present a
simple list of names, when possible I also want to mention what these
kind people made possible. So here it goes.
My father Oscar Toledo Esteva and my mother Hortensia Gutirrez
Mendoza for supporting me. To my sister Cecilia and my brother Adn
for tolerating me, as I almost drove them crazy because at times I liked
to talk about my chess programs a little too much.
Peter van der Lynden for mentioning the IOCCC in his amazing
book Expert C Programming. Vern Paxson for writing the first chess
program that won the IOCCC. The four judges of the 18th and 19th
IOCCC: Landon Curt Noll (for founding the IOCCC), Leonid A.
Broukhis (for being so patient with my updates), Peter Seebach and
Simon Cooper, together they awarded my entries. Stephen Sykes for
recording the 19th IOCCC presentation.
H.G. Muller for creating a chess program so small that I had to
challenge myself to make a smaller program, for being critical and for
writing the first Winboard interface for Toledo Nanochess. Olivier
Deville for doing the ChessWar and OpenWar tournaments, and for
being kind in our chat and e-mail exchanges.
Luc Miron for proofreading the draft of this book and providing
valuable suggestions.
Peter van der Zee for running the great JSlK contest, also judges
Thomas Fuchs, Christopher Williams, Patrick H. Lauke and Remy
Sharp for awarding 2nd place to my 1K Javascript Chess program.
Mathematician Warren D. Smith for citing my chess program in his
paper Information Content of Human Intelligence and Life (see
bibliography for the download link). Marshall Brain for citing my chess

vii
Toledo Nanochess: The commented source code

program as the World Record #99 of How Stuff Works. David Bolton
for putting my chess as a reference in his C/C++ Games Library.
Dr. Michael Stone from Australia (roolose . com) for developing a
version of Toledo Javascript Chess with self contained graphics.
Chessforeva from Latvia developed a version of Toledo Javascript
Chess with 3D board and animated moves. Jacob Seidelin (Denmark)
for developing a 3D chessboard and renderer that Stefano Gioffr (Italy)
put together with Toledo Javascript Chess to create a 3D chess game
with free rotation.
Valentin Hilbig found the bug of the incredible pawn in the first
version of my first chess program. I thought that nobody would ever
notice it.
Pedro Galvn gave me an honorable mention in the Software
Guru magazine. David Ochoa mentioned my winning entries in his
Byte Podcast.
To all the party at Talkchess, for reading my announcements and
answering my questions.
To all the people who have used their time to test my programs and
write about them on their pages, blogs and forums. Some are (in
alphabetical order): Jos Abanto, Pedro Castro, Mariano Comense,
Jazek Czekaj, David Cummings, Leo Dijksman, Steven Edwards, Mark
Harrison, Gerd Isenberg, Brian Jimnez, Fredrik Jonsson, Robert
Meolic, Williams Molina, Ron Murawski, Christian Neukirchen, Darren
New, Charles Pergiel, Norbert Raimund Leisner, Peter Rhode, Alonso
Ruibal, Steven Schronk, Kang Seonghoon, Peter Sieg, Dusan
Stamenkovic, Dr. Harun Taner, George Tsavdaris, Ciro Vignotto, Alvy
(Microsiervos . com), and various Spanish, Turkish, Russian, Korean
and Chinese students whose names remain unknown.

viii
Chapter 1
A brief history of chess and computers

T he first real mechanism capable of playing chess without human


help, albeit in limited form, was invented in 1912 by the Spaniard
scientist Leonardo Torres y Quevedo. This machine was able to conduct
a mate of king and rook versus king in 63 movements or less, which by
the actual FIDE rules would be a tie. For locating the chessmen
positions the machine used loadstones located under the chessboard.
Being completely mechanic and filled with endless gears in the same
tradition as Babbage's machines, it was pretty ingenious.
Years later the mathematician John Von Neumann established the
basis for future computer chess with his games' theory and the Minimax
algorithm, described in 1928 in Zur Theorie der Gesellsschaftsspiele,
where a player tries to maximize his winnings while at the same time to
minimize his opponent's winnings.
These theories urgently required digital computers that would
appear only with improvements to triode and the invention of the
transistor, both a consequence of the Great War effort.
In 1949, Claude Shannon, a researcher at the Bell Telephone
Laboratories, presented a paper entitled Programming a Computer for
Playing Chess in a meeting in New York, providing the basis for
modern chess programs.
Shannon used the ideas from John Von Neumann, taking into
account the limitations of the computers of that time. He described two
gaming strategies for a computer, the A-strategy and the B-strategy. In
the first, the computer tries to explore all the possible moves and the
respective countermoves recursively until a determined analysis depth is
reached. If in a typical game there exists 32 possible movements at the
playing side, and we want to analyze 6-ply depth, then there are
32><32><32><32><32><32 movements (around 1 trillion of combinations),
too much for the snail-paced computers of the 1950s.

1
Toledo Nanochess: The commented source code

This disadvantage was noted by Shannon, and he viewed the


A-strategy as impossible (how could he imagine future advances of
computers?) so he went ahead with explanations of the B-strategy,
where the computer would only analyze a number of the <<best possible
moves at every ply depth. For example, on the first ply the program
would only search the best 5 moves. But there was a problem, Shannon
had no idea how to choose these great moves. Even after years of
research no one was able to establish an <<exact way of determining if a
chess movement is better than other, so the programs based on the
B-strategy never got very far.
White turn
plyl D2-D4 I U D2-D3J ...another 18 moves...

Black turn // \f
~ - - a f - ...another20inoves...
1 2 - D7-D5 D7-D6
py 1 . . The tree for the
I/ / ...another 18 moves... starting chess
position
piys -----------~-------~
Afterwards, several authors discovered independently how it was
possible to reduce the number of visited combinations in A-strategy
using a simple algorithm called Alpha-Beta Cut.
The point of the Alpha-Beta Cut is that if a chess move generates a
winning score for the player, but the answer from the opposite side
superates all the current winnings, then it is not necessary to further
analyze that move and it is cut shoit automatically. This dramatically
reduces the number of search combinations, but at that time it still was
notenough.

1.1 The first chess program


The first chess program for a real computer (the MANIAC I) was
developed in the l950s at Los Alamos, United States, by some of the
scientists who worked on the hydrogen bomb: Stanislaw Ulam, Paul
Stein, Mark Wells, J . Kister, W. Walden and John Pasta.
The MANIAC could only handle 11,000 operations per second and
only had 600 words for programs, so the program was written to work
with a 6x6 squares chessboard, removing the bishops of both sides and
pawn double-move, en passant and castling. It required at least twelve
minutes to search 4-ply depth, and it was no surprise that the experiment

2
A brief hston/ of chess and computers

was dropped after 3 games: It won a single game against a novice lady.
This was the first time that a computer won in a game of intellectual
skill.
-- - -- % . The chessboard used by the
MANIAC I.
7
%'/4%
sss \

f"ii:= `>*l>~\ hf
s=- rU5s\"'
\\\.
"__\
:NQ ' llln Q
2\\ `$k
Llnnnl
sl>
in-auna
\\\\.
,\
~ ~ L

MANIAC 1 - Lady
Los Alamos 1956

l.d3 b4 2.Nf3 d 3.b3 e 4 Nel a4 5.bxa4? Nxa 6.K2? NCB 7.Nxc3 bxc3+
8.Kdl 4 9.a3 Rb l0.a4 Ra 11.a5 Kd5 l2.Qa3 Qb5 l3.Qa2+ Ke5 14 Rbl Rxa5
l5.Rxb5 Rxa2 l6.Rbl [it Saw mate! 16...Ral] l6...Ra5 l7.f3 Ra4 l8.fXe4 C4

Chessboard after 18... c4


/ 6!

/ / /

l9.Nf3+ Kd 20.e5+ Kd5 2l.exf6=Q NGS? 22.Qxd4+ KC6 23.Ne5#.

The advances at that time were very small, limited by the available
computing power.

1.2 The first computer chess


championship
In 1961, Alan Kotok, a student at the MIT
wrote a chess program for his thesis, guided
by his professor John McCarthy. His first
program was not very good and sometimes
performed illegal moves. Kotok forgot
about it after graduating. Years later he
would become chief designer of the PDP-10
computer and inventor of the gaming
joystick.
When McCarthy left the MIT for the
Artificial Intelligence Laboratory at The mythical chess goddess
Stanford, he picked up Kotok's program and Caissa, illustration of the
did several modifications, resulting in a XVIII century, by
B-strategy program that analyzed 4-ply Domenico Maria Fratto.
depth.

3
Toledo Nanochess: The commented source code

At the end of 1966, a small tournament was organized between the


Kotok-McCarthy program and a Soviet program from the Experimental
and Theoretical Physics Institute (ITEP) at Moscow. It used A-strategy
and analyzed 3 plies. The Soviet program won two games and tied other
two more. This Sputnik of chess programs was the cause of a renewed
interest in chess programming in the United States.
The ACM (Association for Computer Machinery) created a chess
championship exclusively for computers. The first program that won
this championship was CHESS 3.0 by Larry Atkin and David Slate
from the University of Illinois.
At the same time, the Soviets enhanced the ITEP program and
called it Kaissa (after the mythical chess goddess Caissa). It reached an
analysis depth of 7 plies, and its major success was winning the
International Computer Chess Championship at Stokholm in 1974,
leaving CHESS 3.0 in second place.
In 1975, the German Computer Chess Championship was
organized. It attracted many German programmers, who afterwards
would create various famous professional chess computers.
In the 19805, advances in chess programming were multiplied
thanks to the publication of numerous research papers on the subject.
And the computing power of chess programs started to surpass human
chessmasters.
During the l990s, the chess champion Garry Kasparov began to
suffer against the pounding of cybernetic beasts such as Deep-Blue of
IBM, especially designed for doing evaluations of hundreds of millions
of positions per second. One human pitted against a computer
programmed by a team of scientists.
Near the 2lst century, new analysis and cutting algorithms led to
the creation of powerful programs that probably only a handful of
humans can beat, if not one or two.
Perhaps in the early part of the 2lst century we will see the first
chess program that will not be beatable by a human being. This doesn't
mean that chess will lose its attractiveness, only that as we see games
between human chess champions, we will also watch, with great
interest, exclusive championships between chess programs, and we will
have fun analyzing the impressive combinations produced by these
soulless machines.

4
Chapter 2
The basics of chess programs

F or the implementation of a chess game in a computer, it is


necessary to determine the internal representation of the
chessboard and chessmen. An incorrect representation will cause the
program to be slow and inefficient, while an optimum representation
will help to make a fast program. q
The speed is something very important for a chess program, as it
will allow the analysis of a higher number of moves and depth levels
that can mean the difference between victory and defeat.
Here is a brief enumeration of the requirements of a chess game:
~ A way to represent the chessboard
' Codes for the chessmen
~ Preservation of information about movement of king and
rooks (needed for castling)
- Preservation of information about the last pawn moved two
squares ahead (needed for en passant)
* Indication of actual playing side (white or black)
- Optionally, extra information for discovering repeated
positions and the rule of 50 movements.

2.1 Chessboard representation


Since the beginning of chess programs, the chessboard has been
represented in various ways within the computer's memory. Novice
programmers tend to define the chessboard as a bidimensional array of
8 >< 8 squares.

5
Toledo Nanochess: The commented source code

int chessboard[8][8],'

chessboa rd[0][O] = [bloc/<_ro0k} ;


chessboord[O][1] = {black_knig/11],-

c7iessboard[4][4] = [empr_y_sqtza1'e};

cliesSboord[7][7] = [W/i,ite_rook} ;

This definition is extremely slow. For example, moving a knight


would require code similar to this:

void move_km`g/it(inr row, im column)

int torget__row;
int rai'get_co[r,mzfi.,'

to rget_row = row - 2;
targer_c0ltmm = column - I;
tf(torget__row >= 0 && targer_roW <= 7
&& tar'ger_coli-zrmi >= 0 && torget_coltmm. <= 7
&& {empzjv_square or eriefe1iy_piece} )
genemre__m0ve(row, column, rorget_row, target__co1Lmm);
/* code for the (mot/ter seven. movements of the knight */
}

Note that it is necessary to calculate the new coordinates using two


aSSign1'nentS (target_row and target__co1u.mn), and alSO tO
determine if this new location is inside the chessboard, and finally it is
necessary to check if the square is valid (an empty square or a square
with an enemy piece), only then can the move be annotated for further
analysis.
Because the computer's memory is ordered sequentially, it is a lost
of time to use bidimensional arrays. The computer will do calculations
internally with a multiplication (or shift) plus an add for indexing each
square of the chessboard. By example, it converts intemally a [5] [6]
'[0 a[5 * 8 + 6].

Many people have independently discovered the advantage of


representing the chessboard as a one-dimensional table. The following
are the most popular representations:
64 numbers (8 x 8), one for each square.
120 numbers (10 >< 12), one for each square adding
<<frontiers>.
' 256 numbers (16 >< 16), the chessboard located in a corner.

6
The basics of chess programs

More variants exist which are less popular. Now we will analyze the
advantages and disadvantages of each representation.

2.2 The 8 < 8 representation


The 8 >< 8 representation is simply something like this:

int chessboard[64],'

0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27' 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63

For example, a movement of the knight can be represented as x- 17,


but here the difficulty is to determine if the knight is outside> the
chessboard. Typically this technique is applied with precalculated tables
of valid movements for each piece on each square. This can be very
efficient when used with bitboards. Remember that 64 bits fits perfectly
in two registers of a modem 32-bits computer and in one register of the
more modern 64-bits processors.
This technique allows for greater speed and it is applied in the
majority of the champion programs, though can be painstaking to
precalculate the tables before starting the program or at the start of the
program's execution.

2.3 The 10 < 12 representation


The 10 >< 12 representation is something like this:

7
Toledo Nanochess: The commented source code

int C/iessb0ar(1[I 20],'

21 22 23 24 25 26 27 28
31 32 33 34 35 36 37 38
41 42 43 44 45 46 47 48
51 52 53 54 55 56 57 58
61 62 63 64 65 66 67 68
71 72 73 74 75 76 77 78
81 82 83 84 85 86 87 88
91 92 93 94 95 96 97 98

In this case the chessboard of 8 >< 8 is preserved in the central part


of the array, and every square along the perimeter is filled with a special
number that marks the border, which is regarded as an invalid square.
The movement of the knight seen previously can be done with a
substract of 21, like this:

void moi/e_kniglzt( int square)


/
int mrget_square,'

tcir'get_square = square - 21;


tf ({empt}'_square or erzem_r_pt`ecej)
genemte_m0ve(square, rarger_square);
I

The calculation of row and column can be done using division and
remainder by ten, but this can be a little slow.
This is the representation chosen for five of my chess programs,
including Toledo Nanochess.

2.4 The 16 >< 16 representation (also called 0x88)


The 16 x 16 representation is something like this:

8
The basics of chess programs

int chessboai^d[256],'

0 1 2 3 4 5 6 7
16 17 18 19 20 21 22 23
32 33 34 35 36 37 38 39
48 49 50 51 52 53 54 55
64 65 66 67 68 69 70 71
80 81 82 83 84 85 86 87
96 97 98 99 100 101 102 103
112 113 114 115 116 117 118 119

Here the chessboard of 8 >< 8 is stored iri the superior left comer of
the array, all other indexes are not used.
The decimal numbers appear to make no sense in this
representation, but if we show them as hexadecimal values:

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07


0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17
0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27
0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37
0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47
0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57
0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67
0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77

Then it makes sense! The bits 0-2 contain the colurmi (from 0 to 7)
and the bits 4-6 contain the row (from 0 to 7 too).

void move_knight(int square)



im* target_sqttare,'

target_square = square - 0x21;


if ((target_sqttare & 0x88) == 0 && {enipry___square or enemy_piece} )
genemre_m0ve(sqti,ore, torget_squore)`;
7

This technique is typically used by hardware, because it can do a


fast determination if a square is inside the chessboard, but when done
via software it can be a little slower because of the extra test that can be
removed if the movements table is precalculated.

9
Toledo Nanochess: The commented source code

2.5 Codes for the chessmen


If we must choose an optimum representation for the chessboard, we
must also choose codes for the representation of every chessman
contained on the squares. There are various techniques.
When Shannon wrote his paper in 1949 about chess programs, he
suggested the following values for the chessmen:
6 = White king
' 5 = White queen
== White rook
= White bishop
= White knight
~ = White pawn
= Empty square
- = Black pawn
- = Black knight
- = Black bishop
- = Black rook
~ - = Black queen
- o\U_,:_UJ\_),CD*- l\.)LJ-I=
l Black king

With this style it is necessary to preserve the information of king


and rook moved using extra variables and code for detecting the
movements.
Another option is to represent the chessmen code using three bits
(for example, 1-: pawn, 2=knight, 3=bishop, 4=rook, 5=-queen, 6=king)
use other bit for side (0= White, l= Black) and maybe another bit for
signaling a piece not moved. In this case the information for castling is
available directly and there is no need for special code.

2.6 Move generation


Movement generation is an important part of a chess program. It must
analyze the complete chessboard, looking for all the chessmen of the
current playing side and generate the possible legal movements for use
in the search function.
The simplest technique consists of examining the chessboard square
by square looking for the pieces of the current side. For example, for the
architecture of the 10x12 chessboard:

10
The basics of Chess programs

for (square = 21; square < ZOO; square++) [


z sqnare that contains our piece}) {
switch ({piece}) {
case [pau/vn}.' generate pawn rnoves}; break;
case ,knight] : fgenemte knight moves}; break;
case {bish0p]: {generate bshop rnovesj; break;
case {r'00k}: {genemte rook m0ves}; break;
case (queen): {generate queen moves}; break;
case ,"king}.' {generate king moves}; break;
1'
J
}

Of course this is an inefficient technique. Typically it is preferred to


record and preserve the actual location of every piece, to avoid having
to search the 64 squares, only the 16 that actually contain a piece.
The movement generation consists in verifying to Which squares the
current piece can move legally. It must not leave the king in check. By
example, the code for a bishop could be something like this:

void genera te_bish0p_m0ves(int square)

actnal_sqnare = square;
While (I ) {
acntal_square -= 1];
if ({chessb0czrd_b0rder or 0Wn_piece})
br'ea<;
genemre_rn0ve (square, actnal_square),'
if ({enen1y_piece})
break;
J
/* code for the another 3 directions */

When the program generates the movement, it moves the piece on


the chessboard and then verifies if the king is in check. If it is, then the
move is not a legal one and it is discarded, otherwise it is added to a list
of legal moves, then the chessboard is restored.
To verify if the king is in check, the most common algorithm is to
save its current position and then explore the directions from Where it
can be attacked, looking for an enemy's piece.

11
Toledo Nanochess: The commented source code

-= ==- '_~=_`f: .:.'_:_._ -. _- _-_"*i*?lll'?'


ii _;= -_'
~;w_\.;j<e1'
_-.__~_\,.;;' -- ,*\: '~_' :-:
$9 _ yr -: ' Q . :_. \ _______-; :'-'"_:- _ <^11*
n_.'-;,__ 'y -;f ,W - ut ~_'-1,'-" .,.1., 5;; '<_ _ .`_-li.
"* "11 -: cf- 4-" . -~ - '--`T"'-*;t- '"- 1" 't.-'.- " _- `i--
'ffi ' te -lg' 1 . .fffff .~:f.~
. -1 riff _ '
--ii ht _ .-;.-1 - 1'-'5 5"
1 f;-~ '_ '- ;
_ i' ' ` 7- m.- .' `

\. _ ., _ _\ . ,- __ M-_ _ , ,i .
_,,_~:s'=;-t' .- _ __-,- ;r_v.
~_=- =~-. = -- .f `--' *- ' -__- -;- asiq
_- -1 - - -
141
I \ - ~'I1- `-`f-V1 - _ _.:-_-; '::u' ' _. - I _ v- W

. ''"- ir ';' _` ` "`'- 5 "


has s.tl;=:
_,;; ff,-M
3-'ft nit;
- _~ _
fs, ~ :tits2
~ ~. - - - -
Tf t - T' f One idea for ver1f1cat1on of
mas
2"" `t^"'*l.\.\-
f 1 .^ mag .. a- 1-W. -..--1-3: _
wn@ ~t af Q; v.-.w - I, ha un (A ---_\'**H'-'.-
_ .
. si '-cf
`-.''._t@_`-.
'- --n'-.
._;=,`_-
-' :-*fx ' . '
-
_
' I *Q "
1;*-E
-'
f:'t_____tg
"-_
_:-_
'fi _
7'..f'e""F-5-'
_
_-W,
^'
_ 1*" l
. __
.\.
_-
' .
,_
_ ___ 5-''_'_, -_
-.
if;-rw'-;-\-HM;
.W fl
-1:-,
*- g c e .
rm :_ _.. If , ___;___?__(_______, __ aa~
.
-_ .,. _
_
\__;__ 3 ___* ~*%a
__-_ _ _,_ _-.t ._-__ - . ` s-wav
______g__ _` ._ ._ \ ._ -_,_ _._.__ __ v _

_
' _
' _' _'I'\\Z"f _
it.-4. P
l.-sa.-' --
' 2 >: _---_
-1-1'-' ,
,EQ = -
_ f\`-'3
Y-Il" -__
. \-:-_'f '\=-`
_ _' _:
;:
`-'

-
_; _ _
.. " --si
~ < W
_ - -;

-Y-'
Una idea para la
'?W*i"-x ' gi' * .ftii' =.= -- "`, ' '-_?
_ ___
,:-1-.._.= -
`__f_--'
:sf
" -
'tg--. - te
tt.-T.
" WT*
"sw"_.+'1'-
` .-9i1=*'
verificacin del
4:1, n 1 : -:fl-\ -` _1'.-1 _ 5': ' '-\ "fi ' _ . - '_ _
~
Q_ nt~f?5-,_-far;__
--: ..~_ \'-'-'.~- -
-- 'I
sf -f - "'*'5.;-
1 .
--*Tr_. _ - -.-
, "'4 -_~.,
te-_ `-fs-.:?* ~ .
^\ <
'1:;'-' - ~: _ _-
1 -"_f'_-11:
=. -` _ rey en jaque.
: '- .-_.-`3. '_ _ 'seem =\ _ __ U -u..--fat-__-t _
_ __ ty-j - -1 _ _' __
*'_ ft.v- W"-'W
_ .
_ '-Is. - ~ .
rw-e
' - _- .-;'\______,
,
-. >+ $__- ' _
' ._ fr t=- <=; - . -es 1' .
:-_'- -.~ 3 ,r
.- -' '-:-. -
-.av x 5,.
i - -. ._ _fl;-1\.
#%%
`='*aaa
__ Y ` _I_`_._ __ _
W- $5; _ 5;:-._'.; .-
`_`_v_W___H
si tar
"-'j==t- _=_''f,?;'-% _ :__ ' - . ''-"*-"'
_~<e-f e"-.-\- Z";' ___
-_:_:- fa- -~
\. f -:tc-_?-tt f- ' - ; p
I
-te
'*2?Q'j-1_ ':-2 f~
eli'-it
_ -=,-_*_~_ 2*.- Wa
M5'-` *_ ' - __;-efi --
_ _' u

--.. _-P5*
--- ~
_
:C :~_%_:-
l.
I-
`
1-72f-..-_:-. *" %.
~=-a_a
-au_1:'-1,2-`'
__ _

2%
. -

nf w* -e" *_`
trgt* %_~ea_____wf,2______-; %__@ gg
f:_-
j.';___.__:',__.3-
'-;=-=_'._'
i_<f`=f"; ___ __Q?
_ -11j-:.-._-A

Obviously finding a check for every move can be very slow, but
there are various techniques for doing a faster detection. Some of them
are:
- Bitboards (also called bitmaps). A map of 64 bits is created
of all squares attacked by the enemy. The check Will be
detected if the king occupies an attacked square.
Pseudolegal. Generate all the moves, even those that leave
the king in check, and the search function will
automatically delete these moves When it detects the
opposing side <<eating the king.
Special moves such as castling, promotion and en passant are
processed by movement generation.
Obviously, generating a complete list of all moves can be very
time-consuming. Advanced chess programs only generate the moves
that pretend to analyze, for example, all captures and then all other
moves (for this the bitboards option can be very useful). When using
transposition tables, some programs do not actually generate any moves,
they only check if the suggested move from the transposition table is
legal.

2.7 The static evaluation of the position


Por doing a good game of chess, the program must have some
<<knowledge of the position in numerical form. This way it can know if
a position is better or worst than another.
The simplest method of evaluation is to add the material value of all
the pieces and substracting from it the value of all enemy's pieces. The
typical values are:

12
The basica of chess programs

A pawn scores l00 points


A knight scores 300 points
A bishop scores 300 points
A took scores 500 points
A queen scores 900 points
The king scores infinite points, because it generally cannot
be captured, but could be useful to assign it a score like
20000 if the program generates pseudolegal moves.
These values must not be taken as an absolute truth, because in
chess a piece can be more or less valuable depending on the actual state
of the game. By example, the GM Larry Kaufman in his article The
evaluation of material imbalances has analyzed 300,000 chess games
between players with FIDE rating of at least 2300 and he estimated that
a bishop pair scores up to half-a-pawn and more if the opponent doesn't
have lesser pieces, or that a rook has a bigger value if there are scarce
pavvns, versus knight having a bigger value if there are many pavvns
present.
A chess program that only takes into account the material
evaluation Will do idiotic moves. It is necessary to take into account the
actual position of the chessman for doing reasonable moves.
Por example, it is a Well-known fact that a knight in a chessboard
comer is silly, so for each piece a value map can be created, assigning a
value to each square. This way the program Will not only take into
account the material value, but also the positional value.

value = O;
for ({each own 's piece] )
value += n1arerial_valtte[{piecej] + l0cati0n__value[{piece}][{square)];
for ({each enernv 's piece})
value -= fnaterial_vahte[{piece}] + l0ccztion_valne[[piece}][{sqnare}];

This code is very inefficient. It is possible to enhance it by saving


the current evaluation in incremental form using a global variable,
increasing or decreasing its value for each piece captured.
Just like for piece scoring, the value of a position can change as the
game progresses. For example, at the start of the game it is a very bad
idea to move the king, but near the end it can be very convenient to
position it near the pawns or the center.
Material and location scores will automatically enhance the
computer's game style, but it is still rather simple, and it is necessary to

13
Toledo Nanochess: The commented source code

take into account other scoring factors which are not quite as important,
but these lesser factors help the chess program to choose a better move:
A pair of bishops well located
- A rook in an open column
' A rook in the seventh row with the enemy's king in the
eighth row
Doubled rooks in an open column
A pawn defended by a rook behind it
A piece attacking two or more pieces
Piece mobility
X-ray vision (for example, a bishop attacking a pawn that
covers the king)
' Being near the enemy's king
Outposts (knight or bishop protected by pawn and cannot
be attacked by enemy's pawns)
Approaching classical checkmate patterns (for example,
Legal checkmate).
Likewise some negative factors:
~ Doubled pawns (two or more pawns in the same column)
lsolated pawns
Overcharged pieces
Losing castling privileges unnecessarily
~ Attacked squares around the king. Por example, if all eight
squares around the king are attacked then it is easy to
determine that the opponent can checkmate too easily.
Let us be careful, as it is easy to overcharge the program with
unnecessary evaluation functions and having it playing weird
movements. Some of the most powerful programs like Fruit have an
evaluation function which is incredibly simple. Other programs, like
Rebel, prefer to do a detailed evaluation only when it doesn't detect a
significant difference between moves, for example, if it captures the
queen with advantage, then it doesn't have to do the detailed evaluation.
lt is estimated that a good evaluation function can increase the
strength of a chess program by up to 200 ELO points, without any need
to increment the level of depth analyzed.

14
The basics of chess programs

2.8 The search function


The search for the best move is the most important part of a chess
program. A computer is very good for analyzing millions of positions,
and guided with a good evaluation function, it can realize pectacular
moves.
John Von Neumann famously conceived the Minimax algorithm:
Starting with an initial position the program generates all possible
moves and for each of them will calculates all possible answers, and so
forth each position. Clearly this produces an explosion of combinations.
For example, at the start of a chess game there are 20 possible moves
and 20 possible answers of the opposing side, so this gives us 400
combinations, and this is only an analysis at 2-ply!
A typical position of a chess game admits 32 possible moves, so an
analysis to 6-ply depth will generate more than one billion
combinations. The code for the Minimax algorithm is something like
this:
/ at some place of the main. program... ii/
search_move(0, 6); / Search 6 levels of depth */
{do_the_best_move};

int search_rnove( int level, int depth)


l
int best___score, score, value;

generate_all_moves();
if({no possible moves]) {
if ({the king is in checkj)
return -20000; /ii* Checkmate, loses ii/
return O; / Stalernate, tiecl */
l
best_score = [-infinitej;
for ( [each possible rnove}) {
score = {points obtained by capture or positioningj;
if(depth > I) {
move_the_chessrnan();
{sWitch sides};
value = search_move(level +1, depth - 1);
(switch siclesj;
andoes_the_rnove();
score = score - value;
J
if (score > best_score) {
l:est_score = score;
if (level == O) [saves the rnove};

15
Toledo Nanochess: The commented source code

}
I
/

The above piece of code would take a scandalous amount of time to


calculate its move, because it checks all possible movements, even if it
is unnecessary! Note that it always searches for the maximum value
(score > best_score). When this happens, it is not necessary to continue
the search if it is losing, and this is the essence of the alpha-beta cut:

int search_move(int level, int depth, int 52, int 1952)


l
/* The othercode */
value = search__rnove(level + 1, depth - 1, score, best_score)
The othercorle */
tf (score > best_score) {
best__score = score;
zf(level == 0)
[saves the move]
else rf(s2 - best_score < bs2) / /* Alpha-Beta cut */
return best_score;
/
I
l
l

The vast majority of Alpha-Beta cut implementations use two


values, alpha and beta, but l've simplified the code for using only one
value, so it may be better understood. Toledo Nanochess uses this single
value to save characters in source code.
For example, if the computer captures a pawn and the enemy
captures the queen, then it is not necessary to continue further searching
because whatever the computer does, the enemy scores a better move,
and so does Alpha-Beta cut!
Like magic, the Alpha-Beta cut can reduce a typical tree of 6-ply to
only one hundred of thousands of combinations. Por efficiency's sake it
is vital to order the list of moves by score. For example, all captures
must be evaluated first. This makes Alpha-Beta cut faster.
Note that the score retumed for checkmate is a fixed value of
-20000 points. This means that as soon as it finds the checkmate the
score will be <<stabilized in this value and it will try to get a better
score with the result that the program will search to eat all possible
pieces while the checkmate lies in horizon. To avoid this, it is possible

16
The basics of chess programs

to add a value (by example, level * 500), and this will make it prefer
a fast checkmate.

2.9 Quiescence search


During the searches through the complete tree, a phenomenon known as
horizon effect can happen. Suppose that the queen is irremediably
lost or the king is about to be checkmated, the computer can see it in
its horizon of 6-ply depth but <<thinks>> that it can avoid it by pushing the
analysis further, giving up all its chessmen to prevent the capture or
checkmate from appearing inside the 6-ply depth horizon.
Other moves causing this effect are king on check (trying to escape
a checkmate with eternal checks or not seeing a capture after check) and
promotions (losing pieces trying to avoid the opponent's promotion).
To solve this problem, the quiescence search was developed. lt
consists of further plies analysis if the program detects a capture, check
or promotion in the last ply, this increases the complexity of the search
but corrects the playing lines of the chess program.

2.10 More advanced techniques


Although the Alpha-Beta algorithm provides an excellent acceleration
of the basic Minimax, more advanced techniques exist that can enhance
the analysis up to l0-ply, 12-ply or even more.
Some of them are:
lterative analysis. The program starts an analysis at a short
depth (for example, 4-ply) and preserves the best line of
game detected by the search. Afterwards it calculates if it
still has enough time (vital in the time control of chess
toumaments) and if it has time, increases the depth by one
ply and repeats the search following the current best line
first. A well-designed chess program on a fast computer can
reach 8 plies in the middle game and up to l0 or 12 plies at
the endgame.
~ Transpositions table. The program defines a table of
pseudorandom values for each side, piece and possible
position (so there are 2*6*64 different values) and
afterwards it adds them or does XOR operations for getting
a value called a hash key (this can be done in incremental
form to save a complete chessboard exploration). This hash

17
Toledo Nanochess: The commented source code

key is indexed in a table used to save the scores obtained


for each position. By reading them the program can know if
a position has been analyzed before, to prevent further
searches. This increases the maximum depth reached by the
chess program, especially in the endgame, where there are
millions of move paths that repeat the same position. This is
very useful to detect the three-move repetition rule of FIDE.
Null movement technique. The program doesn't move in its
turn and allows the enemy to play with reduced depth
(typically by two or three levels). This way it can determine
if the position has no future. Note that this technique can
introduce errors in the search, but there is the supposition
that the speed enhancement combined with the iterative
depth will correct it. Recently it has been discovered that it
is useful to pair it with a verification search to confirm a
bad position.
Futility cut. If the program has analyzed up to two levels
before the maximum depth, and detects that it is losing by
more than a queen, it interrupts the search, because it is
very improbable that it can win it again in the following
two plies. Sometimes this cutting can be done in the last
three plies with different margins.
Similarity cut. lf the moves in analysis are similar and it has
not obtained a great advantage in score, and it is not
approaching the enemy king, it cuts the moves.
Endgame tables. Using tables generated previously by a
specialized program, a chess program can determine if the
actual position is calculated as win, tie or lose, or retrieve
the best possible move. This is useful in games of computer
versus computer, but sometimes a computer is playing
against a human, and it can lose because the table says that
it loses, but if and only if the human plays correctly the
endgame, something which is very improbable.
Static Exchange Evaluation (SEE). While ordering the
capture moves, the program simulates all possible capture
sequences, to determine if there are wins or losses for a
particular movement. The better captures are placed at top
of the list, and this enhances the chances of choosing better
moves and reduces the tree size.
Chapter 3
Toledo Chess history

oledo Chess is the fortuitous result of a sequence of trivial events.


T If at some point someone had told me what was going to happen, l
would not have believed it.

3.1 The beginning


One of my earliest hobbies was playing chess. I learnt to play at age 8,
and one of my dreams was to program a computer to play against me. In
early 1989, I wrote my first chess program in Z80 machine code and I
was able to play four games, until it unfortunately failed and erased
itself from memory (probably because of an infinite recursion bug)
before I could print it, and since then it lives only in my memory.
But I had the itch within me to do something better, mostly for fun
and to prove myself. Since the early 1990s I wrote several chess
programs, each one had a different interface, such as plain text, 2-D and
pseudo 3-D. In the historical context of the Intemet still being an
experimental network in Mexico, I was astonished with the pseudo 3-D
view of Software Toolworks's ChessMaster 2000, and how could one
forget the funny fights of the chessmen in lnterplay's BattleChess.
ln 1996 I had access to the Intemet for the first time, and I started to
learn HTML, Javascript, CSS and other now common Web
technologies. By 1999 I had finally mastered the basics of C language,
so it was easy for me to do my first chess program in C, after years of
writing them in assembler.
l also appreciated Javascript because it was a complete language
that could do almost anything (well, without being able to save or read
files). ln the summer of 2003 I wrote a Javascript version of my chess
program just to probe the language, and slowly enhancing it. The
ultimate version in spring 2004 sized up at 90 KB of source code. It was
for my private use and was never released publicly.

19
Toledo Nanochess: The commented source code

I came about, circa 1995, to the International Obfuscated C Code


Contest (or IOCCC for short) after reading about it in the book Expert
C Programming by Peter van der Linden. lt is a famous contest
founded in 1984 by Landon Curt Noll, where the winners were the
programmers capable of doing the most obfuscated programs that could
do something useful, obfuscated in the sense that it could be written in a
clear and concise style for easy understanding but instead the
programmer would make it a riddle to employ every possible
misleading trick allowed by the C language, so a non-expert
programmer who would read the source code would get very confused
about its purpose and that was part of the fun.
At first it seemed to me like a curious way of wasting time, but little
by little l discovered the amazing effort that the participants put into
their contest entries, and also my own ignorance of the C language. I
kept learning more and more as l worked to develop a C compiler. I
have no doubt that the IOCCC was one of the things that helped me to
become better at C programming and discover that everything is
possible if you work hard enough.

3.2 Toledo Chess development


By a pretty day of 2005, I decided that I would work to win the IOCCC,
but I needed a program to compete. After thinking about it for some
time I recalled my Javascript chess program, and it appeared to be good
enough. 1
I began to do reductions on the source code. My objective was to do
a text mode chess program. It was obvious to me at the time that there
was no need for graphical interfaces since the IOCCC praised program
portability. The style of my text interface was simply a thing of putting
a recognizable chessboard in screen, where each piece was identified by
the initial of its name, uppercase for white pieces and lowercase for
black pieces, along with the algebraic coordinates so the user could
choose easily his/her move.
Although a previous contestant, Vem Paxson had already won the
IOCCC in 1992 with a chess program, it was not a <<full> chess
program. So I set out to establish a new standard for minichess
programs, one that would allow all legal chess moves (including en
passant, castling and underpromotions) and validate that the player's
moves were legal (an absolute requirement intended for novice chess
players). Another objective was that the computer should be able to play

20
Toledo Chess history

a reasonably good game, so a 5-ply search algorithm was my starting


point.
Here's another episode from my childhood: Around 1987 1 became
very profficient in BASIC programming and while I was learning chess,
sometimes I played the game with my neighbors. However, sometimes
they didn't have a chessboard at hand, so I would borr.ow the neighbor's
computer and write a two-player chess program in thirty minutes in
BASIC. Because of that, another feature included is the two-player
mode. 1
I started coding on January 29th 2005. By lunch time the next day, 1
had a very reduced version of the program, but it was still too big. This
is the 10th revision:

/* lo) Copyright 2005 scar Toledo Gutirrez */


#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
char *O="RDTACP .pcatdrXVWYZWVXiecca"acceiabcddcbaYM[M;"
"L=LDLHLXL\\LCLeLEHGYH[HFHOHQHZH\0D<:F<:X<:Z<:E"
":;N:;P:;Y:;OEPGP;Q=QDQHQXQ\\QCQEQEUFUGUUQUYUZU"
"[U\0\n A B C D E F G H\n";
int l[l49];
jmp_buf z;
int e=-l,f=l20,k,m,n,u,y,c,q,w,B,ox;
char i[78],*s;
int olint r){s=e?O+l02:O+40;
while(s+=2,*slifll[s]-79==l[r-80+*s])return 8;
s=78+O;while(c=r,q=*++s-79){do
if(w=(e^l[C+=qll+64,w==l[sl|w==2[s]}return 7;
while(ll[c]};s+=2;}return 0;}
#define I(q,s) if(r=l[h=ql,e?r>=0:1r|r<-ll{\
if(l[h]=j=l[c],l[o]=0,lolgll{i=j;if(i==l&h>89)i=l,t=6;\
else if(i==-2&h30)t=i,i=*7;else t=i+l,--i;\
while(++i<t){if(!k)if(u==c&y==h)B=O;else break;\
b=m,d=n,n=0,a=(jl=l?j!=-2?jl=6&jl=-7?O[h/l0+32]+O[h%10+33]-O[C/l0+32]-\
O[C%l0+33]:(m|=j==6?l:8,C-h==2)*5+(h-c==2)*5:(n=C-h)/8+(h<29?O[i+28]*99-\
950410)2(n=h-C)/8+(h>90?Oli+28l*99-9504:0)l+O[r+28]*99-9504;l[hl=i,m|=\
(c==2l|h==2l)*2|{c==28|h==28}*4|(C==9l|h;=9l)<<4|(c==98lh==98)<<5,n=n==\
20?h:0;e=~e;if(Ek)lOngjmp(z,l);if(f<k)l[f+++l6\
]=a,v{),a-=l[f--];e=~e,m=b,n=d;if(a>l[f]||f==l20&&a=\
=l[f]&&rand()>=RAND;MAX/2){llfl=a;if(f==l20){if(k)u=c,y=h;}slss \
if(l[f+l5]-a<l[f-1]){l[C]=j,l[h]=r,s;return;}}}}l[c]=j,l[h]=r,s;}
#define Hfzl *s++=z;
void vlvoid)
{
int c,p,r,j,i,h,t,a,b,d,g;
char *s;
B=l;
l[f]=-43333;
C=20;
while(c<99)iflll[++c]^e)==6)g=c;
while(c>2l){q=l[--ci^e;
iflq==l){
if(!l[p=e?c-l0:c+l0]){
I(p,0)if(e?c>80&ll[p-=l0 :c<39&!l[p+=l0])I(p,0)}
if(l[p=e?c-ll:c+9]){I }
else iflc-l==n){llnf= H [n]=-2^e);}
i(l[p=e?c-9:c+ll]) H
else iflc+l==n){l[nf= o-Q-4 UMN HH~1~ o..HQ-'C5-~'U-~ _W., l[n]=-2^e);}
}else if(q==2){

21
Toledo Nanochess: The commented source code
s=O+44;while(s+=2,s<O+62)I(c+80-*s,0)
lelse iflq==3lf
s=O+60;while(s+=2,p=c,s<O+70)do I(p-=*s-80,0)while(ll[p]);
}else if(q==4|*q==5){
s=q==4?O+68:O+60;while(s+=2,p=c,s<O+78)do Ilp-=*s-80,0)while(ll[p]);
lelse if(q==6){
s=O+60;while(s+=2,s<O+78)I(g=c-*s+80,0}
ifr{eaa1(ma24)_l1eaa1(ma3l)
&&ll[C-l]&&1l[C-2]&&ll[C-3]&&!O(C2)&&lO{-C-ll ){
l[c-1]=4^e,
l[C-4120;
I(o=c-2.(1lc~ll=0.ll-4l=4^ell;}
ifrreaazrmseolllaeasilmasl
&&ll[c+l]&&ll[c+2]&&lo(c)&&lo{c+l)){
l:c+l]=4^e,
lc+3l=0;
I(g:C+2,(l[C+l]=0,l[C+3]=4^e));}

g=C:
ll
if(l[f]==-43333)
lff]=k1=1?o(g)?-2000O+f*l0:O:tk--,o(g) ~._,.- \

l
int mainlvoid)
{
while(c<l49)l[c++]=-1;
s=O+14;
X=l+20;
while(++x<l+29)
*x=*s++-84,x[30]=O,x[20]=0,x[70]=~*x,x[40]=0,x[60]=-2,x[50]=0,x[l0]=1;
for(;s=i;){puts(O+141};
for(c=0;c<80;c++){
H(32)if(l(c%l0)}H(32)H(O[l[c+20]+7])
ifl(c+9)%l0>7){H(56-c/l0}H(32)if{c&l)puts(s=i);}
}puts(O+14l);
if(k=l,vll,!k){if(1lfll
puts(e?"Las negras ganan:"Las blancas ganan");
else puts(Ahogado};
exit(l};
l
putchar(e?62:42);
if(k=l23,e){
u=(getchar()&9 -44;
u+=(56-getchar )*l0;
y=(getchar{}&9 -44;
y+=(56-getohar )*10;
while(getchar( `-'I-U'I,-U'l ='\n');
._~-.1~_-f .-_;

}else{
vll;
o=u-20;
putchar(c%10+64);
putchar(56-C/10);
c=y-20;
putchar(c%l0+64);
putcharl-c/10);
printf("(%d),f);
putchar('\n');
}
if(lsetjmp(z)l{k=0;v();if(B)puts("Ilegal");}
l
l

lt uses the 10 >< 12 representation for the chessboard. Note that the
string 0 was still without cipher and the messages are in Spanish. You
can see also the o() function, in charge of verifying if the king is in
check and a small code structure used for keeping my mind sane while I
was debugging. The code for the text interface with the user is almost

22
Toledo Chess history

comprehensible. Note that the playing level is fixed at 5-ply, the


two-player mode doesn't exist and the user is able to promote only to
queen.
As C is a free-form language, it is possible to remove all comments
and spaces without complaints from the compiler, although of course
anybody looking at the source code will be taken aback. Another
powerful feature is the comma operator, which you can embed into any
expression. Only the last result will be used, so you can do something
like this:

calcalation = (operation, operation, 2 + 3)

And the star of the show is the trinary operator, an easy way of
writing an if statement, but using only two special characters (? and :).

calcitlation = comparison ? trae resttlt :false result

The trinary operator can be nested and the direction of comparison


can be reversed, so the false result can be in the center and the true
result at the end, and this makes it a very twisty and Vicious operator.
Properly used it can be very clear, but that is not the objective of an
obfuscated C code contest, is it?
I had a certain advantage over pure C programmers, which stemmed
from my experience with assembly code at machine level, BASIC and
also compiler design. Prom working in BASIC I acquired the ability to
pave expressions in a single statement to get the correct result (the
position evaluation function is the consequence) and from assembler I
gained the ability to view the code as a single sequence of instructions
intermixed with gotos. So I worked interchangeably with while, do
and for, and finally incorporated setjmp/longjmp for aborting the
search on a legal movement with the right move done (the other wayl).
A lot of people had difficulties understanding it without a background in
as sembler programming.
Also, I initially tried to integrate a legal move generator, which
would be sorted to give better efficiency, but I simply couldn't make it
fit in the program. It took me another three weeks to discover that it was
possible to play using pseudolegal moves (i.e. moves that leave the king
on check). These moves are rejected automatically when the adversary
<<eats>> the king, because it obtains a very high gain which is rejected by
the alpha-beta algorithm, cutting every possible search of the respective

23
Toledo Nanochess: The commented source code

subtree_ Today's most powerful chess programs use this very course of
action, because verifying for check is a very time-consuming operation.
Finally on the evening of February 18th 2005, I compiled the first
version that met the rules of the contest and I was very happy.

3.3 Architecture
The computer plays using a modified version of the widely-known
alpha-beta algorithm at a fixed depth selected through the number of
arguments given to the program. The same core is used to verify the
legality of user moves, for moving the pieces over the board, and for
detecting check over the king at castling time.

/* Basic architecture of Toledo Chess 1 it/

tnction workhorse()
if it is not the first time running then
change sides
for each square with_ own 's piece do
for each pseudolegal movement do
if it eats king then return with a high score
make movement
calculate score for movement (evaluation function)
if it has not reached maximum depth then
substract score of recursive call of workhorse
end if
if legal movement verification and valid then break HERE with longjrnp
unmake movement /ii not done sometimes see above if */
if the score is better then annotate the move
do alpha-beta cut
endfor
endfor
change sides
return best score
else
initialize board
while eternity do
show chessboard
show prompt
if it's computer 's turn then
call workhorse again with selected level
else
waitfor user movement
end if
validate movement ij' not executes longjmp then indicate illegal move
end while
end
endfunction

24
Toledo Chess history

The evaluation function is another critical point for the gameplay of


the computer. To provide a reasonable game I developed it by common
sense and it ended as follows:
- Pawns: One point for advanced square, adding extra points
for capturing toward center and adding promotion material.
- Kings: Points by castling only, to prevent movement
toward insecure positions_ (At some point it used center
scoring, so it ended up in the center awaiting an easy mate.)
- Other pieces: Points for going to center, substracting points
for piece importance (it prefers to move knight, bishop,
rook and queen in that order).
The algorithm also adds gain for capturing adversary pieces, and
substracts points for taking time on capturing them.

3.4 Final development


After working on it long enough, I did the final obfuscation in the
source code, and I also formatted the code as a knight, which was easy
to do as C is an almost free-form language; the preprocessor directives
didn't fit, so I drew the knight upside-down (turning the source code 180
degress). This almost made me exceed the IOCCC limit of 2047
non-space characters, because I had to divide the text strings, making
good use of the automatic string concatenation of ANSI C (which
wasn't available with K&R C), and adding some backslashes to the
ITIEIIH I1'l3.CI'O.

Some people actually cannot see the knight's figure on the source
code! Try it with your friends, it can serve for some class of mind
reading or Rorschach test. Also, because the program plays relatively
fast, some people feel compelled to play faster, and lose the game!
By February 28th, I had an almost definitive version. I checked for
the start of the contest and the entry period was from March to May.
In the end, the game core occupied slightly more than half of the
program, and the text visualization occupied the rest. By May 19th, I
did the last enhancements before submitting the program to the contest.
Here is the final source code:

25
#define F getchar())
#define H(z)*n++=z;
#include <setjmp.h>
Toledo Nanochess: The commented source code
#define v main(0,0,0
#define #define Z while(
F getchar()}
#define H(z)*n++=z; #define _ if(
#include <setjmp.h>
#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 V mainl0,0,0
#define #define I(H,n) { _ r=l[x=H],!r|(r^e)<-1){ _ j=u[l],-7==r|6==r\
Z while(
#define _ if(
){ n; e=~e; return 1e5-443*f; } u[l]=0,t=j+1,i=j-1;
#define old) (u[l]=0,l[dl=6^e,q=1e4>v,0),l[d]=0,u[l]=e^6,q)
_!i&89<\
#define I(H,n) { _ r=l[x=H],!r|(r^e)<~l}{ _ j=u[l],-7==r|6==r\ 63; \
x)i=j,t=6; _-1==t&30>x)t=j,i=-7; Z++i<t){ d =0; S&=
){ n; e=~e; return le5- ; } u[l]=0,t=j+1,i=j-1; _!i&89<x)i\
a=((j^e)!=1?6!=(j^e)?O[32+x/10]-O[u/10+32]-q:(S|=6!=j?8\
=j_t=6; _-1==ta30>x)c=j,i=-7; z++i<t){ b=s; d=0; Sa=63; \
:1,2==u-x)*9+9*(x-u==2):(d=1==j?x-u:u-x)/8+!(!((x-u)%\
a=((j^el!=l?6l=(j^e)?O[32+x/10]-O[u/l0+32]~q:(S|=6!=j?8\
10)|r)*99+(j==1?90<x:29>x)*(9*O[28+i]-288))+O[r+28\
:l,2==u-x)*9+9*{x-u==2):(d=l==j?x-u:u~x)/8+!(1((x-u)%\
10)Ir)*99+(j==l?90<x:29>xl*{9*O[28+i]-288))+O[r+28\
]*9-288+O[x%10+33]-f-O[33+u%10];
]*9~288+O[x%lO+33]-f-Ol33+u%l0]; x[l]=i; S|={2l=\x[l]=i; S|=(21=\
=u|21==x)*2+ru==2sl2s==x)*4+r91==ulx==91*1s+32\
=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+l\
,M,k):0; *(u==98|x==98)+(20==d)*64*x;
_ i==c&u==h&!f&N&a>-1e4&x==y)longjm\ a-=k>f?main(a,f+1\
p(z,l);,M,k):0; _ i==c&u==h&!f&N&a>-1e4&x==y)longjm\
S=b; _!N|f&&(a>M[[Ef&a==M&&1&rand()\
lll _!fl{ _ k){S=b;
p(z,1); c=i; _!N|f&&(a>M||!f&a==M&&1&rand()\
h=u: y=X: } l else _ \
L~a<N){ n; e=~e; u[l1=j; x[l]=r; return\
)){ _!f){
a; } M=: _ k){ c=i;
J J X[ll=r: h=u; H;y=x;
Ulll=j; 1 } } } else _ \
typedef int G; char J [ 78 ], O [ ]
=
L-a<N){ n; e=~e;
"HRoAMs#-smaqrhturzvrol|TsA("
u[l]=j; x[l]=r; return\
a; } M=a; } } x[l]=r; u[l]=j; n; } } "L\t####"
"s#{AsT|ba`gg`abs>GK[_`fFozxEvR
##B#A#@#G#F#E#D#K\t\3Zlv#tjm
typedef int G; char J [ 78 ], O "\3J#tjm\3Pwb []
"ofnbwf\3Joofdbo\3)&`&`.&`&` #+&g*\t; G y,
= "HRQAMS#-smaqrh[UTZYTU[|TBA("
c,h,e,S,*s,l[l49]; jmp_buf z ; G main(G L,G f,
G N,G k){"$#(ABT|ba`gg`ab8>GK[_`fFDZXEYR"
G u=99,p,q,r,j,i,x ,t, a, b,d,M=-le9 "L\t####"
; char *n; if( *1){ e=~e; Z u >2l){ q= l[--u]^e;
_1-- qll "##B#A#@#G#F#E#D#K\t\3Zlv#tjm"
_i1[p=e?u-1o=u+1o]}{ Ilp)_ e?u>80 s i1[p "\3J#tjm\3Pwb"
"ofnbwf\3Joofdbo\3)&`&`.&`&`"
=10]:u<39&!l[p+=10])I(Pi)} _ l[p=e?u-11;9+u] "#+&g*\t";
)I(p,) G y,
else _ u-1==S>>6){ l[u-1]=0; I(p,l[u-l]=-2^e); } _ l[
c,h,e,S,*s,l[149]; jmp_buf
p=e?u-9:ll+u])I{p,)else _ S>>6==1+u){ l[l+u]=0; I(p,l
z ; G main(G L,G f,
G N,G} k){
[1+u]=e^-2); G u=99,p,q,r,j,i,x
} _!~-q){ n=O+4l; Z++n<50+O)I(u+80-*n,,t,a,b=S,d,M=-1e9
)} _ 0<q&4>ql{ n=q==2?53+O:O+49; Z++n<O+(q!=l)*4+54
; char *n; if( *l){ e=~e; Z
lt p=u: de r(p~=*n-80.lZ!ptl1l; 3 l _ 4==ql{ n=49+O
u >21){ q= l[--u]^e;
_!-- q){ _!l[p=e?u-10:u+10]){
; Z++n<O+58)I(u-*n+80,)_ I(p,)_ e?u>80 & !l[p
e&1(S&24)|1e&!(S&3)&&k&&
ll[u-2]&ll[u-l]&!l[u-3]&&o(u)&o(u-1)){ l[u-l]= 4
-=10]:u<39&!l[p+=10])I(p,)} _ l[p=e?u-11:9+u] )I(p,)
^e; l[u-4]=0; Ilu-2,l[u-11:0; l[u-4]=e^4); } _
else _ u-1==S>>6){ l[u-1]=0; I(p,l[u-1]=-2^e); } _ l[
eairsaeoilies!(sa5)s&kaa11[u+1]s11[2+u]s&o(u)s
p=e?u-9:11+u])I(p,)else
o(l+u)){ l[u+l]=e^4; l[3+uI=0; _ S>>6==1+u){ I(u+2,l[1+u l[1+u]=0; I(p,l
]=0; l[u+3]=4^e); } } } e=~e; return M; }
[1+u]=e^-2); } } _!--q){2 n=O+41;
Z h<130){l[hl=-{2l>h|98<h >(h+lZ++n<50+O)I(u+80-*n,
)%
)} _O[h++]^=3;
10); 0<q&4>q){ } n=On=q==2?53+O:O+49;
+14; s=20+l; Z Z++n<O+(q!=1)*4+54
++s<29+l){ l0[s]=l; 70[sl=~ ( * s = *
){ p=u; do I(p-=*n-80,)Z!p[l]);
n++ -+84); 60 [ S] =-2; } Z
} } _ 4==q){ n=49+O
n=J){ DutS
;(58+O);
Z++n<O+58)I(u-*n+80,)_
u=l9; Z++u<100i{ H{32}_!( e&!(S&24)|!e&!(S&3)
u%l0 &&
))H(32)H(O[7+l[u]l)*l9+u)%lO>7){ H(58
!l[u-2]&!l[u-1]&!l[u-3]&&o(u)&&o(u-1)){
-u/1o)H(32)_ ua1)putsrn=J); } 3 puts
l[u-1]=4
^e; l[u-4]=0;
(O+58); _-1e4I(u-2,l[u-1]=0;
>v , l}){ e=~e; l[u-4]=e^4);
puts }_
(O+(v,0)> 1e4?e?90:82:96)); break
e&!(S&40)|!e&!(S&5)
; } _ 1<L&e) { d=v,2+L); printf
&&!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
(O+1l4,h%lO+64,58-h/lO,y%l0+64
]=0; .58 -y/l0,d); }} e1se{
l[u+3]=4^e); } } e=~e;putchar return M; }
(62 ) ; h= (95 & F-44; c=l[h
Z h<130){l[h]=-(21>h|98<h|2
+=(56-F *1ol; y=l95aF-44; y >(h+1 )%
10); O[h++]^=3; } n=O +14;
+=(56-F*l0; Z l0l=(u=(95 s=20+l; Z
&F)){ c=5; Z--c>l&&u!=c
++s<29+l){ 10]): 10[s]=1; 70[s]=~
=e^-7; } } _! ( *s=*
n++ -+84); 60 [ s] =-2; } Z n=J){ puts
setjmp(z)){ v+l,1);
putsl l06+
(58+O); u=19; Z++u<100){ O): l } H(32)_!(
Z u%10
))H(32)H(O[7+l[u]])_(9+u)%10>7){ 10!= H(58
F; }
-u/10)H(32)_ u&1)puts(n=J); } } puts
(O+58); _-1e4 >v , 1)){ e=~e; puts
I was totally (O+(v,0)> amazed when I saw my
1e4?e?90:82:96)); name as the Best Game winner
break
at the IOCCC ; } _website
1<L&e)in November
{ d=v,2+L); 7th, 2005.
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
26 +=(56-F *10]; y=(95&F-44; y
+=(56-F*10; Z 10!=(u=(95
&F)){ c=5; Z--c>1&&u!=c
Toledo Chess history

3.5 How to use it


For the contest I could not use my name, because all contestants are
anonymous, so every program is called prog, but the judges renamed
winning programs to the last name of the contestant, so my program
ended as toledo . c, and since then it has been known as Toledo Chess.
The chess program can work in one of two modes: two-player, or
one player (always white) against the machine. To get the first mode,
run the program without arguments:

toledo

The other mode is accesible by running the program with one


argument (5-ply analysis):

toledo a

Two arguments for 6-ply analysis:

toledo a b

Each successive argument will analyze one more ply. There is no


ply limit but in fact 6-ply is the maximum possible. The 7-ply setting is
simply too slow as some moves are fast but ocasionally a move can take
7 hours! Maybe in the future with a 20 Ghz computer this will not be a
problem.

3.6 Entering movements


When it is your tum, you can enter your move using chess coordinates
for each square. For example, when you enter D2D4 and press the Enter
key, the computer will check the legality of your move and will warn
you of any illegal moves. All legal chess moves are permitted.
One special case is when you are doing a promotion, you must enter
the move with an extra letter indicating the desired piece. The program
requires the piece letter, it will not select a queen by default, so don't be
surprised if it doesn't accept your move.
For example F7F8N (supposing you have a pawn on F7) will
promote it to a knight, substitute N for the desired piece (N/Q/R/B).

27
Toledo Nanochess: The commented source code

The computer will check for checkmate and stalemate, also after
each machine move it will show the score of the position, a value
relative to the current move (it is not absolute as in other chess
programs). A higher number is better for the computer, i.e. worst for
you. For example if it says 105, it is very probable that it can win a
pawn in the next movements. If it says approximately 99900, it is pretty
sure that it will win the game, if it says the opposite -99900, you are
pretty close to checkmating it.

3.7 After winning


With a more restful mind, I discovered a possible enhancement. The
original program locates a checkmate and substracts a small number so
it selects a short mate, but if there are any captures in sight, the gain
increases, and it continues to capture pieces if the checkmate is within
the horizon -very bad for the user- so I substracted the depth
multiplied by 443, so it prefers checkmate, even with a queen at hand.
I also solved a bug, which converted one pawn of the player to a
pawn of the computer in some cases. After two years only one person
noted this bug, the German programmer Valentin Hilbig.
One problem was not solved: lnternally the computer engine cannot
distinguish between checkmate and stalemate, so while it should be
enough to check if the gain is around -1e4+443 and retum 0, in some
games the computer gives stalemate instead of checkmate, a slight
advantage for the user. I solved this in Toledo Nanochess.
Nevertheless, a bug was present in the code, and Andreas from
Belgium detected it: A castled king thought it was in check, the original
code looked very correct (check o (u) ao (u- 1) in the source) but a bug
in the GCC 3.4.2 compiler caused the problem to emerge, resulting on a
lost expression.
I hadn't encountered this bug myself, because I developed the game
using my own homegrown C compiler. Because I was a little busy, I
simply changed st to es. At the end of 2006 I did a careful review and
the bug still existed in GCC 4.0.2.

; Test of Dec/26/2006

0
3

; GCC 3.4.2 compiling o(u)&&o(u-1 ) from toledo.c (right code)


; gcc toledo.c -S

28
Toledo Chess history

_?

movl $63, _S
movl -12(%ebp), %eax
tnovl $0, __l(,%eax,4)
movl -12(%ebp), %edx
movl _e, %eax
.rorl $6, %eax
movl %eax, _l(,%edx,4)
movl $0, l2(%esp)
movl $0, 8(%esp)
movl $0, 4(%esp)
movl $0, (%esp)
call _main d First call
pushl %eax
ldl (%esp)
leal 4( %eSP), %esp
ez LC2
ucompp
tstsw %ax
tesrb $69, %ah
Sl %al
movzbl %al, %ea.r
movl %eax, -20(%ebp)
movl -1 2( %ebp), %eax
movl $0, _l(,%eax,-4)
movl -I2(%ebp), %edx
rnovl _e, %ea.r
xo rl $6, %eax
movl %eax, _l(, %edx,4)
movl -48(%ebp), %eax
rnovl %eax, _S
cmpl $0, -20(%ebp)
je L-470 * Conditional jump of boolean AND
movl $63, _S
movl -l2(%ebp), %eax
movl $0, _l(,%eax,4)
movl -1 2( %ebp), %edx
rnovl _e, %eax
xorl $6, %eax
movl %eax, _l-4(,%edx,4)
movl $0, ]2(%esp)
movl $0, 8(%esp)
rnovl $0, 4(%esp)
movl $0, (%esp)
call _main 4-- Second call
pushl %eax
fildl ( %esp)
leal 4( %eSP), %esp
fzfzz cz
fucompp
nstsw %ax

29
Toledo Nanochess: The commented source code

testb $69, %ah


sete %al
movzjbl %al, %eax
movl %eax, -20(%ebp)
movl -l2(%ebp), %eax
movl $0, _l-4(,%eax,4)
movl -l2(%ebp), %edx
movl _e, %ea.r
xorl $6, %ea.r
movl %eax, _l(,%edx,4)
movl -48(%ebp), %eax
movl %eax, _S
cmpl $0, -20(%ebp)
je L47O (_- Conditional jump ofboolean AND

; GCC 3.4.2 compiling o(u)&o(u-1) from toledo.c (bad code)


; gcc toledo.c -S
I

movl $63, _S
movl -l2(%ebp), %eax
movl $0, _l(,%ea.r,-4)
m.ovl -1 2( %ebp), %edx
movl __e, %ea.r
xorl $6, %eax
movl %eax, _l(,%edx,-4)
movl $0, 12(%esp)
movl $0, 8(%esp)
movl $0, 4(%esp)
movl $0, (%esp)
call _main <-- First call
pushl %eax
ldl (%esp)
leal 4(%esp), %esp
dl LC2
tcompp
tstsw %a.r
testb $69, %ah
sete %al
rnovzbl %al, %eax
movl %eax, -20(%ebp) 4- Save temporal
movl -l2(%ebp), %eax
movl $0, __l(, %eax,4)
movl -1 2( %ebp), %edx
movl _e, %eax
xorl $6, %ea.r
movl %eax, _l(, %edx, 4)
movl -48(%ebp), %eax
movl %eax, _S
movl $63, _S
movl -l2(%ebp), %eax

30
Toledo Chess history

mov! $0, _!(,%eax,4)


mov! -12(%ebp), %edx
mov! _e, %<'-Box
xor! $6, %eax
mov! %eax, _!-4(,%e(!x,4)
mov! $0, ]2(%esp)
mov! $0, 8(%esp)
mov! $0, 4(%esp)
mov! $0, (%esp)
co!! _mair mi Second ca!!
push! %eax
`!d! (0/oesp)
!ea! 4(%esp), %esp
wz Lcz
fucompp
1ssw %ax
testb $69, %oh
sere %a!
movzb! %a!, %eax
mov! %eax, -20( %ebp) 4_Saves temporal ir! same place!
mov! -]2(%ebp), %eax
mov! $0, ___!-4(,%eox,4)
mov! -12(%bp), %ec!.x
mov! He, %eax
xor! $6, %eax
mov! %eax, _!(,%edx,4)
mov! -48(%ebp), %ec1x
mov! %eax, _S
mov! -20(%ebp), %eax 4--Load temporal
amd! -20(%ebp), %eax 4- AND with itself!
test! %eox, %eax
je L47O

1
2

; GCC 4. 0.2 compiling o(u)&o(uv-1) from Io!ec!o.c (bad code)


; gcc to!edo.c -S
2

mov! $63, _S
mov! -64(%ebp), %eax
mov! $0, _!(, %eax,-4)
mov! -64(%e!2P), %edx
mov! _e, %-fax
xor! $6, %eax
mov! %eax, _!(,%e(!x,4)
mov! $0, ]2(%-esp)
mov! $0, 8(%esp)
mov! $0, 4(%esp)
mov! $0, (%esp)
ca!! _main 1m F.irs cal!
push! %c-fax
fila!! (%esp)

31
Toledo Nanoohess: The commented source code

lea! 4(%esp), %esp


_ dz C2
ucompp
zsrsw %a.x
tesrb $69, %ah
sere %o!
movzb! %a!, %eac
mov! %eax, -56(%ebp) 4-" Save rempora!
mov! -64(%e!7p) %em
mov! $0, _!(, %eox 4)
mov! -64(%ebp) %e(!x
mov! _e, %eox
xor! $6, %eox
mov! %eax, __!( %ed1c,-4)
mov! -28(%ebp) reas
mov! %eax, _S
mov! $63, _S
mov! -64(%ebp) %eax
mov! $0, _!(,%ea.x,4)
mov! -64(%ebp) %ec!x
dee! %edx
mov ! _ %eax
::or! $6, %ea.x
mov
r ! %eax, _!( %edx,4)
mov! $0, I2(%esp)
mov $0, 8(%esp)
mov ! $0, 4(%esp)
mov ! $0, (%esp)
Ca!! _;1!1ar'z!4-ii Second Co!!
push! %eax
fila!! (%esp)
!ea! 4( %eSP!,~ %esp
wz Lcz
fueompp
nstsw %o_x
testb $69, %ah
sere %a!
movzb! %a!, %ecvc
mov! %eax, -56(%el:p) 4- Save temporal m same place'
mov! -64(%ebp) %ecu
dee! %eax
mov! $0, _!(, %ea>c,-4)
mov! -64(%e!9p) %edx
mov! _e, %eax
xor! $6, %eax
mov! %eax, _!( %edx 4)
mov! -28(%ebp) %eax
mov! %eax, _S
Cmp! $0, -56(%ebp) 4- Reads (doesntdo ANDO
je L522
Toledo Chess history

lt is surprising how a simple piece of source code can trigger hidden


bugs in C compilers. Fortunately this is not an important program, but
what happens when the failure occurs in a critical application? There is
space here for terror and speculation.
This third version of the chess program also includes an useful
enhancement for the two-player mode: The prompt character changes if
it is white or black's turn.
Leo Broukhis from the IOCCC was kind enough to publish the
corrected version of the chess program in the final tarball.
lt was surprising for me how many people enjoyed it, and it slowly
grew in popularity, travelling around the Internet. lt was cited as a point
of reference for artificial intelligence (see Bibliography), and in 2009
(almost four years after publication) l'm still receiving e-mail from
various locations around the world asking about how to compile it, and
occasionally encountering web pages that praise it from locations as far
away as China, Spain and Russia.
Of course, the major challenge is to decipher the source code, which
can be viewed as a sort of programmefs test. If you can decipher it then
you are on the path to becoming a very good prograrnmer. And this is
not so hard, it's a piece of cake compared with Toledo Nanochess.

3.8 Time to make it smaller


Around June 2006, it occured to me that my chess program was also the
world's smallest chess program. I did several searches on Google and
Altavista, but I didn't find anything, so in November I sent an e-mail to
the International Computer Games Association (ICGA) magazine and
my message was published in volume 29, number 4. I also posted it on
USENET groups comp.lang.c and to rec.games.chess.computer.
Several of the replies to this post made me blush, when I discovered
that, at some point in early 2006, H. G. Muller from Netherlands had
written a chess game called micro-Max, and it was smaller than mine
(Toledo). The main difference is that it had a rather bare interface.
I had to make Toledo the world's smallest chess program again, so I
began tikering with it on my free time, cutting messages and almost all
the interface, then I optimized the movement generator so it generated
all moves for all pieces in one step (if you check the source code, there
is an independent path for each piece). These enhancements were

33
Toledo Nanochess: The commented source code

foreseen for the IOCCC, but cautiously not included, because of the
very difficult debugging factor.
Also, within Toledo Chess there are three special cases that
consume a fair amount of space in the code:
' En passant: The program needs to keep track of the last
pawn that advanced two squares and compare it on capture
to clean the square.
' Castling: The program must make sure that the squares
between the king and rook are empty and not attacked, and
that the king is not attacked.
Promotion: When a pawn reaches the eighth file it can be
substituted for a knight, bishop, rook or queen. The
computer generates these moves so the player can play
them also.
After all reductions, l reached a size of l290 non-blank characters,
playing at the same level as the original Toledo chess. l pushed things a
bit further and as an experiment, l removed en passant, castling and
reduced promotion only to queen, reaching 898 non-blank characters,
which I found amazing!
At last, it was once again the world's smallest chess program, but in
a game versus micro-Max v1.6 (1433 characters), my program could
not win in any analysis level, although it analyzed more positions. So I
went back to the drawing board to do more research.
After doing all kinds of modifications without making any real
progress, an interesting idea crossed my mind. I modified Toledo to
show the calculated variant and allowed me to uncover the problem: Por
example, if the computer can capture a pawn with the queen, it didn't
perform the move if it meant losing the queen, but because the
exploration depth is fixed, it tries again to capture the pawn at the
deepest ply, and because the program doesn't consider the opponent`s
answer, it thinks that it's a good move. This is the known horizon effect.
My first solution was to add an extra ply analysis if a capture was
detected on maximum depth, but this only slightly reduced the
horizon-effect, and would make the program play defensively when it
appeared that the adversary would capture a valuable piece, because it
couldn't check if the menace was real.
The final solution was to add an extra parameter to the main
recursive function, containing the square from the last capture, only

34
Toledo Chess history

when it had exceeded the exploration depth. This way the chess
program could analyze all recapture sequences that exceeded the
exploration depth, without taking into account enemy captures on other
squares. This enormously reduced the horizon-effect, and in 7 ply-depth
exploration, it tied with micro-Max vl .6.
In the end Toledo chess reached a size of 1322 non-blank
characters, making it the world's smallest chess program. A
further-reduced version with queen-only promotion and no en passant
and castling, took up only 944 characters. While browsing around the
Internet, I discovered the existence of a chess program written in
Javascript chess that was less than SK in size. It looked to me like a
good challenge, so in an afternoon of early January 2007 I translated my
chess source code from C to Javascript. I drew some small GIF
graphics, and coded the program to generate a chessboard using HTML.
The final result landed around the 3K mark.
I was almost ready to put a new web site online with this new
source code, but I casually received news from the IOCCC that a new
contest had started in December 3lst, 2006. So why not to enter the
competition again?

3.9 Toledo Chess 2


I obviously could not participate again with a text-only chess program.
After reading the IOCCC guidelines, I noticed that the judges allowed
X/Window graphical programs. The X/Window system is something
like a Windows for UNIX and now it is very common on Linux and
other UNIX-like systems.
Fortunately I had some books on the subject, and it took me several
days to learn the basics: Creating windows, displaying bitmaps and
detecting mouse clicks. The names of X/Window system calls are
extremely large, so it was a real challenge to make everything to fit
within the contest limits.
The cherry on the sundae: I incorporated a translation layer that
made the program capable of being compiled under MS-Windows.
This new program won Most Portable Chess Set, and along with it I
submitted two extra entries, one of them was an Intel 8080 emulator (it
won Best of Show) and the other was a solver for the knight's tour (it
won Best Small Program).
This is the source code of the graphical chess game:

35
Toledo Nanochess: The commented source code
http://www.nanochess.org/chess2.html

#include <Xll/X1ib.h>
char *l=dbcefcbddabcddcba~WAB+ +BAW~ +-84HLSU?A6J57IKJT576,",
I' >>,> xl~w/? ,>>>,s m\l77>>\l77\l77 mm2>>> >uk>>> ,*f;y,u;
*F-= II

#define v for (i=0,b=0;b>5ll?b=0,i+=64:0,i<5l2;b+=64] A=i/64*l0+b/64+2l,XCopy\


Planeld r[I[A]+7+l4*(i+b>>6&l)+28*(A==Z)],w,C,0,0,64,64,b,i,l); XF1uSh(l;
#define _{a) *f++=a&*F?-lz%l4<7):U\252U\0DDDD[zl4*2|u&l],
#define Glpi p##Pixel(d,DefaultScreen(d))
#define Rial lla==O|p==a)*
#define P return y=~y,
#define a X(0,0,0,
define H while!
#define D ;if(

I[304],b,i,z;main(x,W) char**W; { Display *d =


XOpenDisplay(""); Window w = XCreateSimpleWindow
(d, DefaultRootWindow(d), 64,64,5l2,5l2,2,G(Black)
,G(B1ack)); XGCValues g; XButtonEvent e; int A,r
l56l, Z,* m = I , C ,Y; XSelectInput(d,w,32772);
XMapWindow( d, wl; g. foreground = Gtwhitel;
C=XCreateGC(d,w,4,&g); F+=48; H f=I,i=0,z<56){
H u=O,i++<8){ H _l0)_l 64)_(l6) (8)W(4) (2) ll
_(0)++u<8); F++; } F-= z%7-6?z%14<6?l6:0:8; r[
z++]=XCreateBitmapFromData{d,w,I,64,64); } srandl
time(z=u=o)); H 1[z1=-( z>9slz<21l(z+1%1o<2),
++z<l20}; H ++m<9+I) 80 [m]=-2,90[m]=~{20[m]=7&*
l++),30:m]=l; D l<x) Z: *W[l]-45; D 2<x){ a u,1
,Z): a u,0,l); z=0; } H lll XNextEvent(d,&e); D
e.type==12){ v } D e. type==4){ b=e.y/64*l0+e
.X/64+2l; D(b[I]^y)<-1) { Z=b; v} el5e{ i=(b<29
|b>90)&({z[I:^y)==-2}?- 6^y:z[I]; Y=y; a u,0,l);
z=0; V D l<x&&Y-yli U ,l,Z}; a u,0,l); } Z=0;
v } l } 1

X(w.,h,e,S,S)

{ int p,O= *l,t,d,o,C ,*g,E,n,*m =I,N=-le8,


A,L,r,x = 10,q; y=~y ; H--0>20)
{ o=I[p=O] D q=o^y,q> O){ q+={q< 2)*y,C=q
["5l#/+++], A=q["95+3/33"]; do { m=0,
r=I[p+=C[l ]-64] D tw lp==w&&q>l |C+2<A|!r)
{ d=abs(O- p) D g=q<2 &e>>6==p+{
y?x:-x)?I+ (e>>6):0, lr&(q>1ld% x<l|lg)|(r
^y)<~1){ n =O,t=q<2&( 89<p|30>p)
?n+=yl1,6^ y o+(y|1 D (r^y)<~s l P 1e7-sil
*h; H n-t) { O[I]=O,p [I]=n,m?*g
=*m,*m=0:g ?*g=0:0; E=e&63 R( 91)l6 R(28}
4 R(2l)2 R {98)32; L: (q>l?6-q?l
[p/x-1]-l[ O/X-1]-q+2 :(E[=y?8:l ,t1m)*9:(E
|=20-d?0: 64*p,n~o?( l[l5+n]-' '
)*9:d/8+!! g*99))+(l[ r+l5]-' ') *9+l[p%X]-
h-1[o%x1;i L-=S>h|s== h&L>49s1<S
?x(s>h?0 p ,L,h+1,E,N' ,sl 0 D lr z-oli-nlhl
p~b|S|L<~ le6))return u=E; O[I]=
o,p[I]=r,m ?*m=*g,*g= 0:g?*g=-2^ y:0 D Slh&&
(L>N|l1haN ==Laarand( )a4)){ N=L
D lh&&s} i =n,z=O,b=p D h&&c-L<S ) P L; } q
>5&d<2&C+6 <A&&(g=I+p ,r=I[p+=p-
O],m=p<O?g -3:g+2,l(e &(p<O?3:5) <<3*-y|*g|
r|mlp<O?l: -1])&&L>~ le6&&le6>a
63,l,O}}?d ++:(n+=y|1 l;} l } C +=q<2&C+3>
A&llY?O<8O :39<O)]lr) ; } H1r&q>
2&q<6||(p= O,++C<A)) ; } } P N+ le8?N:0; }

36
Toledo Chess history

The program is very easy to compile, as it was developed for


UNIX-class machines. The command line is:

cc to!edo.c -o to!edo -!X] I v

Notice the extra argument to indicate linking with Xll libraries.


These are the command-line options for the Xll version:

toledo Two-player mode (useful ifyou don 't have a board at hand)
toledo I Human white - Computer black, leve! I (fast)
toledo 2 Human white - Computer black, !eve! 2 ifmedium)
toledo 3 Human white - Computer black, !eve! 3 fvery slow)
toledo I b Human black - Computer white, leve! I (fast)
toledo 2 b Human black - Computer white, !eve! 2 medium)
toledo 3 b Human black - Computer white, !eve! 3 (very slow)

Upon executing the command, the chessboard appears immediately.


To play, simply click on the desired piece and then click on the target
square. The computer will check that your moves are legal, and all legal
chess moves are allowed, except minor promotions for human players.
The program plays a different game every time, using the C library's
random number generator.
In terms of size, the source code lies somewhere between my
original chess program and the more powerful Toledo Nanochess, with
a final executable of l5 Kb under MS-Windows. It's a really tiny chess
program.

Toledo Chess with


graphical interface
running in
Windows.

http://www.nanochess.org/img/captura3.gif
37
Chapter 4
Toledo Nanochess

T oledo Nanochess is the direct descendant of two of my winning


entries of the International Obfuscated C Code Contest. And some
code still bears some resemblance to its parents (check section 3.3 to see
the basic structure), especially the evaluation as a long expression.
The root of its development is Toledo Chess l, developed since
February 2005, it was based on a program originally written in 90
kilobytes of Javascript but never released, which was reduced and
rewritten to its simplest expression, with a text mode interface, in order
to fit the limits of the contest. A
Toledo Chess 2 is the <<sibling of Toledo Chess l. It was
developed in parallel beginning in 2006 from the same source code, to
reduce it enough to fit in a graphical interface.
At some point during development of Toledo Chess 2 I became
caught up in a really busy period with other work, so I had to document
the source code for future reference. The code underwent six revisions
before the first public version of Toledo Nanochess was released on
February 19th, 2009.
Because Toledo Nanochess was in a competition, I had three
objectives:
Make it the world's smallest chess program
- Make it capable of beating uMax vl .6
- Make it fast (this was a secondary priority)
The first objective had been met since late 2006, but the second
objective proved to be more difficult. I had to do a careful rewrite of the
evaluation function. I performed many tests to fine-tune it, but
sometimes it became too weak by giving high scores to some
inadequate evaluation terms. But finally I reached a point where I was
satisfied with the program's behavior. t

39
Toledo Nanochess: The commented source code

The third objective took me half of 2009, because it`s always easy to
do a slow program, but fortunately Toledo Nanochess now plays at a
reasonable speed.
To publish it and share it with the world, I had to set up a free web
site on nanochess . 110mb. com. It was announced on
ta1kchess.com, USENET comp.1ang.c and the ICGA magazine
Vol. 32, No. l.
In the first month after publication the site went online (February
l9th, 2009) it received approximately 3000 hits. Part of them were the
result of a mention on Slashdot.org by Stephen Sykes. This was a good
result for such a recent web site.
I had to remove all comments and spacing from the source code in
order to make it very small, and everybody was impressed with the first
program. So far there have been five releases, and some visitors have
tried to decipher them without much success.
The version of Toledo Nanochess presented below is the 40th
revision of the source code, first released on December llth, 2009
through my web site.
/-J<k1':-}cic:~k~)r:4r1:')r::'1-:!<-k9r1lr'lr'*:-.lc'"s'1*r*k"k9'k':7<'1r'k-k^k'k'k'Jr'kv\':rk1l:*:'';f:^kk'k99<f*r:''1R---:'^k'kz<'kk9:i<1\'1lrir'^'!r\

` Toledo Nanochess (c) Copyright 2009 Oscar Toledo G. All rights reserved
1257 non-blank characters. Evolution from my winning IOCCC 2005 entry. A
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://nanochess.ll0mb.com p
p o Remove these comments to get 1326 bytes source code (*NIX end-of~line)
\1E'if?c"k'k'k1-:'1k'kv|r'.?r-:lc-k'k*r'l:.'9fv1:1:i:1|r-Jrzir'ktlr''-.\:-k-kai:-.kk*air-il:-lr^*r^1lr'.k:k1'1*:'.-lfzk1"k:''k1lr1lr-.l<'k1':--'Jr-k:k~):1f1'rJrir:'"!:1:11''.4s'*v/f

char*l=vstvrtSuqqqqqqqqvvyvvvvvtl~2ltl
H vstsabcddeba .pknbrq PKNBRQ ?AsJ57rKJT57s,+-4eHLsU";
define F getchar()&z
#define V X(0,0,0,2lf
#define Z whilel
#define ;ifl
#define P return*-G,y^=8,
B,i,y,u b,I[4ll],*G=I,x=l0,z=l5,M=le4;Xlw,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=wl|s&&s>=h&&v 0,0)>M;do{_ o=I[
p=Oll{q=O&Z^y _ q<7){A=q--&2?8:4;C=O-9&z?q[& .$ "]:42;dO{r=I[p+=C[l]-64]_lw|p
==wl{o=q|p+a-s?0 I+s _1ra(q|A<3||g)||(r+1az^y>9aaq[A>2}{_ m=ltr-2a7))P s[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:O _ s)L
+=ll-q?l[p/x+5]-l[O/x+5]+l[p%X+6]*-~lq-l[O%x+6]+o/l6*8:1lm*9)+{q?0:l(I[p-1]^n}+
1(I[p+1]^n)+l[na7]*9-386+ltg*99+(A<2})+l(E^y^9)_ s>h|l1<sss==haaL>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+l,G[l],J=q|A>l?0:p,s)_l(hl|s-l[B
~O|i-n]p-b|L<-M))P y^=8,u=J;J=q-l|A<7||ml|ls|d)r|o<z||v 0,0)>M;O[I]=o;plI]=r;m?
*m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ S>l){_ h&&C-L<0)P L _lh)i=n,B=O,b=plN=L;}
n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-pl||I[p+=p-O]);}}}}Z1r&q>2]l(p=O,qlA>2lo>z&
lr&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N>-K+l924|d?N:0;}mainll{Z++B<l2l)*G
++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&3l;Z B=l9){Z B++<99)putchar(B%x?l[B[I]|l6]:x)_
x-{B=F)}{i=I[B+=tx-F}*x]&z;b=F;b+=lx-F)*x;Z x*(*G=F)}i=*G^8^Y;lelse v u,5);v u,
l);}}

40
Toledo Nanochess

The previous version became the most downloaded version of


Toledo Nanochess. Between the end of August and early September
2009, a mention on Reddit titled A guy with a very small chess
program generated more than fifty thousands hits to my website.
Obviously such obfuscated code is almost incomprehensible for
most prograrnrners, except those who like to solve riddles.
In section 4.3, you will find the program indented and commented
in terms of readable lines of source code. Afterwards you will find a
detailed in-depth explanation for every line or group of lines.
Some lines refer to other lines for a more complete view of the
operation of Toledo Nanochess.

4.1 Evaluation function


The evaluation function (lines ll0-127 of the source code) uses the
following square value table:
:_ :-:-:~;:-:-:-:-:-:-:-:-:-:-:-:-:-: -:-:-:-:-:- --af-:-:-:-:-:-1-:-:-:-:-:taa-:-:-:-:-:-:+>:-:-:-c-:- ' ;- -tv" =t;_t j___,-:gti-_-=j___
;tv>t>-t-ve-\'-2:-33231.3
~- -_ -_ _ _ _ _ _ _ _ _ _ _ .ff_f.._..;.;\_:_-.;;.y\3.-f.-.-_.
---_::::::___ :::-::: zttf/;::-:>./:-:'F:4->;_:f:+$F$;*.2
, .- fat
`3'c~ 3'-_ _ -:I 1 I 1.1;-.I I - - - I 1.1 I 1 i tf!fftitt
ff f _- fmtfiitfffft-<F
A
.,__,,,___,_________5__.___f
_' _;2'$2
.r_3, ~.. f f _- f
-_i-'1.g'_'_
-> 1'-1'~g2$`.-132-..g#'I33'3333'3_3_3%3'3:3_3:3_'3:3:3323.32-l3Rl:3:;:`!t;:'3? __;5t3:3;-`3t`t3t3:3:'3:3'3'3:`'3_-Fiji:::::- ::_::"` v_ ;;-:-:_J:;_;;:::;:
if : :` '_;.'1.''.2_`;'~j-'_:___:'::_' -_____':::_:';::;_3f;:'_,%%= " _'._-: __ _ %=_, -\'.-._i\'
-::::::: _:-::-:::-:-:::::_ 5

~:
ai.
f-;_ _;\- __m__r_F_._
:`:::-:::::_::"':_:`:3::-_-:`:3:-:3:3:`:`:':: _'__./:_:
iii*
"':-':3'" gat
2-,.
fm5.1:->$:_i."-C3$;:-:-;-::-::-:-:- 1'
_-.--_____" .-.---.-__
_. _ _ _ _____:-___-.`__....________.___.
_, _, " '
_:::-:-::-:-:::-:_.-5.!\'f$

f.,$_f_.m _ ff.-.m_-fm;
_-;-__f,:_*-:$2__ '3:`'-'_32Z3:3_3:3:3:3'3:3_33'::-_3:3333':3_3:3'3:"`3:3:3.3:3.]-1-:33;3i`f3:::3:3t3Fc3:3l3:3:3:3c:l3f3i33:~'3:3_':`":_`:~::` "_:-:::::::::::^-__ f;3:1 "
12:" `-;;:__;:_' __:_:_';:;'_ : :_:;:;'_:_:_: :;:;: :_:-:_:_:_: : _ _ f_;-_
',..-..-f.-_-...___ _ _ .v_ _-E?33ef-
:ev
___-_-_--_.-.-.-_-.--.-.-.-_-.=-.-.--.-.w.--_-_-:.-.-.- -_
______,____ _ ,__
'
'- --'21'-::___:::"': '-$5::-is:-:s:-?:5:'a-;-1-Pfr-#5:
_ _ _ _ ---_-.-.-J.-:_-u -4.-
L _ -I-
- .-_-- Evaluation of chessboard for
-* '*-- ".-\ -"`\ >`-`::::-:-:::::::::::::------_-_3--- " `t`_""'?"`_`3""'3 __'~----'-------1-1:1;-1;'tttttvttt>:tttttttttttvttnr2-1;_I_f_=-I-1;;_f_f;=_=;=-II;1.1;I;-rI;f=I='""""""""""'*"-
_ _ _ ' ' ' '
ai fi'
ii H-_-.
_-._
-.W

- .- tt.-'E-:
;'_xrWyy
!^}%42'F:3::`:-:-:3:-::`:::::-:':':33:-:3_33'3333_3:lfiii fiiili3:333333^333:3:3_33:33.3-_33:33--:--'--g:-:~F:-i+F:t-:-2+:-:-:-:-2+:-:-2:n2.___.._
?_$-__;__:5:52?5:;_'_'::____;-:tg:-:_:5:_:_:_:_::;-_-`.3.f:.;_.;_.;'P,_;_;_-;:" :-:-::::-:-:-:-'-::-::-::-::-:::::-:-:-:-:._~:;_:_3:;\:5'g:3:3.5;;g:-'-'--.--1-
13 '5-_\_.~:3'3:::3:3:3;:-:::' ":33'3:.3:333_3'3'3_3 1 .uff _
5 - -_-:::-:-:::-:-:-:-: vw _ ffxf __ _ ..
_
-_ M-_ -=_f-_
*_-su-.H _
_ __ Iiirii321215215$1:l
-- .- -_-_-_-_:'.'.'.-_-_r_-_-.f_-
_
k1IEI=I:i
_-_~_-_-.- -_-_-: .-.-.-
-.-_-_-.-_-_;_-_-_-f_~_-_-_-=_-kg
`ftrt;`*-'reif-*-*:tt1'fiatrrrr_;`;;;;1.;.; .;;';;='; ;.;;`; .; ;.;E;;'el-._tera"F>=?esft=_15.2'E'Ei i5:5;======E;f;;_.. '_%-i . . __
-;-:<-_"-:-r-:-:-:--:+{-:-:+:-F;:-:-3:-2:-:-:-_
__,_,______ _ __ piece positioning (not
al applied to king)
'_..' _ N._ _; __.' ,__,3:33:3:33.33'333` _::-:`:-::::::':3`3Ff -'-13%? ` _-?" 7'.3$'3W3f3f`f:f'`f:::3:_::`-3f:f`f`i3f-3' f_,
.. __,-2:.-,;.-.-___?
J -
_. -_
iii'/iiiitillif-1 ".. 'iii- i-i<f3'33'3333333333333;::'::3"':'-:_`3"
_;_\g__g_>_ :\fg______:\;' _sq\:-21
;_;_-_;__1_-,5;_-_;,;;.;_;3;_;;_;;-_-
__ __ _
-_ *M2-; _ '-
me
_- \`'5'l'-:`;`:`::":`;:`:::::;:_'_:;_::`::;:::::
_ _ _
_;:5ft,_t,_'":_3"5f. _35*;';-___;
' _' -'.;;_j;i@j__- 1 _. __ _
__-;-= ,.-T
__--- '-:-
-:
-
gl
~: _ __ ""3:i3:3'3:33:l3:3:$`55;3:":3'>3F$:3i;3:
:-:-:_:-:;:::::_::_::::-::::;:-:::;:_::_:-:l`q;F:-' _-
2>
:E-,'-- $;f-Mi- li:-.'3>'$J:i3 ;t3:;;3s_`f`<'
_ -
:3-' \.-1 ;`__` \n~_____
'_'- '_;_- '__;__-_ _-_-`____''3'".-/f~v--l-
---_-~;_I;._.;;;_3;.W;_},g___';__?:'_-'._-
.". -I '".. w-''~:-z'.''.\'
-_ ` +:--
_'-';._: -_ :';:_'__'-lt'
- -
,____ _____ _ _,_ ___ ____ - -- -- -- _ _ _ . . . _ -_?, ___-_.. ., .-. ___ '.1.'_
'_ _ _ _ _.-__
_ _ _ _ _ _ _ _ _ _ _.-._ _ _ _ - _ _ _-:.'
- __'__"_f:_:___;:;_;;___:_;:_;_:__-:_._j{;:_:';_:

- ' --tv:-it-',=.-.-:ft-:-'$'o-'-_-_-.cc---_
1-_ `_f-_-fE_i-`I_._:-__-_ijI_jnsuj=t=i1rEtgr-t=:;'-giig-:-- ' _ _ ___; ,_,- __ `_.-___ -::-::-'--
: _; -f
_; 'J
*at
53- 1$33:3:`:3:3.3:3:_:3:::3:3:f:f;3:3:33:3:;::3:`:3::3::-:ff,-:<~.-:-:-2-ri:-*t-2-m+_e:-az_-t;-:
,_,,_,_,,_______,__ _,,___,..____._
: :-2 : :-:-: : : :- :- :- 1- '-'':-:':-:-_-:-";;;:;;1::1-:::;:;igf::}:;:<1

: -$?$f=%tt="==1 ==='=-
iv
2:;-2-5-; ==:;&-; =i>ir
r' _q:_
_':,_ 2 e' /w: ` _".' " 2 :-: :`:':3:`: 1': :3:':3 3'3_ '3_3'-_;.-_-_-___;_;__;__-_;._._;_-.;__;_
_<:=*tt\<._2-;; .;.;:;:; 2
3:3'3'-':3_3 ` ` `:3 :3 _- ;-2-2-Z-_'-:-2-:-:-1-;_;-1-1.3'-'-:--;-::-r-:+2-2-:;:-:
;-__<;2;__-_-;_;_-_-
_._,_-_;-*_-1---'-'-'-:-_-:--- '-: _ _ _-:`:'
' 1 :-: -1 1 ::-: 1 :-:-:"f:-';';'::f.-:~:-_'c--:f _;:c-::-t-:_-:-:-,~_~:-
I'
- - - _-_ -.*-+2:-I->.;-Z-2::-::"::-_:' '12_":':.::-.-3w;+{H;_}- ;')_.fl'}'l=' 5-'-' I: ;`s._ - f._.-. ';:'t_Q'
-P-!\.r' ' 4.:/"tt -L-'_ .t -l., tu _- f;,l:-:-::-:-:-:-:-'-:-:- " _-::::-:-:-:::::-:\'.f'.-:\<_: _; :-_c:1'-___,_' m__;_5_;-5::_:_:__;:;::_:-:: :-:`:: -' `:3:3:3:3:3:-i37:3t3

-'
""""
;':;::;;^-:-'::^:`:-;;""-':"
'-
__
'
-tk " ':_-_:::-:-:-:-:-_:_;-:-____:::::_:__:: _-
:3: : :-:`:3:' : :`:-: : :`:" : ' : 1"":
.v f - ._ _ : : :`: :
'P'-' -' -13: -'l''-1^tl'"?--------:--'--'-_--_---:::::::::::::-"1---':-' $5!"$"'-$ ::-:-::::::::-:::::::::-_:::::::-::-:-`~ _'~"tR~: -'_-_-_l' ":-:-zi-_ -ic
_
-_
_
t-
-'5
'"52-
_ _ __ .,.
-'f

3 3 ' 3 _3' 3 3
_ _ _ _ __ . 3 3' 3' 3 _3 3 3' 3 3
,_ __3
3.32.'-;;;$-tf'.f_:-t;'f_:-1;c;1''f_E:::-:-:-::-::--::
, ___

Lt-I2-:c-_?.-2-Ita-fiat-:lt-:f-r->:-:a-:
_________
_
-$1.-l.;.\-_;:;;_~g__,;_:__; __;:;';'_____;:;: :- :_ 2;: :-:
til fl!35::;!H;I:Ic::l:I'l'I:-2-22: I 15:13:
J':":$`I.
c-_- -
-.tt-__<-_-_e-_=-f_:~_-__-_-f__-::_-tu
-_ f _.
-21:-:3:'
:Z:Z1:_:{H-:rr-:Ha
. , _./
_3:3:-:3:3:3r3:' _3.-':3:t3:3
: : : :-:-2:-:-1-1-:-192:-7:-:<-:-.g-1-14:-1;:5-:<-:
_
J , _--_-H-_-_~_-_-fl-.
Evaluacin del tablero
3 3 3 3.3 3 3.3 3 3 3 3 3 3.3.3 3:`:-: :`: : _ : : : : :`_ : : 2 : : :-2 : : : : 1 : :-2 : :`_ 2 :`:-: : : : 1 f
.' ','.'.'".'.'.\.".'.'.'.'.'.".'.'.L' :J J
_ _ _ _ _ _ _ _ _ _ _-- _ _ _ __-_-_-_-_-;_t-_-_-_==-_-_->_=;-_-_-_-
i_'l_:-._ lt-:E313:-:title-iifttt;3i:3:_3 3 3.3 3.3 3.3 3 3 3 3 3'3 3.3 3: : : 1 :':3:3: : :3: :':-52-23:3:3#513S?-F:323$!3F2;3F$$3}': : : :: : 2 : :`: : : :3: : : :`:': :'13: : : : : : :3:31'_-13!3t_;:};313:23:-ffi-:3:l}:2:3$:3:3:

-- _----: _-_- 1' '
$_3t:.__;*~: _>.;l1'._:-!5;i_'f_t_'.;:;_;_;_;_;_;;;;;- ::_:_:_:;:;:::_:;:_:;gg,'J:-f:;:gI;:: "-'.;I~b_2;'
i-2-lt{--Zff-:t-1-21 2*.-l-'Z-`l5't;'f-1;:-:-:-_---'-'-:--:
f-:-: _-_f-'f`~c-
_,__ :`_'
'

._ 1:_:_:__:_:::_:;'_::' _ '-:-::_:;::::;::::_:5-:1;$1!l-2-l -*Z-'-2-'Fl2-lg-:-_-:_-:-:-_-_-'


-':--:-:-:-:-:-:-:-:-_-if-'it-:ri-Ffz r _-:$2-7J".-;`:}"_-::::-:-:^-:-:-'-:_- :-:-:-::-::::-:-:-547.2-:
-_
I

-:'.-:'-;:2-:-:--:-_-:--:-'-:-:-:-:-:-::-'-:-'-
_ -_--i.-. :_-_-_ -.-.-.-_-.- ;.+.-._- _- _-_-,-Y

'-}t'2-:-;--.'-&'_-:-:-: . _
-_'-:-:-:-:-:-:f_-:-:-:2':.._:::::::':- __;':-::':
_ de ajedrez para la posicin
_-or _~~_--f _-fm _r-_-,c--- _:->:-if* f_-:-:_1_\_-'-1-:-_-:-:-:-:::-:-:-;-:-_ :-:-_c-_-:-- :-_ .. _-_:-;-:-:-:- -:_-'_-:-
2-:Tf-7-'"', ' __ '-- *-"'-' -I r - '-:-'-I-J-:-x-:-:-lt-'__.f:-I-:-'-x+:-'<J-- -
1-:--:-:-:-xae:-:E-:-are-:-:!:-:-:-:et-:-:t-:--
"^-:-:-:-:-:=-:-:-:~:-'-"-=:-7-""^'
1:'/-i-:-I-*_-:-:-:-S-'Z-/*':-'-: ^'
:-:-:`:: _
--
' " '
-1-
'-'::::__':
' ""'r-:-:~:~;-:-'-;-_\-.-:-;-;-:{-:-;-'-':-5;-:-:_:-::--:-:-'-_:-'-;-.--'-:-'-;-_-:-:-:-:-:

':`:3f3:3::3'3:3F:3:3:3:3:3:35_3:3:313:3:3$;3:3_33333
'- ,
I J _,

`^ "
fl \_ `
\ \ ,
I, :RI
:::-:-:-.-:-:-=;-:-:-:-:-_=.::-:-.-:-_:--:-:-:'-:-:::::::
' " ___::::1:--:-:-:-:->:-:f"T"~'2-:-:+2:-2-2+'-:_-:::___-:::::-:::-::::::___
'::::':-::::;:_:
_-_;-.-.-_'-_=-_
_3_33`33'3:3:3:3:t35:3atl33:3:3:323:3:3t*2
:--:-:-:-:-::-223:-:-:-_-_-_
' _.
I

, S JL
\-::-:-:-::-:-:-_-;:'-:
3' " ` 3:3:3:3'1:3:3!323:3'J :$72323:-t~.3`:3:i

J
` ' -'3:3:3$:3:!_'3:f:3:3: 3'_:3:3:3:: ff-E313
J

' " ' ' ' ' ' ' ' ' ' ' ' ' ' ' :-:-:-'-:' ' '-_-_-_-F-:J:-:3:-:+2:-:-'-' :-3:-1-':-n _
W.-.\.....
,
-.. ---_;.-...-.11
af-r '-=' 1
:;_ttmi-?::3:%2r:.`:-F
_
.

;`-`-`"'-*It-3'3-ifF-1-zm;-_-rif
{'__.;.__ (_. __:_.-._, ._ _
de las piezas de ajedrez
__ _ _-111;:-:::-:;`::-:-:-:-:-::t:-:-:a:<:-g:-:-;s :: :_1:-::::: :_:f-:-:;~;-;:-:-:;:-:- gg:-:-:;"-gg::-:-:-::;~_- 3333__:33"""3_3_3' f-_<;1:1:=:fs-:rrrt;1;-;1L1:1:1si?ft'-T - 1 1:. 1': 21"' I I - *3-'` ` .s>_u.t-tr-;.:s<;-\_t:
" "":+_f:-_-_-:-_-.-:_-:-:-:-:-:-=;'-:-:'a-:-:-:-_-:-:-:a--- -
___::::':-:":": ::::_:'::-:::::i:3:3:3:23$:3:3:3tf$'t3$:;33 _3_33'33'333_'3 :3333-_l:'33_l3;3::%" `_"5f'
_ --'----------_t_-:'_rt<tcf__f f _'-a \'::::::-:-::-:-:'-: ___:::-::::::::-:\:- ' -
:-;:f; ;==-'._:" if-f-; ;-2a'~1_'
_'
'-'--t-:-_-Mt-_-'-Fai'-^-_l?x-_-:-:--::'t-:_"__ _
U
-_-.-_-:.s\\-.-r.-_'_~.-_-,_/.~. :.-.-.-:!\1.v.-I-

--:-'------'-'-'-'-tf-:t-?-:rra-f-1
itissrts-1;-5;-5;-=-=-f;f' "':=:=-jai-f^;:=2.2g;sE;, 'ti ^'ti;f'f*ri;: <><f%=;5f;=2=2;-%=:-;.=- -:if_:i=32:.:ia:;:;;:;:ta=;2=r-tau-'-'
--
:-:-:-:-:<-:-:+:-s.=:-r-'-'-aa:-3:-:-:-:_:-:-:-:_:______::_:--_-_-- _- -. -- -s :3:-:-:+:-:-::3:+`-' ' '=3:<?_-31:-:=_ -F:-:+:;
:-::::::-:_-::::____.__ __ (no aplicado al rey)
-3'3'-'-'33`-
3 -3-3.3
_ ___-:3&`:`c3t3:i31--I_"3_333_`:33"`^-:-
3:333gil-t'{':I;__3Zi:b`:Z''+3'-3:" -I_
---fI_------__-1'I.-Iztittttlt-:it $,ftf:~$f$'3:1*:1.-$`
.=f.==-='>1= -=-=-1:=='=;iit?hi'_=i+f-iit?t'*<sr2i;:':-- : .: =.f
_ _ _ __ _ v,".-,-, .,,- ,- $3- _,.- _
:;.l 15:-,v_,iay-.;.;-.-.j.'l.j.'. _ 'l.;';;_-_'_'_;`;;;-;'_
-l`_.__-fi'
--
;:__;: -2-::;:_=
.ft-`_1'3?_t3::5:3
_: $;'$1:::::3:;.;_____ '
"<:-:3::;n'~:;-'_-'-'.-=:_3''3:
___3.__ ___.__-_:~_\_J13
I: `:_ _3'3_3-^-_::----I;-__,/13% `,-
'

'S-"l.*'u);g.j;'J_^"a._*_.;*$.;.v,__.____-___'__._ .:__._:`: . -pag'-'-='-\'ttv a;-~:-n~1;Q - " '


btilgl-l:-;`1}$i{2:'_;\;_'.'f_:::_:-::_:::::;:::-' -1.1. - --:'.i_*%;-'l;:-'t"i'1f~'**'?.'l-'_l:-:t;':-II--- - -- -_
.'fq..' 1 ii? 3,2'-19'
______::':::_: :_'_':::_:-:-:__:': .;>_ ~ '12 _- /_-"1_Q;f-'-- : _;'-__'-_;-;; -'---_;__;_ 2j_5;.-y$<;_'t5 *;.;;-j-'_:::::____::_`_:`:_::`:`::::':::"`:::_::`?;g1- _'-'f'- ._^' wa;-:,"$:::::':`::`:-:'::333:333'33_333_3333'3-_-:1:-f:-:l-:-:'-1-vt-:- _:cp;-1-1-t]of.3:3
ttittiliitiifiiiiti
" "----------^31l_iii3.
" `
::::::::::::::::::::::::::::::211;:-~:-:_-g:-:arg-:iw_t;_t_c,-'-t-:;_
_t}3i<'r j_t;>* *5-_. *eg :' :::::':::::::::::::::::::::,:;q .^;:;$5{1$;,5g5.:r};::.j
aa
fizlif"*3-_3:;3:3'3:3:-3:33.___ __3'-:3:-:3:3 ::3:3i"'*"'"'^`7""-" -'<'i-'+'-'*'-
____i'_"='=1;-'-';:f;:11125.;; `-;';'i3^t -'_-fr _ '$2 ati-':'=:::=:' 3f*f-=--f:f:ff fuf _r:-turns-Is;:rs:<-Ir;ts
i%3iE5Ii<=`;'r% 'rii:fI<-1=I_?E
' C
9

:-:-:-n:-`:-rn-2';-;-f~.-w.-.-m-.f..-f.-rr/fr.f/-.-.
act-
`
lr-f-Ir~f-
-:-:`:`:-:': :`: : : : :3 3 3 3 3 3 3 3.3 3 3.3 3 3 3'3_3'3:-:-;'f-'):c!- -:tf -:fs-1-:-_xR'-:3'cf-:3
___f_ __

_.,-_-1; ;_-'_..tt __ .:-.'- _\-:-_*_::_ _:_:- _' _: _-2.; ._ __ _-'gt-qe. :lc _ _t


._~.-,_ -"?'_\. 3. 3_3_3_3_3'3:3_3_` `_3_-:-'3:3_ _ '-'3 ':`:3 ""l.i:-'1`E$'-I-:`:3:`:"3_3:3:-_ :3:-:`_3: :-:-: : :-:3:`:'_ '-:-:3: : :` : :'::' 1: _ ::::: : ::::::: : ::::: : :__j_-;-1_;;t:c;:;2323;.-:;:35t;;:_-;;5;
3:3_3_3_3
2'ft lrf-5:;-;:z_;:;-5:;5:52' ---ff-5-si-25.2-2;-;:'-:->,'c-'ftf_<-__t
;:(_,;?===fff.,
_f3*-' -'-:I:-:-:-tt.-;f--:ff
-->r=>-r=`=,>r*- -:-:-:-:-::-;-:-:-::-:'
31 EI;-jlE11E -5213 E-E-Z-I`1fE-` Ef-f;--EEIEEIEIEIIF "II1E1I~:fP1-.2:2. _ _ - _ ; ,: ; _ -_- ; _ _ 1--;;---:,
_-:-::::'-'-_:_: :-:-J'-;~;-':-232-5;:-:-'
. -_:._.,.._.' -3 -1; -7-' ,-_- \.- -
_
-_.;_;_;.;__-__;--_- =-_-__;_,__;_;__;_;';--;;;_;_;;;;--;_-- __; ___;_;_;_-__;_;_;__;_;___ __,;.___.;_-;_;_-_.;
fA J \ ;.;_;_-_;_;_5_;__3_;_; :::_'_::::-'::____ _:_:_';. :':::::_-;r':_$:-_ fl? :::-:'-'- '
-ff.-_-.-_-_-.:_
`\ s .-..-.-.-.-
.-4 .-f _-_-_-._ . n f
tu f"'ff" f-IE 7 'f!51:2E51Eiii?iffiilfii"""
, J . J - `"f'-'--"i
_ i" ` _ _
Kar'
-'J' (H -'W-'ft tf;--:fl--5 ^-5-f-3;:-'_; .ff ''-tr;-.-WI.-\ ' _' 1_ srwrff tt s fssitt _________________ --_-;-- _-_ ;_-_$frl_~
__ _ _ .-;%_-,._.?-$551-_.?l -_-_f-__- _-.;_;:;';;';;;';-:;:1-';';:;
-la-:-__t:=._ :-:-:::_:'_':_-'_-__
_._______________:_____________:
_3.'--------`_t_f3'3:E"`_ -'f1'l " `;':::-':_-:_-1.1:I-_-:-::_1:_f_-__'f-_ 23:- >_\:-:-'}:~':-"":':- :3""'_- _ :-:":-;-:f:::' -::-:';:-:_::::::'l"~':`ll'*:.ll' -ilmlff z:-2-::::::-::`::333_3333_33333333_33'3
:-=--. '=": :=- = _-rr-ftttirittr-igittiitiii:-=-
'-:-="J' 5!-5'-:-*~ :3'm"-"t-:-"1_;;' 2::_---I':':-
- - -- -_ ___ini:t=;1;=;=ff&;=liri;=;i;
_: --_..__"'-'.-..-tf-gta-'c-:-:t-:f5rt"-'e vr-14'-'ac
._-- .-- _ -___...-... ._ .S2
.'2 J.-"*' _ _.- 4
te-=a?_ft t__a;ite;=es;:; ; f=&t
_____.__.______.._"."' ' . 5
_tttt=:==_-1;'f,t'-;-1t\_~=:F.=;fsx:_=t
2.-.5252.51-^.2; ;.-5-5;=2__;';1a
' ' ' ' '
VW ._;.;;~- -_-';_:.--_ WE
_- .f-,f
' '. :-;!!'$.-f:.-_{{''.j'.-'t..-_-----:
._ __ -_'--.
. _. _
__- - _ 3- _._,:_,:,_-,C__,$_;;_?'
- -_-2;,_'w-;-.-_-<'->.&{zz"'5:C'.'=a
\.-\_,.;:_~$;_-i.-,-5-_
_
_'_I;:;:_:______' ___..
_:_::;:'_:;._-:_:___:;V_F2.
____________):(:_>_ _ _,
.~. .ff fIZII_I_1_Z;IZIII-`-- I;`;__1_I;_;;I;`u.'.\;.._';'-- _".-..._~..;< ;,..
_/_, '*' ;'f_'/_::~::;:-:_::_::_:- _ ___________;______________\_`___ _;_:__________________
-_
-_-::__:::- : "' -
`b'`."$l)` r
'.' *' .P,t_-:-:-_-_-:-:-:-_-_-__
'
-- ' J-.Sl-' V - -3+
'u_u T;--'-vil.
:::-:'_-___ _-:-:-:-_-::-:-:-;-_-:-:-
532:".:`_::-::::3:_:::3::`::"'32-:3:':3_`::%z':}i!'3ir:.-_
' 'ff'if' '-':-:-:.-_- :-_:_-:-'-:-:-
` '-:;:::`:`_-:3:3:3:3:`:::--_---3_'3'33'333'33' ':-:+:<,_\:
_<<1;1;2s_<_t:f:1rf-&f- I-;I.<:I':1;=-Im:
f :_ff _ f-
't
e
'3;3;$.5?'%3.__3i5Z :3;3:3`_'3'3:_:3:3'3_':3'333'33 333'3-33_'_'i?4;.
v to 't ~ tt' ' 1'::"1:-:_:_-:::::-___:::v:-:-:-;:-:-2_ " f'` ; if."; -
1 :`:':_3:_:'::-:_^:_::::-::`:3:3:':::;_3:`:3:""3'2;;5gg;- $1212,
2: '. ' ' '
- f-:.- :.:1*>.1
ri -_'21:3:3:-:Q<3:3l:i<-f<3:ct3'\~`g":-
"'3_ff3':3:3':3'i:3$}'.f::FS5:3$:3:T:F:3:3; "sf,
,::_-_-_ ;__;.-:___ _..__.- -.W-__:-__'{/_/_<>'f>f;-*:'_;_f'_;t __.-_ _+__\;- _ .-_-:_-_\,-_.'.,_.'-~.-.-_-_-:' -_~_-_~-_~_--_:
'- *-- ' _' ---.f---_---_-it-xt-_-J:
_ :: - - ::'- -.- -+'- -.-:-- -' _
_=t;t -%='; ;`;`;"'*-'1':';==I' -1; ?='; ' " 5-ii* 1 1 fe- f`St':-:*.-'f.\;2:-;:~}--;-; =: : _ - :-:-:-;-
wltwlm ktpn ft _ -_ -_ _,_-__-_-.-. :--
.'3;"""`_3'l""2'"'*l-"'-tf-'---_-_-----'3'3-_3-:_:_:::::::: -`!'3' ''t`-!` -'' "'lt_.":'3:3Z`f ::-;__::::':_:_____ " " :;' --I-'f"'r-'-"<'-'~I-7-'--': 't`f-'-
___,,__;_,_,___., _t-_ _ ___
-ii _;;-;5-2;;-2;;5-52-2:'IE-aazaff fiai-2 tiiait t ,=t~'=t__t=-;^f; ;=:1-__ ';:=;;;'a':'2;a;-ti -*if
:t~'
f -_ _A.C' _- :::;::::::::::: ': J -If.-_.
_'Hfjff _3::-:::::::;:::: ::-_`3'3_3'_3';_: __,-"lt';_-L-'L.-;"l9'3'tt
-_-_-__
-.--
_--._)-,_;_-_-__- ' _
__;____'__---_
- - --
_ '_ _3':'
.J _ - '-.-
'v <$':' 7 i__'.';'.-ig"
:gp-.___ \,,_"~ _
_
es _ ;
gt'-ha _ _-.$."~ :::::::::::;; : :--_;: -_-, -1-'+ _ - _____':-
___:'___:'_- _ i .,-t :_*____ r _
,_._ .i-Cn---.-C -_-.If-,: f:"

.-:_-_.-_-.M-.._3..-..+t-_-I-.\-tj-iv----
- -
- -.-,-.-.-!-_-.,y.-,-_-.-.-J_-|_;_;;:.;.-._..-.-_._ --_;;~
_..--t .-:'5___
_ _-t _ '*** ..I'
_
4`5<-W* -9 :"_-` _--flliit'
::-.:':~"' :-1-'-'__,iii-:igilt: .t ~:__g_;_- i-'{;_
--'-'~"1.1-.
.WP __,_J__ __ _______ _? _ _ _ _
iiilllliiiiii filf iiulIfff :_:- 3 __; _ itiEitiliiitiiiiifttiiiii

The following scoring applies for moving a pawn in that column,


this makes the program prefer to move central pawns at the start of the
game:
_ -'-\'-'-'-='-'-';:-:-;:-:-:-:;:-ag:-;:-:-:-:-;a:_: - -:-:f-:-:-:c-:-:- 122222IIZZIIIIIIHIIIIIIZ-III
:_:::::::: ::::::-Si i$::1$-5:32FFFF.f1\:3M35:3i:3$:3::::: ------_-_las-_\-_-_-_=c__-_-_-_=- _- - __ _ f?f1>j ffi:-:--:-'
:-:-::-::-_-_-:-:-:-' ffffii-:-.-:-'
fiifEIIII
:.'-.:ztt -'-te-
' :-_-:
_.-_-__.,
1-:-:-2-:-::15S12;:_-t;:5::;t:::::;:,: -1: -_
_ _ _ ..' .. 1- -3:-vi:-:-:-_f:tx-:tra:-rx-i!:;$-
_;:-:-:;:-:-:-:;;:;__'_ "<;:-:c-'-:;'5<c_,_, ::_ - _ sm' -'e-:-::.-E-:.ftt~:l
'-\:-:-:-:-:-:-:-;-:-;-1-:' _-:<-:-:-;-:-_-:-_-:-: _' _-
-_--_--'-:-:;::;:::;:;:;5_ :;:;:;'-'~:;:____:'
.I -_._-_27_
)\- - ri __-__._<= :-- --:-1'-li jtttf fs,
tt-zu-:' :-s_:;:< ;:_-:;::-,:;:53-'f:;; ' ' '_:-: ' _'; *Jl- _;22< ;-- ; 22' -:_:__::::_____ _I_:_:::__: :::_::
..
1-_-=-2+''
.__f. .._r ...ll ...__
: :-- : :-:-
__-:;$'.\;.g.';:; 5: _*.;:3.i-:;;:;::3:_I-
.-sv~:
. _ , 't+ ' '_ _'-----_-'3'3:-_-::-: 1.=:;:=2=;:=:1-;.;.;: 1_:5-;~f;t ;iti;it%i =lil ;55;-;.=_-555.;55;
.-`\.
;;;;;;1.;;;;;;2; iit'f..'_\f
_
$222'__,._193.
-bl'-.5
_*-;,Lt_.
~:-
_; -:<+5t;:*_-;t- _
' ' " '- 3_3'3'-'3:33'-23:32;:3:3:-'3_`$33._3.f -/-fa -.v_-tu-':-_-c5--:-
@-tai-2-;::3'=;-:-:3:3'
=;.=-2;:3:3: ' 2'-_-"-:fi mi-: ' .+1-:;-:-:"-t-_ _____:::::::::::-':'__:`:::::'::::::`: ""
"
_.-_p.'-_
rr-t_-_%`fi__-.-'^ f._;;_-f- ,-::_:
-'- " _!_- __
fmx -:T4 n.'4-v-Q
5 2% .-:3'"_3`3'33`3'3'3""'333"'3 "'"'3'^i.4'3'ii'''i'''f'3i''fi''i:F:34::3:::'::
___________;___E___r__;.1_-.-_-.km--;;-__
'3.3-:3:3_""` __________ _____________ ________
~. __ ^^"__:`:::::':'::':'::`:3::': ~_;_;'
_`_'_3i :_3f:_:`-::::_ "':::`::3_"" -::::::3r-.gr
._f_ -if _
_;:~;;':;:;.
12-.. r-inf r I ri--HI

>Sfi<`z-'ifrf;i':``__f-'.:`_`_'.i' :3:-' ' '


_ -_
-- -- .J
-.Hu-ww -J.-a
1'
-1
-- _;-_
'-" ititaiatfa.-;:= tirrsrttrtrfettttstmss ~\.

It adds 8 points for moving the piece away from its original square
(not applied to king). lt adds 9 points for doing castling
Toledo Nanochess: The commented source code

.. --_--_-mi-. .__ __ _ __ __ _ .; ;.;__;_;_;.._;_ f_ _ _


- -- __-_-__,;_~-_-_-_--tp.fi,-.;..-__;_;;;.;.;____ _- -- -- - _--_ __ .___ .___ _
' I-I -- - - _- -'':'3:'_f:'}_-I:I5:3!-:3Q3H3:3:3:3:3:3:-:3:3:`-:3:3:3'-'--=-I _ _ _ _ _ _ _ __ :-:-:-:-_f^-:3'3.'33-:t:3f;t-:r-:i-:;-:- __; ;;; -- _- -- -t-:+:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-S:--:-ll@- ' _-:-::__-:_
I-I - " ' 1:- _:_:____i_1-':-^:- ''.-'.-'-"-:--:-:-:-:-:-:-:-:-;-:f:-:-::-_-::: -:-:-:c-:-:-:-_-.cu-- .*.-P~':-.-:-: :: ' :::' = " __:;::::__;:__:___-_;2-':-:-:-:-:-:-:-1-:-:-:-v_:-:-:-:-:-:-:-:-.-_'-.-:-:-.-::::: __ _ :
:-::-_' ': '- -;;-;_';5;;;;::2;_;;il$1i:li;3$:3::3:3:3:35Fif::::::" :: _3_3:3:3'_3:3:3;331:f:3v`!33_-_1;:'-Flf%3:: _ __ __:_"'-: -3 3-31.-_` I' '- - -l53333f333333f333f3ii3:3:3f3l33 3":'""ff':` l 1
-- ______.___::-._-f-_-_-rr:,_-_-_;_;_;_;__;_-_;_;_____-_ -- _;____3.t_.;...--.;.;...;.t-_;_;__;. - _ - _ _._.;_;.;_;___;_;_;_;_;_;__-_-_-_-.__-.;.;f__;_.;.__-__ __
-- -- -_ _
'-----::+:-:-:-F:-232355' '-:-I'-1-::-::-:-:-:-::-:-:-::-::
-
-:_ ' -:-:-:-:-:-:-.-.-:-- '-1 -'*-:-:-::-:-:-:-'
-:-'-:-:-:-:-;-:-'-:-:<-:-: -:-_-:-ifii--1-I-in:-13: __ 1'
- " ' " _
-:_-: - :--
-:-;:-:-:-:-:-:-:-:- -'-:_-:f-::-:-:-:-_-_ --
-:-:-:-:;:;:-:-:-1-:-;-:-' -_-_'-::-:-_-_l'_-:_-:~:-.-_--_:-___.. _
'__3f-f* _333333"' ?'*."I~>-_:f:f'3 1.111--= II' ' ' --3:3:f:3::t:::: 1:3::$:3:3:l$::*3:iF-' ::-: :_ ' ' - - __-_3:-_:_-_`_-$i: '-'51":-'"". 32352I331113I-2323232323'fi 2-'-._-23::-2'-:__ - 5' V
1""-''II-f1"'f I. 11'3:13T-f iffl-if33 'fi 'f . ' .E333ll1 5if-tt ' '- ' - " ' - - 5fff3f3i:fiff:i:3i155- 1': "':":::: 1 1' 3:55
'_'_'_____;_::;ffj;':____:j; ~,f_,-:;'-5:-:3:3:3:-:3:3 :3:-3:_:`-:3_f':-H-_:t::t______;_;,______'_1___ :_:_:_:_:_;:,:_:_;f$$:33_:3f_:'2::3:3:3:3 :3:3:3:3:3:r'_-_'_:f?.3'____;__ ' = ':___,_____,________;3____j:_j:j______:lt:l3:Il23:3 :'c3:-':3:3:3:3:t3:33:3:3::___j____;___j____;______'_;_;'___:_:_:_:
'::;::;;-;;-;;;:;;::;::::::;;:-2_-15];{-__5 - ;::;5;::;_:t;:;:;: :;:::_:-_::1::;: -___.-_-__: __ _ 1"__ __ ;_I;;f_;;;;;;g_;;.1f!_E-i__I- ;;::;;j;i::g':::;; :;:::' :_---::: :- _:::: __ -- -- :;:3:::::};:::;::j :;;;i]:t';;;:.;]
_.;._.;_i;;5_;_;_..;___;__;_;_;_;_;g;q'____________ _ ,_ _
-_"_-_'-_"."3~._-.z-.w.-_-.-_-.<.-r.v_'.-.-.-_-__-_--_ -_
- ______;.___.;- _-_
- _- --r.-_-_-_-....'.-.-.-C
t r 2 ::-:-:::-:-::: _'
_ _-
'::-'-:
'--_-_-_-.._
t H r
-:_-__-_-_-_-_;-_-.\-_-.~.~.'-.".-.-.....-- r
..t-.;.._tt;___-__;_-_;_;_;_;.-_-_-_-_-_-_
'..\. _.','.-_--,_-_------.......----

rr 5. r 1 A v
:-:-::~:-:tt-:_:-'.;:'-:-:-:-a:-:-:-:-:~;-'_-:;-:-
-.__ __ __ - _ - ';-_-_-_-_-_-Z-A-.-2'.-r
-:-:;-:-_-:-;.';:1-'
f_.-.-:-_'_;_-; Si ';c-:-:-:-:-:-:-:-
-"-:-':-:-:-:-: -- -- - :-:-:-::-:-:-:-:-:-:-:-::-:<-"\'"~-'
-:-:-' -:-:-:-;-::-:-:-;-a '"' 'i*';l;-.*I-
5 -_~l.ti _ -- -' II"IIII..II"'tttg;-'''tt,;-'-'3'?'3^'3'33'3'3f'3'3:3Ff"
-: -:-: _ '.',v1.-i,,-. _-:-:-:-:-:r::-::-':-':-_-f' 5
_;.;.;.-_.;_-_\_-_;.._'.. 1 ---;{-;.--;-;-- ' 3J5.'.'.':- . -- _ I '-'.-\_~.-.-.-_-_-_-.ta-_-. '..;\:l".'.p - .;3'.''._-:_-_-.-.-.-_=F.-.
;.;.-_-.-_\-;..;.-_-:-_-,_ -__,-.._-_,
_;.:;:-_:;~__:_1___-__.r_ __;_; __-_-_-_-
.;_;q;.; -;1;;- _..;.;---_-;-:-;-;-;-:-:-:-:-:-
;'_;_;_;_;_;_;_;_;__;_ -_.sipgf;---1;;
-~_-_-.;-;- -- - :- _--__:;-:-'
---:~--t:-:-' +:-:;-:-:-
t;.g:5-:;;f;:: _-_-:r~_--:-
::::,:-:--- ; -- - - -; :-:-:-_-M:-1-.F
--;:;:-:t;:-:- t,,-.-;-'
5 :--:e-::-;-:-:-:-:-:-:c-
-55_g::;;:;:g::;::;:
I;I;I_L.:-$~:-
-_-.-mm tf-:kitti:--;-:t:-:-:1;-:-:
-_-l-_ - -- -- - ' -:c-:-:-:-:-E-:-:-:-:2+2- '$:-:-:--:-:---: _ -: ; - __ _ _ 1__.t-;-at-U;-:-;-,u-1-:-:
----3-1-jp-1--1-1.;.;.;.;. -;-:-:-::;-f_- -- - - _ --:-:-:-:-: :f_<-:-: tt-:-1-ziiv:-1+:-1:-:+1-:-:
__._____._._._____ :_-_-,,-,-_-_-_-_-_-_-_-_-_-_-_-_-_--- 3 -._-_-_-_-_-_-.\.-_^.''1'1 ..-...;.... _ _-.-.___;.___..._. -.-.-_-_\,' - 3 - - __ I-I-2-)I'f'f1-H-1--\'--`-I'-ZC-1-I-I-I-E
____f__~_-_.___..__..-_t._._._._._.___._.
:-:-_c-_r-_f._. _*:--'+2-*az-:+2-:-:-:-:-:-_':_ _'-':;:;:;---- _ -_ -:-:-:-:-:-:-:-:-:-;:-:-:-: s t :-:-:-:-...:-I-I- ' ' _: Y - --;5-;;;j-'--I-I-I-I-I-1- 5
I'-I-I-_--fi _ 'I1---'I-I;;-''P---t::-::Pa+:-:-:-:-::-:-:
51.35i'..kit1'-:3:3:'-:3:3$:3:3:3:3:3$--'3'-'-'3'33:--'-'-'3--" ' ' ' -:_1:I-1:I:II'
;.;.;.;:_y,_...;.;2.;1.;.;.;.;.;.;.;;_;_ ._.III"" 2,1. ' '
i'-I'-Ii
--1-1-1-;-1+;-;-;;f,-rr.. -.f
t P*
-*fftitiif
_-:-:--:-H+::- '
__ -I-935135-3 3335- -la:-_-'
1-':';1_-:-:-;-_-:-:-:-:-:-t-;-
$;:l'::1:1:: _________3--$:-' -*--
-:-:-:-:-:-:-:-;-:-;<-:f.-!~:-:i------
__ - _ - ----:-:-:-:c-;1-:c;tc~t-:-:+$:-:-:-:-:-:-_-:-
:_1;i_:I-_?.$511:H'H:::>:%%32323232339*

+1 point +1 point +2 points

' ' ;-;-;-~x-:->_.:-:-:-:-1-:-:-:-:-:-:-:-:-:-:-:-: ____


I'tt;-t-22-:-:-:-::::-:-:-::a:::-:-:-:4-:-:-:- - - --
1'*i i i ifttif2IEIIESEIEIEIEIEIEIEIIEIEI ' I -'
":': _f$.f:-:-:-_f:-:-:-:-:;-:-:-::-:-:-m:-2:-:+;:"""
.35/;.-._-_..;;___-_ -_
` `- - I" ' ' '!':'H''-'*'H" '1"*' H'*'''': ' " ' ' -----
-- :-1-:p' -:-:-'2-'-;- _ -J'_-:-:-:-'-'-'-f-.'f_-" _-.:-_-:::-:- :"
_._.__._._._.__._._.__,,_._._._.__.__._._.I._._._._._ _ _
_ ..;.;.;.;.;.;_;_;.;_;.;.;.;.;.;.;..-_;._;.;.;._ -_.',-____.__; -_ ;__;_

rr rr tu i ___.;__:;-'-:::__ _ _ .;.;::' is g;';_;2I;


EXE1lplC Of blOCklng
t-!-:-:::-::-::::' " -- ' - :-:-1-:- "-'I'-2
to-o
_ _ _ _ __ _<n;_'
5 33_t3t3!3"_:3:_3'_3:33`3:-:::`3:3:33_`_' " _ ` _3':3'_-3:3:3:3:3::3:3:3'3:3 .glli
3:3:3:3:3:3:f:'_3::3:3:-::`:::'_':":;:v_____ _ _
__
'3:'_3:3::3:3:3:f:3:3 .'._.__,._..
;Qfft_t _
ff _-_-5*-:-:-I-I-I-2-I-2-:I'-:;::_:::::: _;::::__ ::'::'--
::_-3-:_-_-_-_-_-_-:___.___-
'--I-!-m:::-:-:-:-:-
--'.'._-_-_-_-_-_-_-_-_-_-r
:-'f-.fr-`-.
i i 'l
'l-U
f_-; =2=2=z=a=2:'-;2f;:2=_.-=-=; ._=_=;-;- =: .=-;:- -;=; -- .e.t.:.2=_==n;:1.?;=z=;
|`-'-''-.'.'.'.'.'.'.'.' _ _ _ '-'-`-`-T-`-`-'-'-`-`-`-`
3
' :=;=;:;:a=;t 1t:=t : 1l';'it<t:5t=:2:=; - ' -=
. . r;=-_=;5=;r==;==;r::_ra<;lavugtixi .. .
3`333 - - ` __, 32325;-3L3:3:3:3:E3:3:13:2illl' -(ii-.3fff:3333333"` __3-
_______,____ ______._____,______________.
'._;.;__..;_.;.;_;___;2_2'_;?.;_.;l-:._______ 2
:::' 1 1 1:-:-:+1-:-1-:-:-:-:-::-.-:-$:}:-:{_----:-__
':-:ff:-_\:---*.I
-- -- = -:-:-:-;-,'-:-;;:-:-:-_-_-_-:-:-_-:-_-:-:-mi-:-~:t-"- --
: -1 - - : : :-: -ir-:-_-_-:-1-_.-:-:-:-:-:-:-:-:-:-;-:-:-:-_-:-_-:-:-:-'-:-; 1 1 : 1 1 _ _ _ 1 _ _ ' _
- -:- - - = - f:H+:-:-H+:-:-:-:-:-:-:-:-:a-:-:-:-:-:-:-:-:-:- -' -' - -' - - --
1- '-1 1- :-: 1 1 _- .;::_qu_2;';r:;:-:-;-:-:-:-:-:-_-a:-;-;-:-:-::f-:-_-: _ _ : :-- : - : :-:-: : -
1' -1 1 :-: _::-1: _;-;.-::gt,;1;yr::::::-:-:-;--;-:-:g:-:-;-:-: - _ _ : : : : - : : : _____

+1 point

For pawns, one point is added for a partner at the left side of a target
square and one point is added for a partner at the right side of a target
square. The pawn value is substracted from the material value for
promotions. One point is added for advancing two squares. For all
pieces, one point is added for blocking an enemy pawn.
When capturing, the program substracts the depth level (with a
penalty for delay) and prefers to perform a capture with a pawn, king,
knight, bishop, rook and queen (in that order).
For material scoring see line 38 of the source code.

4.2 Toledo Picochess


Toledo Nanochess has a little brother called Toledo Picochess. This was
another leaf of development, also a descendant from Toledo Chess l
and 2, but in a different way.
I removed support for en passant, underpromotion and castling, and
this allowed me to save a large amount of bytes, with the source code's
size reduced to less than l kilobyte!
It has some very good tricks for saving space, but when I tried to
base it on Toledo Nanochess, I discovered that it wasn't simple to do,
because some tricks that help to save space in Toledo Nanochess were
totally out of place in Toledo Picochess.
The algorithm is rather similar so it's not necessary to explain it.
This is probably the smallest-ever chess program in C that plays chess
<<intelligently.

42
Toledo Nanochess
-k'k'r~.4r'c*:r-Jr'.lr'\"k:!c'7\--Jrulrir':1\'9rk4r''-k1:'k1:'7lr1'r'Jr'k1i'wi.-*1':|r'k*1*.'1r1lk1r*'<'"k1r**:'k'i:''r1'rrk'Jr7ic"#'ic'i1f')r')r1"k>\"-^_:'<'\

Toledo Picochess (c) Copyright 2007 Oscar Toledo G. All rights reserved [
944 non-blank characters. Evolution from my winning IOCCC 2005 entry. |
o Use DZD4 algebraic style for movements. biyubi@gmail_com Jan/21/2007 |
o Only promotion to queen, no en passant or castling. nanochess.1l0mb.com|
o Press Enter alone for computer to play (num.args+5 == depth of search) I
o Remove these comments to get 1009-bytes source code {*NIX end-of~line) [
'k-k:k'ct'1r**v`\'':'irrvr**'r*1lk'k1\'1|:'k*'*****''k'k1l'**1r')c'i**9<':":f'Jr'\"<r1<':<'1<!<'k:k^k:4r1rkk*1lr1r^."k*''k9f9r/
_ .'-?_. i -

#define F (getchar{)&l5l
#define v main{0,0,0,0,
#define Z whilel
#define P return y=~y,
#define _ fifl
char*l=dbcefcbddabcddcba~WAB+ +BAW~ +-48HLSU?A6J57IKJT576,;B,y,
b,I[l49];main{w,c,h,e,S,s){int t,o_L,E,d,O=*l,N=-le9,p,*m=I,q,r,x=10 _*I){y=~y;
Z--O>20){o=I[p=O]_ q=o^y,q>O){g+={q<2) y,t=q["51#/+++"],E=q[95+3/33"];do{r=I[p
+=t[l]-64]_lw|p==w&&q>l|t+2<E|lr){d=abs(O-p}_lr&(g>l|d%x<1) (r^Y)<-l){_lr^y)<-6
)P le5-443*h;O[I]=0,p[I]=q<2&(89<p[30>p}?5^y:o;L=(q>l?6~q?l[p/x-1]-l[O/x-1]-q+2
l
0=(p[I]-e?s4s=a/si}+1[r+15]*9-2ss+1rp%x]-h-1[o%x];L-=s>h|1s==haL>49a1<S?main{s
>h?0=p,L,h1,e,N,s=0 _!te-o|hlp-b|s]L<-lee))return o;o[I]=o,p[I]=r _ s|haa(L>N
||lh&L==N&&l&randl))){N=L _lh&&s)B=O,b=p _ h&&c-L<S)P N;}}}t+=q<2&t+3>E&(ly?O<
so 3s<o)|lr;}ziraq>2sq<s||(p=o,++t<s));}}P N+1e9?N;o;}z r[s1=~(2i>e|9s<s|2>(e+
l)%x},++B<l20);Z++m<9+I)30[ml=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 l,3+w);v Oflltll

4.3 Commented source code


Note that the revisions are from the tree of development of stable
versions, leafs that don't work are left out.
: /* Toledo Nanochess. tc) Copyright 2007~2009 scar Toledo Gutierrez

: /* Revisions:
: /* Aug/24/2007 Aug/25/2007 Feb/O4/2009 Feb/05/2009 Feb/os/2009.
: /* Feb/13/2009 Feb!24/2009 Feb/25/2009 Mar/01/2009 nar/03/2009.
: /* Mar/04/2009 Mart06/2009 Mar/07/2009 Mar/20f2009 Mar/23/2009.
: /* May/29/2009 Jun23/2009 Jul/02/2009 Jul/03/2009 Jul/11/2009.
O -]O\LJ`|L*. JI\J|-* : /* Jul/14/2009 Jul/27/2009 Aug/03/2009 Nov/18/2009 */
9:
10: /* Introduce your move in algebraic form, by example, DZD4 and_press Enter
ll: /* Press Enter alone for the computer to play.
12: /* In promotion add a number to select piece (3-N, 4-B, 5-R, 6-Q)
l3:
14: /* The board is represented as an array of 12 rows by 10 columns with the
15: /* 8x8 board centered_ */
16:
17: /* Piece representation: */
18: /* 0 - Empty
l9: /* 1 - Black pawn */
20: /* - Black king */
21: /* - Black knight */
22: /* - Black bishop */
23: /* - Black rook */
24: /* - Black queen */
25: /* - Border */
-JOlU1il2>L0lZ\J
26: /* 9 - White pawn */
27: /* 10 - White king */
28: /* ll - White knight */
29: /* 12 - White bishop */
30: /* 13 - White rook */
31: /* 14 - White queen */
32:
33: /* Add 16 if the piece is at its original position */
34:
35: /* Initial board, piece ORed with 96 */
36: char *l = "ustvrtsuosqqqqsqyvyvvyyvl{l~z|{}"
Toledo Nanochess: The commented source code
37 /* Points by piece : Points for center : Piece letters : Movements */
38 76LsabCddCba .pknbrq PKNBRQ ?A6J57IKJT576,+-48HLSU";
39
40 #define F getchar()&z
41 #define v X(0, 0,0 .2l,
42 #define Z whilel
43 #define ;ift
44 #define P return--G,y^=8,
45
46 B, /* Origin square of move */
47 1, / * Final piece (for promotion) *J
48 y, /* Actual side *J
49 u, / ak Pawn available for en passant */
50 b, /* Target square of move */
51 I[4ll], /* Actual board with space for best moves table */
52 *G=I, /* Pointer to origin square table for best move of enemy */
53 x=l0, /* Constant 10 */
54 z=l5, /* Constant 15 */
55 M=le4; /* Constant 10000 */
56
57 /* Calling forms: */
58 /*s= 0, s = 1, verifies and does legal moves */
59 /* S = l, s 0, verifies if king is in check */
60 /*s= 1, s level, the computers chooses a move */
61 X tw, /* Recapture square (quiescence search) */
62 Cr * Enemy score leveled to zero */
63 h, /ir
Actual analysis level (starts from 0) */
64 e, 'Jr
Initial search square */
65 S, /ir
Available pawn for en passant (or 0 if it doesn't exists) */
66 sl /'Jr
Maximum level of analysis */
67 {
68 int tr ff*Limit piece (promotion) for move in analysis */
69 o, K* Original content of move origin square *t
70 L, /* Crude score and later move score */
71 I! Contents of square in front of the piece (pawn advance)
* */
72 .HI * Indicates whether the king is in check */
73 (D tlf * Origin square of move in analysis */
74 ases=-M*M, H* Net score until this point */
75 K=78-h<<x, /* Scoring for mate */
76 pr
'ir
Target square of move in analysis */
77 *s * Pointer to pawn captured_en passant or rook castle end square
78 nf IX*Final piece of move in analysis *E
79 m_ Pointer to rook origin (castle) */
80 A, _/9:
Limit offset for piece movements */
81 qt
ir
Code of piece currently processed */
82 ff ."/_* Original content of target square of move */
83 C, _/9
Actual offset in movements table for piece */
84 J, Tells that is not possible to castle */
-Jr

85 a: y?~X:x; //tk Inverse direction for pawn advance */


86 Y ^= 8; / ak Side change */
87 G++; /* Advance pointer for keeping best move */
88 d = w || s aa s >= h && v 0, 0) > M; /* Checks if king is in check */
89 do { 7* Search the board */
90 _ o I[p = O1) { /* Read piece (original in o) */
A
91 Q .-.-. O & Z Y
92 q < 7) t /* If piece is valid (code in q) */
93 A q -- & 2 ? 8 : 4; /* Number of movements *I
94 C O - 9 & z ? q["& .$ "] : 42; /* Locates piece movements */
95 do {
96 r = I[p += C[l] - 64] /* Slide in direction */
97 _ tw | p == wi { /* Simple movement or recapture */
98 9 = q [ p + a ~ S ? 0 : I + S /* En passant? */
99 _ lr /* Move to empty square? only if not */
100 a l C1 l Q /* pawn, l/2 squares or en passant */
101 lr + 1-* 2"* N K > 9 /* Capture? only if not pawn, or */
102 && q | W> ,-^
__ /* pawn does capture. */
103 m = llr - t/\.\J\.-' _ ))
___] /* If eats king, doesn't analyze more *t
l04 P Gil] = O, WR">l\J- fu)
105 J n = o & z; /* Piece minus flag of not moved */
106 E I[p - al & z- /* Gets piece just in front */
107 t q | E - --J w 5 /* Simple move */

44
Toledo Nanochess
108 : (n += 2, 6 ^ y); /* Promotion */
109 Z n <= t) {
110 L = r ? l[r & 7] * 9 - 189 /* Points for capture... */
111 ~ h - q : O /* ...minus points for delaying */
112 J/-k 1- .minus points for capture with big piece */
113 _s)
114 L += (1 - q ? /* All pieces, except king */
115 l[p / x + 5] - l[O / X + 5] /* Conquer center */
116 + l[p % x + 6]
117 * _~ iq /* Points for being central pawn */
118 - l[O % X + 6]
119 + o / 16 * 8 /* Points for moving out of place */
120
1 Elm * 9) /* Points for castling *X
121 + Q /* Scores pawns */
122 9.@p _ 1] ^ n) + /* Points for left partner */
123 H Ep +
M.:. ] ^ n) + /* Points for right partner */
124 1[n & 7] * 9 - 386 + /* Promotion */
125 lig * 99 + /* En passant */
126 (A < 2)) /* Points for double square */
127 + 1(E ^ y ^ 9) /* Points for blocking enemy pawn */
128 _ s > h /* Normal analysis */
129 II 1 < s & s == h && L > z /* Recapture search */
130 { /* If in check do a further ply */
131 p[I] = fl; /* Move to target square */
132 o[I] = /* Clean en passant and origin square */
133 m ? *g = *m, *m = O /* Castling */
134 >l-
CJ C3 /* En passant */
135 L--: ><2 C11 ~\J C : p, /* Calculates recapture square */
136 /* Actual score leveled to zero */
137 asno /* One level more deep */
138 V],
I-*+ /* Best move of enemy */
139 = q | A > l ? 0 : p,/* Calculates pawn for en passant */
140 \-no
.-1.- /* Analysis deepness */
141 I( m-~m s~1|B-o|i-n|p-b|L<-M))
QQUF
142 >-~n:8]_]_: J; /* It is a legal movement */
143 J: /* It is not the king... *J
144 A --Ji-1 /* ...doesn't.moved one square... *K
145 /* ...already castled... */
146 I .U- /* ...it is on verification... */
147 /* ...it was on check... */
148 t -'11='.Q*<I'.I5' /* ...capture... */
149 W o <Z /* ...already moved... */
150 I v 0,0) > M; /* ...it is in check now */
151 O[I] = UF /* Rebuild origin square */
152 p[I] = ri /* Rebuild target square */
153 m ? *m : *gi ak
g = 0 /* Restores castling */
154 = 9 ? *g = 9 ^ y : 0; /* Restores en passant */
155 }
156 _ L > N /* Best move? *X
157 /* || L se N & Eh && s > 1 && 1 & rand*/) { /* Random? */
158 *@.=o
159 s > 1) {
160 -_h as c - L < O) /* Alpha-beta cut */
161 P_ L;
162 Eh)
163 -1 = n, B O, b = p; /* New chosen move */
164 }
165 N = L
166 }
167 n += J ]| (g = I + p, /* Get target square of rook */
168 m = p < O ? Q - 3 : g + 2, /* Get origin of rook */
169 *m < z /* Rook already moved */
170 I m[O t P] /* Possible third square is not empty */
171 II Ip += P O]}; /* Second square is not empty */
172 /* If no condition valid... */
173 /* ...king moves two squares. */
174 /* increase piece code */
175 }
176 _ 1
177 - }
178 . } Z | r & q'> 2 /* Keep moving if queen/rook/bishop and empty square */

45
Toledo Nanochess: The commented source code
179 || (p = O. /* Return to origin */
180 q | A > 2 I o > z & lr /* Verifies pawn advances 2 squares */
181 && ++C * --AD) : /* Next move of the piece */
182 }
183 1
184 } Z ++O > 98 ? O = 20 : e - O) ;
185 P N + M*M && /* In quiescense search and without recapture... */
186 N > -K + 1924 | d ? N ; 0; /* Detecta stalemate *f
187 /* .. quiescense search returns 0 */
188 1
189
190 main()
191 {
192 /* srand(time(O)); */
193 Z ++B < 121) /* Init board */
194 *G++ = B / X % x < 2 | B % x < 2 ? 7 /* Border */
195 : B / x & 4 ? O : *l++ & 31; /* Piece */
196 Z B = 19) { /* Infinite loop */
197 Z B++ < 99) /* Shows board */
198 putchar(B % x ? l[B[I] | 16] : x)
199 _ x - (B = F)) { /* wait for algebraic move */
200 i = I[B += (x - F) * x] & z;
201 = F;
202 = (X - F) * X;
203 + - (*G = F))
Ntfo* N /* Piece selection for promotion */
204 i = *G ^ 8 ^ y;
205 } else /* Enter alone for... */
206 v u, 5); /* ...computer to play */
207 v u, 1); /* Perform movement if it is legal */
208 1
209 }

46
Toledo Nanochess

Line 36

har *l = "UStvrtsuqqqqqqqqyyyyyyyyl{|~z|{}"

The first part of the string contains the initialization data for the
initial chessboard, codified as ASCII letters, of course, so this Would not
run on EBCDIC systems.
If we use an ASCII table, We can see the codes used:
0x75,0lll0l0l,f
0X73,0lll00ll,s'
0x74,0l1l0l00,t
0x76,0lll0ll0,\f
' 0X72,0lll00l0,T'
0x7l,0lll000l qf
* 0x79,0llll00l,f
' 0X7d,0lllll0l,'
- 0x7b,0llll0ll,'
0x7c,0lllll00,T
' 0x7e,0llllll0,Hf
0X7a,0llll0l0,f
Bits 0-2 chooses a chessman, 1 is pawn, 2 is king, 3 is knight, 4 is
bishop, 5 is rook and 6 is queen. See line 94.
Bit 3 chooses side, 0: Black, l-= White. See line 91.
Bit 4 indicates piece in its base position, useful to check castling
privilege and to score movement out of initial position. See line ll9.
The remaining bits are cleared to 0 on chessboardfinitialization. See
lines l93-l95.
Remember that bits are numbered from right (0) to left (7) inside a
byte.
Alternately you can change this string to start with a different
position in the first two rows and last two rows. This is useful for
Fischer Random Chess (Chess960), though only for positions Where
king and rooks stay in standard chess positions because of the
hard-coded requirements for castle handling (see lines 143-l74). Never
set bit 4 for king and rocks out of their standard positions, or else
Toledo Nanochess could perform Weird moves.

47
Toledo Nanochess: The commented source code

Line 38, divided in three parts


" 76Ls"
"abcddcba "
".pknbrq PKNBRQ "
"?A6J57IKJT576,+-48HLSU";

Just like line 37, this string contains codified ASCII letters for the
representation of piece scores, relative values of columns and lines,
piece letters for visual output, and movements of chessmen.
To determine the piece score on capture, the ASCII value of the
letter is multiplied by 9 and then 189 is substracted; this is equivalent to
substracting 21 and multiplying by 9 (see line ll0). Since the score is
calculated only when capturing or doing promotion (line 124) except for
empty squares and kings, the first and third character are useless. Only
the second character (space, 32 decimal) is used for pawn scoring, and
the fourth to seventh characters.
Pawn value = 99
' Knight value = 306
- Bishop value = 297
~ Rock value = 495
Queen value = 846
The next values are used for doing positional scoring. Because they
are substracted from the previous value, only the relative values are
necessary, so We could put "0l2332l0" instead of "abcddcba" (see lines
115,116 and 118).
Next, the piece letters are defined for visual output (see line l98).
Finally, the codified movements of each chessman are defined,
relative to 64 ("@" in ASCII). The first four characters are used for the
rock, the next four for the bishop, the following eight are combined for
the queen and king, then four characters for the white pawn (using two
of the bishop) and four more for the black pawn. The last eight
characters are used for the knight.
Remember that the chessboard's size is l0xl2, so one row up is -10
or 54 (ASCII character for 6). See line 96.

48
Toledo Nanochess

Line 40

#define F getchar()&z

The input and output in Toledo Nanochess are heavily optimized.


This simple macro reads the character input and returns a value between
0 and 15, using AND 2, Where z is always 15.
It is the only invocation for console input Within the entire program.
See lines l99 up to 203 for further explanation

49
Toledo Nanochess: The commented source code

Line 41

#define v X(0,0,0,2l,

Another macro for saving bytes within the source code. This
constitutes the most common call to the search function.
The four hard-coded arguments initialize recapture square to not
used, enemy score to zero, starting analysis level to 0 and initial search
square to 2l (the top left square of the chessboard, i.e. the starting
position of the black rock). Check section 2.3 for chessboard
cocrdinates used in Toledo Nanochess.
The X function returns the score of the position, depending on the
type of call, which itself depends on the other arguments passed to the
function. See lines 88, 150, 206 and 207.

50
Toledo Nanochess

Line 42

#define Z wh1e(

Macro for character optimization of the source code. This is a direct


descendant from my original IOCCC 2005 entry
One character replaces six common characters, but the disadvantage
is that the parenthesis are unpaired. Some utilities like <<lint can
become very confused by this.

51
Toledo Nanochess: The commented source code

Line 43

#define _ ;if(

Another Weird macro for saving source code characters.


In this case an if statement includes the initial parenthesis and is
prefixed With a semicolon to close the previous statement. Again, some
utilities like <<1int> can become very confused by the unbalanced
parenthesis.

52
Toledo Nanochess

Line 44

#define P return--G,y^=8,

This macro is used four times Within the program. It decreases the
pointer to the best move (see line 52) and changes the playing side (see
line 48).
Used on line 104 (checkmate), line 142 (legal move), line 160
(alpha-beta cut) and line 185 (final result).
In Toledo Nanochess, any code that is used more than twice is an
important candidate for a macro.

53
Toledo Nanochess: The commented source code

Line 46

B, /* Origin square of move */

The variable declarations begin in this line, using an almost


forgetten trick of C language: Since Kemighan and Ritchie's original
compiler, C compilers declare variables with integer type by default.
Although admitted in common ANSI C compilers, this curious feature
has been removed from C99 compilers.
The B variable contains the origin square of the move when doing a
player's move, and also when retuming the computer's move (check
section 2.3 for chessboard coordinates).
This variable and the five others that follow it are arranged to spell
<<Biyubi, the codename for the Intemet browser at the company where
I work. It is a Zapotec word that means to seek without truce, and is
pronounced Bee-You-Bee.

54
Toledo Nanochess

Line 47

i, /* Final piece (for promotion) */

This variable contains the final value for the target square of the
chessboard (see line 50). It can be the same origin piece, and only
changes on promotion. This allows the player and computer to play
underpromotions (knight, bishop and rook) which is vital for generating
and accepting complete chess moves.

55
Toledo Nanochess: The commented source code

Line 48

y, /* Actual side */

The actual playing side is specified by this variable. lt contains one


of two values, zero or eight. This eases the task of checking if the
current piece belongs to the current playing side (see line 91, for
example). `
The semantics change over the course of the program: Upon calling
the search function it marks the current side (O-=Whte, 8:-Black) but
inside the search function it is reversed, because it changes sides on
entry to operate and then changes it back to its original value before
returning.

56
Toledo Nanochess

Line 49

u, /* Pawn available for en passant */

This variable contains the square of the pawn available for en


passant and it is only updated after doing the movement.
lts value changes when a pawn moves two squares ahead (see lines
139 and 142).
The search function contains a current copy of this value in the S
variable (see lines 65, 98, and l39).

57
Toledo Nanochess: The commented source code

Line 50

lo, /* Target square of move */

This variable contains the target square for the move for the player's
move or the computer's move depending on the calling sequence of
function X (see lines 61-66).
Check section 2.3 for chessboard coordinates.

58
Toledo Nanochess

Line 51

I[4ll], /* Actual board with space */


/* for best moves table */

9'

This array contains the actual chessboard on index 0 to index ll9


(check section 2.3) using the piece representation described on line 36.
Zero is used for empty squares and 7 is used for border squares.
The index from 120 contains the origin squares of the best moves,
and it is referenced by the G variable (see line 52).
The rest of the array is unused.
Why 411? Because my birthday is on November 4th, so now you
know when you can send me a nice gift. ;-)

59
Toledo Nanochess: The commented source code

Line 52

*G=I, /* Pointer to origin square table */


/* for best move of enemy */

This variable points to the current best move origin square, a


one-dimensional list which is built during the search process. See lines
44, 87, 104 and l58.

60
Toledo Nanochess

Line 53

x=lO, /* Constant lO */

This variable helps to save source characteres. It is used in many


places within the program. The disadvantage lies with compilers that do
not optimize it to its value, but fortunately most good compilers are able
to detect it.
lt represents the Width of the intemal chessboard. See line 51.

61
Toledo Nanochess: The commented source code

Line 54

z=l5, /* Constant 15 */

This variable helps to save source code characters. It is used mainly


to extract the piece code from the chessboard, code and side, minus the
unmoved ag (see line 9l for example).
Also it is used for input. See line 40.

62
Toledo Nanochess

Line 55

M=le4; /* Constant 10000 */

Another common constant. Note that le4 is the exponential notation


for the constant 10000 (thus saving two characters)
This constant is used for detecting the check score (see line l50 for
example) and forms the basis for the infinity score used when there are
no available moves. See line 74.

63
Toledo Nanochess: The commented source code

Lines 61-66

X(w, /* Recapture square (quiescence search) */


c, /* Enemy score leveled to zero */
h, /* Actual analysis level (from 0) */
e, /* Initial search square */
S, /* Available pawn for en passant */
s) /* Maximum level of analysis */

The main search function performs four different tasks when


provided with different values, the default values are provided by the v
macro (see line 41).
' S = 0, s = l: Verifies and performs legal moves, and the
value returned does not mean anything (B, i, b contain the
move).
S = 1, s = 0: Verifies if the king is in check, a value
returned which is bigger than M marks a check.
- S = l, s = level (plies minus l): The computer chooses a
move but doesn't actually do it. The value returned is the
score (B, i, b contain the move).
Other values: Inner search. The recapture square is only
used at the last analysis level to do a crude quiescence
check, the enemy score is leveled to zero to check for
alpha-beta cut, the actual analysis level (ply-depth) is
contained in h variable, the initial search square gets
derived from the best move table to speed up the search, the
available pawn for en passant in calculated for the move in
question, and finally the last argument is the maximum
level of analysis.
This line uses another almost forgotten trick of C language: Since
the Kemighan and Ritchie's original compiler, C compilers declare the
return value of functions and parameters as integers by default.
Although admitted in common ANSI C compilers, this curious feature
has been removed from C99 compilers.
Note that the letters used for the function`s parameters are arranged
just like in Toledo Chess 2 so that it still spells X/Window Chess,
though it is not dependent on X/Window.

64
Toledo Nanochess

Line 68

int t, /* Limit piece (promotion) */


/* for move in analysis */

This variable contains the limit piece for the current movement
being processed. It is used mainly in promotion to generate
underpromotions (see line 109).
Typically it contains the same value as the n variable (see line 78).
Some people have said to me that it is unnecessary to process
underpromotions, but I believe it is a very useful feature. For example,
as a kid, when I managed to promote a pawn, I was kind enough to
promote only to an available piece, typically a rook since my favorite
checkmate was two rooks against king (laterl learnt to use an inverted
rook as a queen, something not possible with the sharp-pointed bishops
and knights). One things I've always wondered about is why chessboard
makers never include an extra queen. lt would be very useful.
Also I know of various checkmate problems that can be solved only
by promoting a pawn to a knight, and also some tricks like checking a
king with a knight.
Notice the first letter of my last name, there isn't a more obvious
way of assigning non-obvious names for variables.

65
Toledo Nanochess: The commented source code

Line 69

o, /* Original content of move origin square */

This variable contains the original value of the move origin square.
It's used to generate the q variable (see line 90 and 91), to index piece
movements (see line 94) and to restore the origin square after doing a
movement internally for further search (see line 15 l).
Note that it's the second letter of my last name.
By the way, did you know that the name order is different in the
United States than in Mexico? ln Mexico, my name scar Toledo
Gutirrez is abbreviated as scar Toledo G., because the name order is
Son-Father-Mother, but in the United States the order is
Son-Mother-Father, so if I were a native of the United States my name
would be abbreviated as scar G. Toledo. But please don't use it that
way, it`s incorrect for legal purposes.

66
Toledo Nanochess

Line 70

L, /* Crude score and later move score */

This variable contains a crude preliminary score, used for locating


the best move of the opponent using a l-ply search (see line 110). This
search also determines if the king is in check (see line 88 and 103-104).
Within the main search, it is further refined to be the main move
score (see lines ll3-127).
It's the third letter of my last name.

67
Toledo Nanochess: The commented source code

Line 71)

E, /* Contents of square in front */


/* of the_piece (pawn advance) */

This variable contains a copy of the square value just in front of the
current piece. lt is useful to detect promotion of a pawn (see line 107)
and to score blocking of enemy's pawns, see line 127 and section 4.1.
Fourth letter of my last name.

68
Toledo Nanochess

Line 72

d, /* Indicates if the king is in check */

This variable indicates if the king is in check, a non-zero value


indicates check, a zero value indicates not in check
Letter number five of my last name.

69
Toledo Nanochess: The commented source code

Line 73

O=e, /* Origin square of move in analysis */

This variable contains the origin square of the move currently under
analysis, it originates from the e variable which is used for detecting
end of chessboard search (see lines 61-66).
Last letter of my last name.

70
Toledo Nanochess

Line 74

N=-M*M, /* Net score until this point */

This is the net score of the best move identified so far. lt is updated
whenever a good move is found. If the search function is checking for
recapture (quiescence search) then it can be undone. This is verified
before returning (see lines 185 and 186).
The proper initialization of N depends on the compilers
optimization of the constant. The straight value of 1e8 couldn't be used
here because some compilers do floating point operations instead of a
direct conversion of such a constant, so it was better to do an integer
multiply rather than a oating point conversion.

71
Toledo Nanochess: The commented source code

Line 75

K=78-h<<x, /* Scoring for checkmate */

This is the score calculated for checkmate. The value 78 is derived


from my birth year (it could be another number, but I like to sign my
code) and from it is substracted the current level of analysis (held in h)
then the entire expression is multiplied by 1024 (1 << 10, which saves
two characters compared to h* 1000 and saves one character plus
floating-point operations compared to 1-1* le 3).
The value 1024 also helps to detect a stalemate (when it is greater
than the score for the queen). See lines l85-188.
These big numbers make Toledo Nanochess prefer the shortest
checkmates even if it can capture more pieces, and also appears to be
smarter from the player's point of view.

72
Toledo Nanochess

Line 76

p, /* Target square of move in analysis */

This variable contains the target square of the move under analysis.
lt is calculated using the displacement tables (see line 96).
The order of this and the following two variables is to spell "PGN"
or Portable Game Notation. Just because. :-)

73
Toledo Nanochess: The commented source code

Line 77

*gr /* Pointer to pawn captured */


/* en passant or rook final */
/* square (castle) */

This pointer is NULL (0) whenever the current move is not an en


passant or castling. When an en passant move occurs, it contains the
position of the pawn captured. When a castling occurs, it contains the
final position of the rook.
This variable is used along with the m variable (see line 79).
Check lines 133-134 and 153-154 to see how both are used.

74
Toledo Nanochess

Line 78

n, /* Final piece of move in analysis */

This variable contains the final piece for the move under analysis. lt
is always the same piece it was before the move, except when a pawn
promotion occurs (see lines 107-109)

75
Toledo Nanochess: The commented source code

Line 79

*m, /* Pointer to rook origin (castle) */

This variable signals that the current move is a castling one. lt's
almost always NULL to indicate no castling, otherwise it contains a
pointer to the rook origin. Used together with the g variable (see line
77).
Check lines 133-134 and 153-154 for examples of use.

76
Toledo Nanochess

Line 80

A, /* Total left of piece movements */

This variable contains the remaining number of movements for the


current chessman. Some pieces can only move in four directions, others
in eight directions. The value is initialized in line 93.
lt is also used in certain comparisons to check for special
movements of pieces: Pawn two squares ahead (see line 180), en
passant (see line 100 and 102) and castling (see line 144).

77
Toledo Nanochess: The commented source code

Line 81

qf /* Code of piece currently processed */

This variable contains the code of the piece currently being


processed. This code is adjusted towards zero to save bytes of source
code. lt is calculated on lines 91-93.
- Pawn
-Kmg
- Knight
- Bishop
- Rook
U.If. Jl\J-i@ - Queen

78
Toledo Nanochess

Line 82

r, /* Original content of target */


/* square of move */

This variable contains a copy of the original content of the target


square of the move. It is used to restore the original chessboard state
after doing a movement.

79
Toledo Nanochess: The commented source code

Line 83

C, /* Actual offset in movements */


/* table for piece */

This variable contains the actual offset used to index the table of
movements for the chessmen. Line 94 initializes it, line 96 uses it, and
line 181 advances it.

80
Toledo Nanochess

Line 84

J, /* Tells if is possible to castle */

A value different from zero for this variable means that it is not
possible to do castling

81
Toledo Nanochess: The commented source code

Line 85

a=y?-xzx; /* Inverse direction for pawn advance */

This variable contains the inverse direction for pawn advance. This
Way, it is easier to check if a pawn can do an en passant (see line 98), if
a pawn is being prornoted (see line 108) or to score the blocking of
enemy pawns (see line 127).

82
Toledo Nanochess

Line 86

y ^= 8; /* Side change */

In preparation for the search, this line changes the current playing
side. The change is reverted When returning from the search function
(see line 44) except if checking for legal movement, When it does the
movement and retums With the new current playing side (see lines
141-142).

83
Toledo Nanochess: The commented source code

Line 87

G++; /* Advance pointer for */


/* keeping best move */

Advances the current pointer for referencing the best move origin
square. Within the search function it always points to its own best
move. The expression G [1] is used to access the enemy's best move.
This best move is given as a hint for the next recursive call to the
search function, so it starts the chessboard analysis at that special
square. Check lines 135-140.

84
Toledo Nanochess

Line 88 /* Checks if king is in check */

d = w || S && s >= h && v O, O) > M;

Verifies if one's own king is in check. To overcome an endless


recursive call, several conditions are verified: First if it is searching for
recapture (w is non-zero) then it marks it as a check. Secondly, it will
look for a check only if it is running inside the search function (not in a
verify check).
If it hasn't exceeded the maximum search depth, then it does the call
and compares the score against M (constant 10000). If it's greater than
that then the king is in check.

85
Toledo Nanochess: The commented source code

Lines 89-90

do { /* Search the board */


_ o = I[p = O1) { /* Read_piece */

This marks the start of the search loop. It traverses the chessboard
starting from the square indicated by the e variable (see line 73) that
was copied into the 0 variable.
The first comparison initializes the p variable which contains the
target square of the move (it is reinitialized at line 179) then indexes the
chessboard to obtain the piece and saves it into the o variable. If it is not
an empty square then it proceeds with the loop.
The other end of the loop is found at line 184.

86
Toledo Nanochess

Line 91-92

q = o 8: z ^ y
_ q < 7) { /* If piece is valid (code in q) */

The content of the square under analysis is read to obtain only the
piece and its side (via binary AND with the constant 15, contained in
the z variable) then it is XOR'ed with the current side variable y, and
saved in the variable q that represents the current piece. For example:
If the piece is 0001 (black's pawn) and the current side is
1000 (white's turn) then it will calculate 1001, so it is not
valid (greater or equal than 7).
* If the piece is 1001 (white`s pawn) and the current side is
1000 (white's turn) then it will calculate 0001, so it is valid
(less than 7).
' Other ignored squares are chessboard borders (0lll
binary).
It will do further processing only if the piece belongs to the current
playing side. At the end the loop will cycle around at line 184.

DECIMAL BINARIO

0 0000
1 0001
2 0010
3 0011
4 0100 Precedencia y asociatividad de operadores
5 0101 de mayor a menor prioridad
6 0110
7 0111 Operador Asociatividad
8 1000 ( )
9 1001 not derecha
10 1010 and izquierda
11 1011 xor izquierda
12 1100 or izquierda
13 1101 -> izquierda
14 1110
15 1111

87
Toledo Nanochess: The commented source code

Line 93

A = q-- & 2 '? 8 : 4; /* Number of movements */

After discovering a valid piece for movement, the program will


calculate the number of valid directions for the piece, and in the end
the q variable will contain the code of the piece.
Entry value of q is 0001 & 0010 = 0000 (pawn) then four
directions.
Entry value of q is 0010 & 0010 = 0010 (king) then eight
directions.
' Entry value of q is 0011 & 0010 = 0010 (knight) then
eight directions.
' Entry value of q is 0l00 & 0010 = 0000 (bishop) then
four directions.
Entry value of q is 0101 & 0010 = 0000 (rock) then four
directions.
- Entry value of q is Oll0 & 0010 = 0010 (queen) then
eight directions.
See line 81 for the reference codes of the chessmen.

88
Toledo Nanochess

Line 94
/* Locates piece movements */
C = o - 9 & z ? q["& .$ "] : 42;

This line calculates the index into the table of chessmen directions
and saves it in the C variable. It is strongly reduced to save characters.
First is the special case of white`s pawn, it gets index 42. All other
pieces get indexes of:
Black's pawn, 38, ASCII &
King, 32, ASCII space
- Knight, 46, ASCII period
* Bishop, 36, ASCII dollar-sign
- Rook, 32, ASCII space
Queen, 32, ASCII space
The table of directions is this (see line 38):
At index 32: -1, 1,-lO, lO
At index 36: -El l, -9, 9, ll
* At index 38: 9, ll, 10, 20 (note overlap with bishop
directions)
' At index 42: -l l, -9, -lO, -20
At index 46: -2l, -19, -12, -8, 8, 12, 19, 21
Note that the entire table is codified adding 64 to each direction to
get a valid ASCII code.

89
Toledo Nanochess: The commented source code

Lines 95-96

do{
r = I[p += C[l] - 64] /* Slide in direction */

This starts the loop for moving pieces. It takes the value pointed by
the index of table directions and substracts 64 to get the offset (note the
trick of interchanging array and index) and adds it to the variable p, so it
now contains the target square.
Then the program reads the content of the target square and saves it
in variable r for further use. The end of the loop is located at lines
178-181.
In C language, it is possible to access an array using
array[nu.mber] Or nu.mber[array], aS both Operands are
interchangeable, because of the compiler interpretation of a [b] as * (a
+ b).

90
Toledo Nanochess

Line97

_ lw I p == w) { /* Simple movement or recapture */

The move is valid only if the search function is not locating


recaptures (variable w is zero) or the target square is the same as the
provided recapture square

91
Toledo Nanochess: The commented source code

Line 98

g = q | p + a - S ? O : I + S /* En passant? */

The program determines if the current move is a valid en passant


move.
If the piece is not a pawn (variable q is not zero) or the target square
plus inverso pawn advance is not equal to en passant's square, then it is
not a valid en passant move (variable g goes to O or NULL pointer).
Otherwise variable g points to the square of the captured pawn,
Note that the C standard has a special interpretation for the zero
value: It can be assigned to a pointer as a null pointer value without
needing type casting. This is a feature first seen in C++.

92
Toledo Nanochess

Line 99-102

Ir
&(<1|A<*||a>Il
(r+l&z^y)>9
&&q|A>2){

This comparison detects the majority of legal moves. There are two
cases: movement to an empty square (tr, that means r is zero) and
capture movements with (r+1&z ^y) >9.
In the first case the movement is valid only if the piece is not a
pawn (q is not zero) or if it's a pawn moving one or two squares ahead
(A is less than 3) or if it's a pawn doing an en passant capture movement
(g is not NULL).
In the second case the movement is valid only if the piece is not a
pawn (q is not zero) or if it's a pawn doing a capture movement (A is
greater than 2).
This complicated expression saves a lot of characters at the cost of
having to understand the C operators precedence table.

_ !r /* Move to empty square? only if not */


& (q | A < 3 || g) || /* pawn, l/2 squares or en passant */
(r + 1 & z ^ y) > 9 /* Capture? only if not pawn, or */
&& q | A > 2) { /* pawn does capture. */

93
Toledo Nanochess: The commented source code

Line 103-104
_rn=!(r-2&7)) /* If eats king, doesn't analyze more */
PG[l]=O, K;

Toledo Nanochess tries non-legal movements in order to detect a


check on king. Obviously eating the enemy's king is illegal (this is the
objective of this comparison) but it can be seen as winning the game
and this is a very good objective, so it cuts the search and returns the
winning score (contained in variable K). It also takes note of the best
move and the P macro decreases the G pointer and switches playing side
before returning.
In other circumstances it allows the detection of a check, for
example, when running it as a l-ply search, which is useful for castling
needs and stalemate detection.
Note the trick of initializing variable m as zero: lt will always be
zero after the if.
By the way, in ancient chess, the players were apparently allowed to
eat the opponent's king, but the game still ended immediately.

94
Toledo Nanochess

Line 105

J=n=o&z; /* Piece minus flag of not moved */

The code of the chessman to be moved is copied into variable n


with an important modification: The unmoved bit is cleared (by means
of AND z) so during the chessboard update the piece will be marked as
<<moved.>>
Another trick done via variable J: It's always non-zero, to indicate
that castling is not valid if the code is searching for check.

95
Toledo Nanochess: The commented source code

Line 106

E=I[p-a]&z; /* Gets piece just in front */

The program takes the piece just in front of the target square (in
front as in a pawn advance) and saves it in variable E with the unmoved
bit cleared for easier comparison.
It will be used to detect pawn promotion (see line 107) and to score
the blocking of an enemy's pawn. See line 127.

96
Toledo Nanochess

Lines 107-108

t = q | E - 7 ? n /* Simple move */
: (n += 2, 6 ^ Y); /* Promotion */

The variable t contains the limit piece for the move. It will almost
always be the same as the origin piece, if it is not a pawn (q not zero) or
the square in front is not a border (E is not equal to 7). Otherwise it will
start promoting to a knight and up to a queen.

97
Toledo Nanochess: The commented source code

Line 109

Zn<=t){

This line starts a loop, which will almost always run for only one
iteration.
The special cases are promotion (four iterations, see lines 107-108)
and castling when it runs for two iterations in order to move the king
two squares (see lines 167-174).

98
Toledo Nanochess

Lines 110-111

L=r?l[r&7]*9-189 /* Points for capture... */


-h-q:O /* ... minus points for delaying */
/* ... minus points for capture with big piece */
These lines constitute a crude first-step evaluation. If the variable r
is not zero then it is capturing an enemy piece, and it gets the piece
value from the codified table. Then it substracts the current analysis
level (so it does not delay captures) and the code of the piece. This latter
trick causes the program to prefer captures with a chessman in this
order:
Pawn
King
Knight
Bishop
~ Rock
Queen
For example, if it can capture a queen with either a pawn or a
knight, it will prefer to do it with the pawn.
Also, if it can do the capture at the first ply, it will prefer this over
doing a capture on the third ply. This simple math makes the program
playing's style more aggresive and compensates for the crude
quiescence check.

99
Toledo Nanochess: The commented source code

Line 113

_S)

This simple line checks if the search is beyond l-ply, then it will do
the more refined evaluation.
This little trick saves a great deal of time when Toledo Nanochess
only has to detect a check and is not interested in performing a full
evaluation.

100
Toledo Nanochess

Lines 114-120

L += (1 - q? /* All pieces, except king */


l[P/x+5]-l[O/:<:+5] /* Conquer center */
+l[p%x+6]
_~q /* Points for being central pawn */
-l[O%:<+6]
+o/l6*8 /* Points for moving out of place */
:!!m*9) /* Points for castling */

This is the first part of the refined evaluation. Por the king it simply
applies a unique score based on castling (nine points for castling).
For all the other pieces it will award points for getting onto the
center.
""'f2 _?rt2:tt{"t' 5 $$-';f{_,,,,o_-
$>`-iiffi '-95552-f' fII=-- =i-_ ;iiSii i i ;Elili51i_.-_*-_{,_____$.-$___.
=i5'Ei}*?i _- -1- _ Ej-22322IE5E1E1I7II1EI1ZIEIEEFE??
_ - _2 , 5 __ .___ ___;:-_.__.._
1 __,,,q';,,,,__,___________________,_ _ __ _
._ _. _ _ _. _ _ ._ ___ __._;. ___.t5't'_,_;____... ._ _ _ ._ <_______ _.
`'_'f''______ ` --'Iii--"-"I-""::-:2;'::_-'I:H=_-Ltriaz-_-t" __-;9;:-::::-;v_:a -_.__'::-;-:-_: ' '-::-:-:-_-:.-:-.t-:,-_acc-:3:-:-1-""-r->'::&:::fx::-'-_-:-_-;--:-::-_-:-:-'-':-;-:-'-_-_;-_--1-1-:-:-:-":-14-1;;`-22-.-'-""tf'f"'"_'fw
:'_: "''_^'-" i r -_ ` _-i:`- -' _-__ :;::`:;:::::-::1:Q::$::..-:-' :3_'3:3:_Cf:::-:>_::_::`:-_-:"-:-;`_':`_-_:-_ .-:-.:-_:f_`_:-:`:_-:::::_f:5':<:` -72- `d':::'::1:::::f:;::::::- 13:1:':::;:-:::::4.2' ` 'if' ,, '
:___:_ -:f'_ " . --$555
_?.-`.f:c-'51 _:';-:::;-;-:`:::`::'$:2:::-13:3". `::?_:-`.3_R'::::::::'-:-:-;-:::_-__ :-:::'::-:;-:-:;;5:` ::ff:I`:i:f^i '_.`<`:::'::::-::::::: '-::':`:`:;;:::::
ftf:_f_f::__ ___:f-__f__ __ " _ L L y ;__:-.:_:';;:: ` " "__:::-:`:_:::`:-:_::::::;:;*?-'32 _'-PP.":?_::7Z2:1::.::::_;:"""'' -11.3:1:-::::::::-F5;%;_':" 13' __:`\:I;:;:`::;l:-:::;_f_:_ _;__:____E____f_I____f__S.tf-l _ f _ _-' _"95-"' ,___
: .a;z; :2_-1 5 = : ';= *_=;f;:z:iz-_-2=;::EiEi-_:::;;aaf_%;;;i 2.2-:_i1;_=i:=___3:='1*:*T' 2:5?; z=2:5fi.E; lf2;22` " MI5f=*=:-EEf?= f :-;: ._:; 1- '
_-: IIIII_I'III"'2`=f:ff -fr$33iiIlf 55'f.II1.If11fIII-f''-fkii gf b '-''III5'III5f'f-f'fIf''Iff"IIfI'
--'1_ 1;-_;:;..-.;:_:::1-_-'-s:--:-gp:-sE:-ir;-:-2-;;:<-g;-$;g$:;-::::::::::-::::-.----.--------'-1;__g_';{'..; -Fl' il' ,_,_;,I"III112__I2..'.ff
_-,;,_t; `:f`f:-f:f:`::::`:`_`:-...`:`:;-:`..
.`
fc'`f:-`1;:`-if;:';`;i:`;'i32:2:::_':}_f::f::j:-::f_1:1_::.11:3::::ifil-`;':"}:;`i'ig'";'ifii;5"3""$:-'::f1:::;`:`:-:-::::::::::`::::_::::::::-if F 'S
*_-_--:'__~-_- .-_f_-.-.-_-,_-_-_.-_-,.-_-_-_--:_-_-_-__--_-.-_-.-.-.-_-:-:::-::::::-:::-::::`ap:-_-ig;f1;_- ' 9--;f'_t__
:-1;'5f_t'i
-_ t- .-:gg -__ -;-:a;<,_:5;:'
__-________-_;-..,;.'
_ _. __;;''';-___;;'-_;-.'-:;.;.;;:-2?-_-_;-5.
_ __ _
H ' ~'- _ = '- :--;' ::':_:::_'"-':1'".:1-:-:-:-:-::-f-1-2-:-2-:-2-H?"=_-' -_-:-'-'-'-' er
p
_.___f__s. _-_-_-_-_; __;_-'._- :-:::::_::;:_:;:_:_:::_:;:;::;'-:;:;:::;:_:;:;:;.- __,-_._ _______
- -
_-
_. *;; ___
Mew?
'__':_'_''_. -
' i* '
:::::::::-::::::::::::'::::::::_
-_-' ,.._._; __.._.;.___-...;___._..;.; _ \ i:-
- _
_ _,E-_ r _.__\
* -_-._ H
5-:
-_\` -_,_..
.f=-_
E=_i_ E===_'=:;i=_ .22=11; ;"";;_'
2-JI.. . "
--

4;
Mi 5-_

FR `*f - *ir ` 1. : _ - c f -' = ;:-'


_'
: : ' : ' . _ : ' : ' = ==-
_
= ; - : ' = ==25 2 =
__: 2 ; ; _ =- a__:_='
__ '
:_ - 1 - _ _: 3 ; f
^
; ; 1 E; E ; 2 ; 2 ; 2 ;
_-I-I'.I`If.`-_'-.I1:11--If2:-2:1-$111-:-;::I:'_.I:I::c$:I_I.1:f.f;f;f;1:1::-;'
; ; = ; = f ' ' ; ' = ' 1 ==' = ' = - 1 1==='
':::::--'-_f_-. z^_:-14:8
= I tarifa
= =i _ '
rtftr -.' _ -P* - a at
3_n_ 2 =2: 2 : 2 : 2 : 2 =2: =: 2 : 5 : . - _ : - = _: 5
` _`^__?.__-ii;f:1:-:1III;1I1212-- IEI-Iifif-_1
: 5 - 5 - 5 - ; : ; : _ :
.if
; : ; : ; : _ - 5 : ,
oa _ _ ~ gr v ~ 2* -3:_-&_:;._:;:-=-
'
>"-_* 12.:1.f'f.f'f E:f
_ 1 4 -l. \ \..' .I _.
;F'_ -_ ' -!_:::I__-1:__.-*_-'az-'c-_-J:-_-' '.a-2-:-2-:-tj-'-gi-_-1-:-:::.-:=-_-:;:_:-'-'-:-' fj';---:;'--;-2;4-1-1-_-A-.i-:-224-:-za -_::,:-:-_-:-:-:-:-:::::::-::-:-::' " :-::-::-:-:-:::::-___ _:-__* -_ '_-'::-::-::::---.-.= -
.f-:-:-_ ' __. -_-~ _ ;.;.;.;.;;;;_.;-;_.;.;;._.;;_.--;.. _@-:lvl:,- -:-:-:-:-:-:-:-,-__-:-:- --_-_-1-~:' -::':':-:..-:-.:::.::- :.-=:-:-:-:-1:4;:-:-:-:::~;-1:-'-'-'-a:-:-:-:-:-:-2--'--:-=-'-.---.-.--'-:--'--'-':-1-1-:-_-_:-:-:c=cf-:-t-!-: _f_;_<f-3 '-'-tj-' :-::-::::-:::::-'::':
W) - ';::`:::_::-::`:-::.'_;":::-''-;;-;'_.-'-*-'.)*i:b`i:':i5'f-23:12?3-':j'":_-f:__-':`:-::-2;Il'::--$:::::::%i$:5it ilfl-:`:"""_I''''_I_'"""'1.3.:222;$2-:3:`!:::cf%R:_3:1:'_:`:`:':-::`::-::-:'-::-:-':____-
===ris;fi_.;-,__t-,r=* 5
'_-fl.\M.v. Jiw.
:5:=:;:;: _: ::_:'=-:_:_=:'-;.i-==;:;i2-.;==-==2;. _ _E_
H---" " Jwau. ..'-..__'__._.._'.._____ ___. __ __
;_;_;~;_-_-_
__ _______________.-.\_.._~r...)__-___1_..'___._:.. __ __ __ ________._.-_._.__-__._;.l.;.__ _.?.w
:;:;:; .;..;-5.=;=;=;:.1-f:;:==;:_:;:;:_:_:;:1';:_:_:_:;
;.. Imwz __`____-_-._ - 110-'
_-_ _ N32@ J;, __._-;____- -;._ __ _ -1.__,___-.vu_-._v._\..____,,__u_. - -_ _. -_ - __ _-__--_-1.-.-_-:5l_-_~_-_-.-_-_-.-_-_-.-_-_-_-;_'..'_-.-_-.__-_________..___-_-_-__-_-___-_-_-_-_-_- $2 _-
-- _-1995;;_5;::;ssx-:;;::-:_g'1::-tj: "::::::-:::::.':-::15;-$2-:-:-:giga-:-:(145-ia-:-:-:->:-:-_-:;<-:---'---'--'-----:--'-:-'-:-:-.-'-:--:-'-'-:-.-'-_ f-tf 1. Hf
1 'ia

'-:1.'..^'....1*::..::::'-:3-' - rr 5' ig'-I-III--'I..-:1'-1--_ J.:__-:-:-:-:<+:->:-'-tar:-.a-gi:-:-3:-a_-:1:.-'____::_:1:_::::.."---2-::::1:-:ratr::a::$::$:cj;:: f1.11?:1-11--.r--_1-1*~--P-_q,, '~


___.;;1- ; :::::i!;-::::'-;;"_---.__-:__$12Efr;-;:q<:::f,;;_;:_y5 " ' " ' "'"_""'""'_'"g:;:;:;gg.;::;:;:r:: :::::_::_::;::::-:::::::_::
--`3":':if----:ff-C-fi_ S ~/. H f\=__`-`_`-"' '_f`-__73:;1i_`:"::_`:::?' _::::-:'" :"`:;:;`f:`:`::::'__. ";:'::f::::::`f" '- "-
:-:-::-:-:-:_;:-::- __:-1'::-22::-:_::f::_ -fl
. '5__`2-.- - : ' ' _-1;;-_-;::;>'__:_____ _`"''-'f2:':`:-:::::1::f.:}: ':;:`::::::-:-::-:lffi-:ii_ii__pi
':::".:"-'-'"'':-:::::.;'_'- ` -'
\(. _ _',;_$- -- _ .
_ _-_ __-:I 1'-1:1'-_-::':::k;;:::$i:1:___Eg:__-_;_-__%__;_.;
_'::-`:;:-_i,-:?_:l_-::-::'::::::-:'::-: _::::-:::::_&::f:i:___^_ __;:i':_`f_5-t5'3R:_''_____'_ '_'__'l;__ ' '<
_ --.--
_ ___. _-_-.--,-J.-__.-_-_-.y'.-_ _ _ - _; f,^ 7 _.
__-_-I----`-_-_--_-I-I-`IC-._-*_-Iu1"-_".-.zi ,__
'-_-_1;1'.- $1-~.~.
2'..-..LI-I-IHIII-III-_ __-,I-II-II-II-I-I-I-IE
:1:::_-:I::':-:-:-:-::'::-::?::-:-:-::_~ _,,__
_ ' 3? -' ':;:-.-_ ._ ';';-_;-;'_: '-';::-_'.v_'-:'.__-:gas:-1;:-__,__ _
-_--_',-_-_-_-_.-:_ \ 4 1 - I- I

__-1;:-::_:-:-:-:::'_::?::-:-;::::::'::::: __ $5. .\-_-.-


HK _-f
me .-_-$-_- ..-_
_ -:\:-.-.-::'::;-.-'-:-:--:;:; 1-'.--f-';:&:;q:9::;;f.g:1:;;;q;qq -:_';_:-__-:_;_-___:-.:-:_;;1;:_:;_:-3.;_;::-' ;;:<-:-:-:efi-:-:-:-:;:;"2-:-:-2;-:-_-:-:-:-.-:1;--;--:-;-.;-:::-:::11:1-?::.-$23?-E-G
--fac-='-:-'-:-:-:=\:-:-:-:-:\\:c-:-:c-:-:-:-2:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:::-:-:-:-:::-:- iii" _ ii; --*.ii'
2- '15' 2-tf
-1
~ r: ~*-_r~' _'-f ;-:_:_-ita-__f_--_-f=:_;_;_;_;_;_;_;-___;_;;_-_-.;.;.;;_-_-_;.;.;;;.;._;_-_-.-_--_-_-_-----------_-_----_-_-12Q5:87;R21Rifc52`ta?.f!'-iii:::-::_:::-;-::::-:-::::-:-:-::::-::-:::-:i
__r====t_ r=:a=;f:=ar=:_ ;=t_=;$f==i=?22:25?;; ??;;z?2;' ''-fi'
'":<-'~' H.._ 9?:::::::::``;'
-:f *' 5'` -- 'F-
_/ ;- - -;
F2-__ ff,;;'
f -'
S.` __ __ __ ____w_.-11..-_,;_;,\ a t _ I. 'ne 4;.- r -_ -- - -- -
\ _;::-:`:::' '::1:f:1::';:::1:1$$;I:2:I;:3'""`ffIII11" -1-III-111.51-'-'-"'Ii _-fififiF1-1-IffE$E;E5",,iI$ii$i--5""`-f''E--{' -_'->i 5 T .- fii i-11'--I1_I"_'"1-'II_I_1-.-_f`
:5_@_ W" 3 f ana-355'== ~-_ qh
_-_
1_ .-l_- "~IIII1;2'
-:- :I2';Z;II`f$'i'ij':-;
__ - _ - .___.._-_":-_-_:-mi-t,
._ _._.,._._:._._._
itfiiiir _`_ `:'-:;::::: -_-__--_-2,.-_?.
__
'c7::::::: "2if:'_'':'i-'::`:::-:-:-::-::':___
-
_f__;:__.,\f_._,,____;_;;_;__-_._-
-:-:-::::`:-::-:::-:5:-Ff
__ - - '___-_______
-

- iiiiflii-_ ;__; ;;.;1::;':2;:_:-;'2:1';;:;';i:~fi:1'-:-_-:-_-_


ar-_-'-2'_:16;-
'l-xu
-.-:f,-:-:-:-:-_j -:%-:-:-'---_-11_--'-:-_-.__--:--f".-_-:-:-:-:'-_-__-::r`.31:1:-:t-_-_ ..-:`.r_--:':.:':-:-:-:'::-::::':_____-:I::-:::-:::-:':::::1"$f
`
_..___..______._-____;;.__-,Q_-_;_-_!5:,__,=__-_;___;_;__;_;;;;_;;;__;;;;_;;_-_-_;_;_-_-_;__;_;+5;-__-_=-_;+__;_;;__;;:\.-___-_-__-____-_-_-_-_-__-___..-____-_-_-_-__-___-_--gh-_-_ \3g_5;_}_f___;_-_-5
:=.-.=__ -: j\';_ _-.Sf
_
f _,_
f.-
_ __
`%-= =*~ ';_:~.~*-4
$3' --;-'--"- -- 2;-
a_1*`i_2
: J
2 -a_fa%_'. %~ _ea_;= =- ::::I:::::::I::::'_:;'::_:;-'_:::"(W'__.- :af_w_;L_ -_-:t-21;: 1: 1__:_-:=__:';__:-___-:_'__;; 2::-Qg;:;:;::::;:;;:g;.::__g:;:g5_:;:;:;:;:_: :;:_';.:;:_:_:-:;:;
FF 'F * mi *-t;
3%~$_.F" b_."C-`;'
`1'Ck"_' _:-:_:;:-:;:}_;_;:+:$_F_'$'i_$_ -i ;:;:;::;:;:;:;:;:-:-::;:_:;:_::-:;:;_;:;:::-:-:;:;:_:;:

3135:::`:`::7:'_-:::':::::::-::-:::f:-:::'- _' it???-'la "_


"A", "*iw*&f
_-* ":-'>> .tv _- ._ _ _-*--_ :_-_-_-__.;._._-;-;-_-;.;;-'__=:-:-;-;-:>":"`f .f''.-1 :".`f1`1f'::`-:'r':-:-:-; ';-;:-.'-_-. -_-
'-' 43313:":-2'..*:"`I`:`I":' --- 2 :cr-_,'-,*_;5::3 :f,f_1i3i:1:2:1$:::'12I_: :I`____:_: _:: ___-_-_-_'_-_1\-2-_y_-,a-_-,-_-_-_z-_-
\ `:-`:-.-:`-:" '
:f::''-: 'it'-1-'-'51:7:::-:2-:-:<-:--_- -v.-_w.-_-_-__-_-_-_-_---_-_-_-_-_-_---_-_-_-_-_-----_-_-_-\_,;\\\.att-.-.':.;')_-_'f
:-.=::'-:.f:-:-1;:-:-:-:-:-:-:-:-:-:-:-_-:-:-'-:-:-:-'-:-_-^-_-:-:-:-:-'-::-:-2-:5--5':-ae:-_'f'"t-~;f 15.;
'z-_:r:~>
' _; - _ '.' ___.-_u_.___-_-_-_?, .;_\ _ _;-J.-_______ .;.
" ` "
'''3::.:;::::_:.:::':::::'__3;-__, M"0 ` ' ' f" _' '>' _2"?"" " "'
1' ::f;;`;_:;:"_f_-ii:-:-:-:"'-:-:" '- "'_il:'_':$'$$_'2;':'*5:2;'
t-__ - _ -2- _\i'"J::::-:::.__:'::-_:-:.:;-;:::'-":'-::`~"'
_ _ " " ''
_ 5:1._:::3:-:-"::::::_-5i:'_'::::-:ff:ff`:ff'-f``:`-ii'if2"i+F`i`i-:-_o-':~i`3
;1;z; ; ; ; ;a:=;'_:_:'-=ga:z; ;; ; =;_; ;.; ; ;.='g_-<<gi;z:;:-:; =; ; ; ;2;a._-= :_:___z;=;z-:;:_z__-;_;_zg jt ` _i3*i`
.:::::-:;:"-"
22-aa;-5-2;;:._'::-:::::_:::-:-::;F$$_-$.~F$=f
f-_2zz:; .f-22;-gar ___;*'_<",rrr~r _/
' __..'f"" 1:;-'
` R ' fi_. _-__z -_.-W .-__:-:-::-
___?`?':_5.-
===;gaga=;=z-z;-1:=;gaga;;aa;;=_z;f;z=t;____
_:_::-::_--_ ::l;'l>li{'_#.:;-
__ . . _ _
_:-_:;,\g:;;::;;r;':.:::_:c_:=:-__... -___:__:-:-:-1_::-:_:_:::;:;::5;;:::5-Y-_;:;g:::::;;::
?'^""
_ :::1::-::_.:::;::;:-::-:-:-:-:2:-22125:-W f $4 .41-.-____...-._-___..._-.;;;.;;;;.;;;__ y'F-c
_1- ai: F _ '-' _-_::j`:-21.-._1---5;---._:-__.;-:$$l_);;2'.\_.'-____':_1.4;-':-'\"" _j._. __."_ _ _ _ _ _ _ _ _ -__;_;_;;_-_;_;_;__.;_;.;>"'"c";"^r.
':::::::::t:-::-:;::::;::::-::::::;$FiF$=i.'FF F ;$_F.-25- 'f_;$F'-2:::;:-:-:-t_::_:-:-::-_____;-_.;_-:. ___ _ _ _:-::-:_.:.-:`-..;_:-:f_-
:.f:-_-.:--:- _ _ _ '
"1
,_f_
__' __; _;. - - -__ _ _ _
fa fr 3'" _;_~,;===-;=;.-:-'.-i.====-=.z.2;:;.;.;:1._.;:1;2_;_2=1f:=1ifl2;2;2=;=;?:=s2=;==s==2z_
_.-_-__;___- _ ;.;. ___

-.--:-:-:-::::-:::-:-::-:-:"-:-:-:::::':-:-:-:-!7$FFf"'4Rf$F'
_ _ _-' _PP$FFi$1-:-:-:-;:-:-:-::::-::-:---_-^-=--.-:-:-.-:-=:-.
*_-^ __ __ _ _ _ -_'_- "' :-:-:fr:::^:.`:-.-:';:-:-:-:-::-:_::;-:_::2
-_ _ _ _ H _- - - '--f'-:-':-'-'$15 I-':`f-'<-:-'-''-+:-_:-::-:-
_~*-f
1.-:_:_: :_-221:'-_:_'::-.:-;::':I:-Si-2-2-H-2121:-2-'>$':~:"Fi-:F"`F:'-11":-:-:-::-::-:-:-:-:-::-:2-::::_:'_:::;':::__ < _ te = .a ri.. aiii@_ _
"-" _ '1' 5" 5.-~ "-'-:`:-:'-^:`:-'-::-:''-:-'-:"::-"-'::':: "'''-'-''"'-`.'-- ri- 25 -fi"'5"<-''Z'-22-:-\'2-:G5:
==:;--,-'
2:_r~f_;----=---5-5:--1---1--'
=;=1ta1r2_-2f=:2-=. :f=a--=1-1-1-2-1-1-1-fi
1
:=:=-;:;: .;=;:z:;:;: : _-:_1-1?1-19-11-1-1-ff191-??1-ae:rr:-;ti
{
=::__;;:_:;:;:_:_:_:-:;.: ;: : :f+._-na;-= -<-r=<s-1-vr-+a:1s:-5-' ----'-ff'-'-'-lifii'-??:if:'?`?a-~`= *ai-1 '
_1;2122252222.11;;.;.=. . . . . . ii
1- 1 Hi
_ ' E-'%`''f''I?EE'%_
f__2Ei: ~-1 .-if:
-:'_ .*i3ffii:?.':'i;'f-'-'t;".'?7;'_';';'-
_==;=_==____;_;,_;. ___;__; ,\

; ;i_E=;;E=E;E1E_EE;E_E;5EEE'E'EjE_5j5-Efi iitift itif :_-C13;-5-515;;g5515.;5555;-513;;-5;5.5.1;-5';-; _ FEZE-


_ E-EEEEEEE-EEE-E-EEE'E'EEEEEEEE =;''i i "-I='1-;E_EI
_ _~-_:-f. ____'__'''"_:I
--P`-:_.. -5'._-.LW
::::<::""J&$F::F3:F:____::::;:""' `;:_':'':___:j-Fitc-R4- '_--'S' -.__'-',ri.;__.':'::`::::;:':::"` `::'::::::`:::-:`:; ' - "'_?_-."-5_:-ff.-5.73-1:13'
. -7"".<.: ':::':::`:
_ :::::2;:;:::;_::::_:;:f;-;_: _:f::2:2.'';:_::{'2__F:"'"'::" -"j1%1;;::-:`::::::;`:: _":_::_:::::-`:`:_::_`; -e *e-_mar*-te ea* . _'::'f'''f'` f'''f}__ W
,.*'-:'_.:<'_.':.%
__
"-^%.. :::':_::;:
ff="-iiattiE555555;E;;E;I;Z;E1E1=-':- _';E; ; ;E;2;;E;;E;E; " ';_ W *JE1;r_EE-E-15-EFEE EEEEEEEEE-ii;_-_$ff'$+! _ _;__;* jej-_;5rr=1frf=' '---rr-:r;_:-'ii;iv:t;+;?;;- ;1fEEE_EE-E';
_ _ -' ' -
$^`::::::::':_ _-_:!:-f::'_::'$$"e:-:-;:f'=__ _-:FH 1 --$112-11!-1%-:-_.. --:-;;+:-\:-"'-:<-"----_-_-_-.-'-:-::-_,-__._:-:::::::-
5 W _ - -:-'-'':"--:::"::-'f:-:-': _ _. _ _ _ _
sin
-' -- 4 i
' _/.-_ '_'__- \ _ __.
-ti - __ :_::::::::_::_:_::_:-:;::_::_:::_:;:-::-II;
.\\\\\\ \ ' .
:-2:2.:-::::::::::::.::H:`:::::::: (__
'
"
"_
'22 _ .-;;_- '-1:'
_ 5-
__
H
, --; ;
*>'; ;I2;
:J - - ^;.*"H"""t""`H""'W::'--'::-' ^
'\"' "_-\"""'~\''r1- __ `_ J_
"
_`__`:-_ `-_'123;-`?::3:'::':
i -
_. __-_-=:- :;:_:_:- iaaa=zi:a: zaazsazai i-5-_:f=;5-;.;.;=i:;:==_:;=.:f=z:_:;=;:;.;=;:=:z=;:=: ;.;
^ '~'"2fIi)':`'"`i525If5::'::`::':-::'1:-:::3:-:`:`:`:::::-2':
\-Ln-C'_1u,-..\_-ul.uu--- ----.;.;.;.;.________________:_-_-_-_--__-_-___-_~_
"`:'`7f`-`:-:-:-:-:-:-;-:7:-:`i:12::-::-:-::-1'-"-Iii""-9BH'I;-W:::-:-:-::-_-:::::-:_-'--.-----7`---- -_"'-W'-7' -T-5'--'E-_-25.-'M' i'-11151-"I-;---_-_":' 'f 7- _-_*-`-*'-L '-`':-`*+:: '+28-I-I--'-2-\` 'f'__._7_-I`-'-`-''"-:`-_ _ _:_:~:-:f__f -'_ f
1-::-::::::7;`:-:':':::'::-:-::':'::-:`::-:`:-Hif -t -':`::`:':`:::::::`::"''f'''f'-`::'f'*?$Z- _ _':_$1_;_`:`:"":-:-:' '-;;*` 1- 3.313-1.3:i:::$::i:4i:''''':':'5f:i:5
-'--'-~----:---'-_-'::;.^::::::::-1: F3-t-t+f-9 '5"__;.\. ,-1 ;_-:-_--::__2-;-__:.-;!:___ -.ct-_ -_r-:c-::-:-_c-;-:-_>;t-;;._-_-';';' ;_;_;';:;_;:':;::_;';''--'-'-'-'-'-:-2;:-:I-'-:'^:-'-:-:-.R-2-5:32'-52--`{-F_'R
"2;_2_;_;_;_;_;_; 2=;; _; ; ;_:;_a_a.___ _
__ __
_ _ ______-_-._____-:;___
_ N

_x__;_ ~
__'_f_:_ '_f::_:'''____":__j_'
G .___ 'lr _ __
5, __i~_..__-_f__\1_.
_ ,-2, _-_P_'__f'_ _:::__-"
_ _ '

_:_:_:::_:::_:_:;::-: _-_*
_ fr " " '"' "|*|-- _.
_ '32 _ _ _'- 1-|"|-H-'
R-_"-` _- - %-(__ 7' _I::`::I:`:`::::" _I-:::_::-_'?
.___ __
"| \-'- JJ-'\-'-' -'--'-'--1-5
- -\U;._, -L--_\'_-
__ gm 1-- 3*_* - _, -lt.' 4'_, `_-_`I` ._ 'I-I'I2';I"`-'::--::I:7'';_
-_ .Lt (--_ (H. _7:f2f`-`;_::::5::l
* _s_=- -:z-a_-1__-_;_-;3-__;-I5_:;'^;_=~_r2e22:
,, ,_r22=5=;_ 1=*` _ _______'___. _ _
;-2-5;_;;;;-5;;-2-;5;&;2;t<_<'-li`-'.3 _ r."-_tii 5
:_ f: f: : ':':=='r..___`_`____
<.t2*'f~;==_;- _-__-; ____ _:.II'II.
:t*:t_=>_ -:___ fr___
f':ia=;=;==a==z;:;:-a;,=_=;=z:f;': _:-:=: '::':___::.'-:::_
==:: -: ; : =:as.-_''>>'_I--I-Hg-22353-3-2;'2-;;;v/_=--;-1" __;
J%t
t.-,;f; _t;~*i_:;=_=_:_=::_=;=_==,._ 1::::::_==s-:;--___,
':=:;:':1:-=::=: :-=_:':_:-':.:;:';
-=-22-=:ia-_ar;
'
t f al-_1<t
= 5=a2=.
r 1
~ /_,,___
.___
_ . _ : _ : ; < .
_*-ii "` z;;.;a;.a;;;;*'
_;-~'v-;s;:':;f-3f
._ -=;.;&;.;=.;-:;._;;gl
._
.z:;:;.;:;:;-5:;_._._._._:_:_:;:;.;5:;-5.2-;:z:;-:ar
s" `
M
7'-F
._..1:=.t:&t t$_:
_ _ 9- -_''*i"E$f_$"=
_-_'-;-:_-5:-:-1-:-:.;.-:c:_:q:-:''-:-_-_-;.:;:;:;_;:;.;:-:;:-::;:;:';_;:;;-:;;;:;g-_S_',_4_-._
__ 'I rr?,
-:-:-:-:-:-:-: -:-:-:-:-::::-: *E3 gl- ' :::-::-::'-::-::::'-----.- - -_ ;-_ "";:'- 3:- "='.&:-I- _ -_ --3.-_ -'S
--1:::-::-::::f:::::::-:-:::"`:':-::`:
_____ Si- _,'__._._.__
__,_ _____;, F tt' ____. "- _,___,__ ::`::':`:':::::":':`__"_`^`__-i-ft-'
__ I'" ' ' -~ --39'? `.i-f'-7::5.323*':::::'312932323:-258.-ffiiif':''-ii:-_-__ .ii
._ _w_--_- _ _-_ ___ ___. __ _ _ _ _
_ _ _ _ -_ ___ - -Y-_-_-'-' _~.-i~.';',', J.--v '
.-_-TW -'---_-' i'_\-'_"f-f-`.f_\.\_ _ -_ __ ___. ______________-___.. _____________.-__3.3._______.___3._____
:[:::f:3:R:5:8:E1235:: ::;::::::5:32.ffff:}'2_:f::::f:::::f::::j13:;::'_1i::?.f?}_%F,'f$$'f:`:'I1:':`:-:':::::':::::::::'':_:' li R' ' ::'::-::`:'31"-::::'_:':::_~:":::' "_- '-3_::::-:5::;:;:::_: -_'_`: ":f_:_- 11:
_---\_-:-:-_.;;;_;:;;-:-3-'-'-3:-g::-:_g::;.;_-.___-_-___-2__-_;_;_;_____:;_,;_;__-_;_-:;.;_;_;_;;:;'~'-'-.;..; :;- ,__,;.'.;;:';:';:_:;:;;-:;:;:;::-:-:-::-:-:-::-:-:-:1;:-:r ' '-:-:-:-:-'-'-_-:-:-:-'-:a-:-t-:-::-:-:-:-'-'-:-"-':-_ 1;'-.ag -_-~ _ 2 _:_:_:_-:_;;';._._.::__:;
___.__3___________,________.___,_______._>_,___ __ ___...-_w_\__\;.__ 25-'-f_~ _ y
JL;
__-' "" *j _ _
__ _ -_
--__ _- ,--'w
1':
J',-,-:-1
"" ":5:3`c>J::"` :-;. :- 1-^' :::::-':`:`;':`:f`"5t::523'f1I;?`If' __-FE;-.lf''-'WR'-l:::'_':_:__":` '_':'''_' -aif
w.;J_4_4__-,._____ _ -
--_ 4 _- '-_i'
_-_'-'^_-A -_ \~_'-:tri
- _\:`::::`:::-:::"'-'" _:::::::::::t:.
_^'/ - _$ -
__ " _-_,
-'35
g -'J,:__;_-__; 5;,--'_<_;.-1-_;_;'-;:;_;;;'_______;;;';;;;;';;_--3-'-:r1$?x-:-:__ :p`:_~g_4111-:-:-::-:-:-::-:-;:-:_ __-_:-::-:-::-:-:-:-:::-: _ :+35 _ _ 5-n_n?. *J *
_' ...
__ :_-:_ _._ _ :-'_-_--:_______________.________.___________;_-.;.;.-f._;.g9l..
_ ___ ______________ -_\j_3133-v-l.3;_;__;_;_;;_;_;__;__;_;_;_;_;__-_;_;_;;_____ ' '__f., :_ $_f.$" . ,Q
__ ,___ __ f " :-i
ilW%_ ~

f_`f-.rgg a-
__
M _
.--

*HW
--_ _~-. _A9%-~--2_
-_' :-~.- _-:-_
l____
_

,m ma _- _-_-_-.'_ -.-.- .gw -`_^_----_...


.-_-_-_-_-__;.-.;_;_;_=__-_-_-___-_-_
_ areaea
e mmawemarm M V-am%F_,_%
___"

Eight points are scored for moving a piece out of its initial location
(o/16+8) and extra points are eamed for moving a pawn: No points if
on either side, l the second and seventh column, 2 on the third and sixth
column, and 3 for the two center squares.
The extra score is calculated by multiplying the target square value
by two, tq is l for a pawn, then the two -~ operators convert it to 2.
The extra value is substracted on line 124.

101
Toledo Nanochess: The commented source code

Line 121-126

+ (q '? O : /* Scores pawns */


!(I[p - 1] ^ r1)+ /* Points for left partner */
!(I[p + 1] ^ n) + /* Points for right partner */
l[r1 & 7]* 9 - 386 + /* Promotion */
Hg * 99 + /* En passant */
(A < 2)) /* Points for double square */

This is the second part of the refined evaluation. It only pertains to


pawns. The first two expressions verify the squares to the left and right
of the target, XORing with n (same pawn) and by doing a logical NOT,
one point will be awarded for the presence of a partner pawn (see
section 4.1).
The third expression adds the promotion value of the pawn (using n
final piece). If it is not a promotion then it will not add anything.
The fourth expression adds 99 points for a pawn doing an en
passant capture (see line 38).
And finally, the fifth expression adds one point if the pawn moves
two squares ahead.

102
Toledo Nanochess

Line 127

+!(E^y^9) /* Points for blocking enemy pawn */

This is the third and final part of the refined evaluation. For all
pieces the program will award one point if the piece blocks an enemy's
pawn (see section 4.1)

103
Toledo Nanochess: The commented source code

Line 128

_ s > h /* Normal analysis */

If the current level of analysis still hasn't reached the maximum


level, it will analyze one more ply.

104
Toledo Nanochess

Line 129-130

||1<s&s==h&&L>z|d){ /* Recapture search */


/* If in check do a further ply */
If the program is not searching for a check, and if it's at the last ply
of the search, then it will search another ply if it captures something or
if the current side is in check. This is a crude but effective quiescence
verification.

105
Toledo Nanochess: The commented source code

Line 131-134

p [I1 = nf
/* Move to target square */
O[I] = /* Clean en passant and origin square */
m ? *g = *m, *m = O /* Castling */
: g ? *g = O : O; /* En passant */

These lines move the piece to its final square. The first line puts the
piece in the target square, using current piece contained in n for
underpromotions. See line 96 for the target square calculation.
The second line cleans the origin square with zero using the result
of the following expression.
The third line performs the castling when variable m is not NULL.
Then it moves the rook from square m to g, and cleans the original m
square.
The fourth line does an en passant when variable g is not NULL. It
will remove the captured pawn. See line 98 for details of en passant
detection.

106
Toledo Nanochess

Lines 135-140

L-=X(s>h|d?O:p, /* Calculates recapture square */


L-N, /* Actual score leveled to zero */
h+l, /* One level more deep */
G[ll_ /* Best move of enemy */
J=q|A>1?o=p, /* Calculates pawn for en passant */
S) /* Analysis deepness */

This code does the recursive search. The first given argument is the
recapture square, which is 0 if the current side is in check or the current
depth is not the maximum depth, otherwise it will be the number of the
target square of the last move.
The second argument contains the score of the move leveled
towards zero (current move score minus score of current best move) for
the alpha-beta cut.
The third argument increases the level of analysis, otherwise it
would never reach the end.
The fourth argument provides the origin square of the enemy's best
move, this accelerates the search enormously.
The fifth argument calculates and passes the square of the pawn
available to be captured en passant, the conditions being that the piece is
a pawn and it is moving two squares ahead.
And finally the sixth argument is passed unchanged, namely the
maximum level of analysis.
The score retumed from the search is substracted from the current
score to get the net score to store in variable L.

107
Toledo Nanochess: The commented source code

Lines 141-142
!(h || s - 1 | B - O I i - n I p - b | L < -M))
Py^=8,u=J; /* It is a legal movement */

This code manages detection of legal movements:


- Level of analysis is zero (h).
* Maximum level of analysis is one (i.e. s is 1).
- Current origin square (o) and provided origin square (B) are
the same.
Current target square (p) and provided target square (b) are
the same.
- Current target piece (n) and provided target piece (i) are
the same.
The score does not indicate a check.
If all the conditions are met, then it returns, but the current side
(contained in variable y) is unchanged, and the program updates the
current en passant pawn contained in variable u.
While running around enhancing the code I was tempted to change
the name of variable p to g so it could speak <<boing>>, but <<boinp>> is
nice enough. :-)

108
Toledo Nanochess

Lines 143-150
J = _ /* It is not the king... */
D>*Q A \1|- /* ...doesn't.moved one square... */
lm /* ...already castled... */
`| !s /* ...it is on verification... */
C1 /* ...it was on check... */
_r /* ...capture... */
_ o < z /* ...already moved... */
| V 0,0) > M; /* ...it is in check now */

These lines implement the first part of the detection of a valid


castling move. This is a very complicated chess move that only can be
done once for each side in a game. If a castling move is possible then
variable J will contain zero.
Current chessman is king (q is 1).
It is moving to the left or right (first two movements,
A>=7)
It is not already castling (beware of recursive calling).
~ It is not searching for a check (beware of recursive calling).
- The king was not in check (d == 0).
The king is not capturing a piece (r == 0).
- The king hasn't been moved. (bit 4 set, o >= 15).
- After moving the king by one square it has not been placed
in check.
Obviously this code consumes a great deal of space for a movement
that can be done only one time in all the game.
Notice the use of both the binary OR and boolean OR operators.
The binary OR forces both operands to be evaluated (so it is slow) and
the boolean OR does a short-circuit evaluation (if the first operand is
true then it doesn't need to check the second operand) so it is faster,
although with some processors the generated jump can be too costly for
the internal pipeline, especially if the expression is too simple.
See lines 167-174 for the second part of castling detection.

109
Toledo Nanochess: The commented source code

Lines 151-154

O[I] = o; /* Rebuild origin square */


p[I]=r; /* Rebuild target square */
m ? *m = *g, *g = 0 /* Restores castling */
:g?*g=9^y:0; /* Restoddres en passant */

These lines revert the chessboard to its original state, target and
origin square.
It also undoes castling, repositioning the rook in its original
location, and restoring the pawn captured by en passant. The chessman's
code is restored using current side variable y.
See lines 131-134.

110
Toledo Nanochess

Line 156

_ L > N /* Best move? */

This line takes into account the move only if it exceeds the current
best move. In the source code you can see also see the commented-out
line 157, which checks if the search is at the root ply, so it can choose
randomly another move with the same score.
The random selector was applied in Toledo Chess l, but it lacks the
call to srand so it always played the same. This was corrected in
Toledo Chess 2, and it was also used in my Tiny Chess JS1K entry for
giving a great variety to gameplay, via Javascript's Math _ random( ) _

111
Toledo Nanochess: The commented source code

Line 158

*G = o

The origin square of the current best move is saved via the pointer
G, so it can be immediately available for speeding up the upper levels of
the search.

112
Toledo Nanochess

Lines 159-161

__S>l){
_ h && c - L < 0) /* Alpha-beta cut */
PL;

Since the code is multifunctional, it has to check the value of


variable s: If it is zero then it is looking for a king check, if it is 1 then it
is testing for a legal move, An alpha-beta cut would obviously harm this
verification. For historic reference, previous versions of Toledo
Nanochess didn't have this comprobation, so in some positions it would
allow the human player to place a king in check. If you are curious
about it you can download these versions at my site.
In all other cases, the alpha-beta cut only is only done when the
search is in ply 2 and onwards. It checks the previous ply's current
winning score and substracts the current winning score of the current
ply. If it is less then it means that the move is hopeless and returns with
the current score, since there is no need for further search.

113
Toledo Nanochess: The commented source code

Line 162-163

_ lh)
i = nf B = Of b = /* New chosen move */

If the program is searching the root ply (th which means his zero)
then it will save the current best move in the variables B (see line 46), b
(see line 50) and i (see line 47). See explanation for lines 205-209.
lt previously checked that it's searching for a move (see line 159).

114
Toledo Nanochess

Line 165

N = L

The current best score of the move is updated. Variable N always


contains the current best score. Note that in Toledo Nanochess all scores
are relative to the current position, there is no absolute scoring.

115
Toledo Nanochess: The commented source code

Lines 167-174

n+=J|| (g=I+p,
rn=p<O?g-3:g+2, /* Get origin of rook */
*rn<z /* Rook already moved */
lm[O-pl /* Possible third square is not empty */
|| Itp +=p-01);
Although lines 143-150 tested the first part of castling with a
verification on the king, now it should check the rook.
The n variable will be incremented when castling is not valid. This
little trick allows the king to move two squares but only in this loop.
The program first checks that the king can move legally (indicated
by the J variable) then it calculates the destination square of the rook in
variable g and the origin square in variable m.
Eor the castling to be valid, the rook must not have been moved
(*m>=z) and the two possible intermediate squares must be empty.
If all these conditions are met, the variable n will not be
incremented and next time the king will move two squares (note the
code p += p - 0 to update the destination square).

/* Second square is not empty */


/* If no condition valid... */
/* ...king moves two squares. */
/* increase piece code */

116
Toledo Nanochess

Line178

} Z lr & q > 2 /* Keep moving if queen/rook/bishop and empty square */

The search function will keep moving the current piece if it's a
sliding one, such as a bishop, rook or queen (q > 2) and the previous
destination square was empty (tr)

117
Toledo Nanochess: The commented source code

Lines 179-181
/* Return to origin */
ll (P=O
q|A>2|o>z&!r /* Verifies pawn advances 2 squares */
&& ++C * --A)) ; /* Next move of the piece */

When the current direction for the piece is done, the target square
will be reinitialized (0 value copied to p).
The loop will end when all the possible movements for the piece are
done. A special case is the two squares advance of pawns, as it checks
for it and exits if any of the following conditions are not true:
' Chessman is pawn (q is 0)
' Current move was one square ahead (A <= 2)
- The pawn has not been moved (o > z)
The path is not blocked (1 r)

118
Toledo Nanochess

Line 184

} Z ++O > 98 ? O = 20 : e - 0) ;

The search function will check each square as it increments variable


0, looping back to the beginning of the chessboard (when 0 > 98 then
0 = 20). It will end when the origin square is equal to the starting
square of the search (e == 0).

119
Toledo Nanochess: The commented source code

Lines 185-188

PN+M*M&& /* In /*._.*/
quiescense search and without recapture... */
N > -K + 1924 | d ? N : 0; /*
/*Detects
._ _ stalemate
*/ */
/*/*...*/
... quiescense search returns 0 */
J

At the end of the search function, the value returned can be 0 if it is


in quiescence search and a capture was not detected (N == -M*M, see
line 74).
Or if the score signals a mate in one ply, it will verify if the king is
in check (d is non-zero) to detecta stalemate or checkmate.
In all other cases, it will return the normal score.

120
Toledo Nanochess

Lines 190-192

main()
{
/* srand(time(0)); */

Here starts the main program. There is a commented-out


initialization of the random number generator, which is only useful if
the random move selection is activated (see explanation for line 156).
srand() seeds the random generator but it is important to use a
different number every time, so time(0) does the trick. Some UNIX
programmers also like to use the non-portable get:pid() (i.e. the
UNIX process id. which is never the same).
By the way, in the first version of Toledo Nanochess (available at
my site) the function main() contained the code of function x(), so
main() got a weird calling sequence, some people (around
Feb/ 19/2009) at comp _ lang. c thought that it was scandalous. :-)
The C99 Standard (ISO/IEC 9899:l999) defines two common
main() start sequences, but it says it supports other
implementation-defined manners>>. Most C compilers allows any
definition for main, though some will give a warning. In particular, the
environment of Cygwin C compilers fails with recursive calls to main,
so eventually the recursive part of Toledo Nanochess was relocated to a
new function x(), and it even saved some characters (main uses 4
characters, X only one).
On the other hand, some purists could still be disturbed by this
simple main() declaration, because it compiles as int main( _ . _)
instead Of the Standardized int ma:_n(void) Or int main(:i.nt
argc, char *arg[]).

It's also interesting to note that in the C++ language, because of the
way C++ programs boot (constructor initialization and other very
curious things) the recursive main() call is explicitely prohibited.

121
Toledo Nanochess: The commented source code

Lines 193-195

Z ++B < 121) /* Init board */


*G++ = B / B % X < 2 ? 7 /* Border */
: B \.N N$ N
W mA Nw @__. *l++ & 31; /* Piece */

The B variable loops for each of the 120 squares composing the
chessboard. Notice how it uses the C language facility of auto zero
initialization.
The G variable was previously initalized to point to the chessboard
at array I (see line 52).
When B is a number between 1 and 19, and between 100 and 119,
the program will initialize to border square, also when the least
significant digit is 0 or 1.
Por other cases, when B is a number between 40 and 79, it will
initialize the square to empty.
ln all other cases it will read the piece's table for initialization. The
board will be initialized as follows (see again section 2.3):

I[ 0] 7 7 7 7 7 7 7
It 10] 7 7 7 7 7 7 7
It 20] 20 19 21
I[ 30] I-\I_\J '-II-* I-*I-* \`I\.0 I-*LJ *JO PN -1l\J 17 17 17
It 40] 0 0 0 0 0 O 0
It 50] 0 0 0 0 0 0 0
It 60] O 0 0 0 0 0 O
Ir 70] 0 0 0 0 0 0 0
It 80] 25 25 25
It 90] NN KOU1 |_\Jl\J \1U1 NN (DU1 UJN CJU1 28 27 29
:[1001 7 7 7 7 *J *J -'I

:[110] \l'~I` '~1- \1I\l'~J`l1-`l 7 7 7 7 7 7 7 -'l\I~`\l-~l'<I"~1- ~"I-.'

122
Toledo Nanochess

Line 196

z B = 19) r /* Infinite loop */

This line starts a never-ending loop. Obviously a whi1e(1) could


be enough, but I used this opportunity to initialize the variable B to 19
for displaying the chessboard and saving another two characters
(namely the 1 and a semicolon).
Many novice programmers have difficulty accepting the concept of
a never-ending loop, but most programs have one, though many of
them are interrupted with the C's break statement, or through user
interaction with the operating system (clicking on a application-closing
button, UNIX's kill command, or killing via process list in Windows
or Mac).

123
Toledo Nanochess: The commented source code

Lines 197-198

Z B++ < 99) /* Shows board */


putchar(B % X ? l[B[I] | 16] : X)

These two lines display the current chessboard, incrementing the B


variable up to the last visible square, then the program checks if the
square is in the boundaries to insert a newline ('\n') character
(equivalent to 10, which happens to be the value of the x variable).
Otherwise, it will use the character equivalence table to show the piece
(see line 38).

124
Toledo Nanochess

Line 199

_X-(B=F)){ /* wait for algebraic move */

On this line, Toledo Nanochess waits for input from the player,
using the F macro for reading the keyboard (a value between 0 and 15),
saving it in the B variable, and comparing it with Enter ( ' \n' = 10 =
variable x).
Because of the default behavior of the getchar() function, the
player can exit the game using Ctr1+C. He/she can also correct the input
with the Backspace key, and the game will receive only the final
cooked> version of the line.
Note that the common gets () function from the standard library
<stdio .h> is not used because of security concems because it doesn't
set a character limit, and fgets () would be too big.

125
Toledo Nanochess: The commented source code

Line 200

i=I[B+=(X-F)*X]&z;

If the player doesn't hit the Enter key, Toledo Nanochess reads
another character from the keyboard, and sets the origin square in the B
variable.
Note that the first key was a letter ('A` to 'H'), but once ANDed with
15 it becomes a value between 1 and 8.
The second key is a number ('l' to '8') but once ANDed with 15, it
also becomes a value between 1 and 8, and with reverse substracting we
obtain 9-2, multiplying it by 10 and adding the previous value we obtain
the square index.
The resulting square index is used to read the origin square and to
obtain the source piece, ANDed again in the i variable.

126
Toledo Nanochess

Lines 201-202

b=F;
b += (X - F) * X;

These two lines of code use the same trick as lines 199-200 to
determine the index of the destination square

127
Toledo Nanochess: The commented source code

Lines 203-204

ZX-(*G=F)) /* Piece selection for promotion */


i=*G^8^y;

Here the program awaits for the Enter key, but also an extra number
for use in pawn promotion. If this number is entered, the code for the
promotion piece appears in the i variable (remember that it Was
initialized in line 200).
= Knight
= Bishop
= Rook
nooo O`\Ll-[>L.J = Queen

The program Waits until Enter is pressed, so this also serves as a


primitive synchronization feature with the input, in the case of user
error.
The movement will be done (if legal) by the call at line 207.

128
Toledo Nanochess

Lines 205-206

} else /* Enter alone for... */


v u. 5): /* ... computer to play 5 original*/

If the player hits Enter only, the program will select a move, and the
value 5 defines the ply-depth minus one, as the speed of a 6-ply search
depth is reasonable on current machines.
The values 0 and l cannot be used because they trigger special
handling, so a 3-ply search depth would be the minimum search
available (see lines 61-66).
The u argument specifies the current en passant pawn. lt is updated
when performing the move in the next line (see lines 207-209).
Upon return, variables B, b and i will contain the best move
available at the given ply depth.
The computer Will behave rather amusingly When playing against
itself.

129
Toledo Nanochess: The commented source code

Line 207-209

v u, 1): /* Perform movement if it is legal */


}
1

If the player chooses a move or lets the computer to do a move, the


end of the loop is located here. The program will validate the legality of
the move and will perform the move if it's legal (see lines 141-142).
This is important for novice players or When the computer is stalemated
or checkmated, because the search code could return an invalid
movement.
The call assumes that variables B, b and i contain information of
the origin and target squares, as well as the final piece for
underpromotion.
How does the program check if a move was legal and performed?
By saving the y variable content and doing a comparison. If it is not
equal then the move is illegal.
The loop will execute itself again and again, until the player or the
computer wins the game.
Obviously, when the game reaches a state of checkmate or
stalemate, neither player can do further moves, and the human player
can exit the game using Ctrl+C.

130
Toledo Nanochess

4.4 The Winboard interface


Originally, all chess programs had their own interface, textual or
graphical, for the obvious reason that this was a burden left to the
programmer, and most programmers were not necessarily good graphics
designers.
Around 1992, while developing XBoard, a X/Window graphical
interface for the text mode of GNU Chess (first released in l986) Tim
Mann came up with the idea of a protocol. Some other programmers
noted the advantage and they wrote their programs to use more or less
this same protocol. Today these programs are typically called chess
engines.
XBoard became more popular when it was ported to Windows, and
was renarned Winboard because of some small protocol differences.
Winboard assumes that the chess program is a text mode program and
communicates with it by sending and receiving text.
I had not envisioned a Winboard interface for Toledo Nanochess,
but when the first release of it came out, H.G. Muller developed
Max2WB, a Winboard interface capable of working with Toledo
Nanochess and micro-Max vl.6. He did some tests using his enhanced
Winboard Gold. And some useful programs exist for doing tournaments
between Winboard engines.
It was a nice hack of Toledo Nanochess, but I had the feeling that
the Winboard interface should be part of Toledo Nanochess, in
particular to keep the code small, as Nanochess implies.
After doing some research on the Winboard protocol I did my own
Winboard interface, and I made it fit within 2 kilobytes of source code!
Toledo Nanochess currently accepts the following Winboard
commands:
- quit, it quits the program.
~ force, forces the program to accept moves for both sides,
something like a two-player mode.
' post, indicates that Winboard wants to receive search
information.
- nopost, just the opposite of the above.
~ level [minutes] [moves], this sets the time control, and
ignores incremental time controls.
time [centiseconds], Winboard indicates the time left.

131
Toledo Nanochess: The commented source code

~ new, starts a new game. It is necessary to give this


command the first time.
go, forces the computer to play.
- protover, indicates the Winboard protocol version, Toledo
Nanochess takes it as a signal to return its name.
~ Algebraic movements such as d2d4, this does the
movement on the board. If 'force' is not active, then the
computer will start to calculate its move and it will say, for
example, 'move d7d5'. Upon promotion, a letter is added
to indicate the final piece.
This set of commands is enough to make Toledo Nanochess work
with Winboard and Arena (another graphical interface) and to
participate in chess engine toumaments such as the now extinct
ChessWar and OpenWar organized by Oliver Deville.
/'kair*-ki:'k'!<'1c1k'k*1'f1'fl'1'k*1|z'1'<'1\'1'r'k'k1''1'f**1rk'kk'k='fk<1\'1'r*:'k:1r*'k***1'e*r<1r-k'k^k*ir-k'k'k*1:1fr'k**\

| Toledo Nanochess (cl Copyright 2010 Oscar Toledo G. All rights reserved |
| 1257 non-blank characters. biyubi@gmail.com Jan/ll/2010 1
| o This version includes a minimal Winboard adapter (699 extra bytes) |
l o Full legal chess moves. http://nanochess.l10mb.com I
| o Remove these comments to get 2025 bytes source code (*NIX end-of-line) l
\'*91E*****1'r'kir*'kk'k'k**#*ir**irk'\"k1'r'k-k'.k#1'r**'9r****9<9<****-Jr-k'Jr~k-k*=k9r***#r**'r/

#include <stdio.h>
#include <time.h>
<=har*l= "uStvrtSuqqqqqqqqYy'yyy1fyy}{ I ~z I {}"
" 76Lsabcddcba .pknbrqmove %s\n\O?A6J57IKJT576,+-48HLSU";
define v X(0,0,0,2l,
#define Z while(
#define _ ;if(
#define P return--G,y^=8,
B,i,y,u,b,I[4ll],*G=I,x=lO,z=15,M=le4,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]_1w|p==w){g=q|p+a-S?O;I+S _lr&(q|A<3||g)l|(r+l&z
^y)>9&&qlA>2){_ m=!(r-2&7))P G[l]=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:O _ s)L+={l-q?l[p/X+5]-l[O/x+5]+l[p%x+6]*-~lq-l[O%x+
6]+o/l6*8:llm*9)+(q?O:1(I[p-l]^n)+1(I[p+l]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^
9)_ s>h||l<s&s==h&&L>z|d}{p[I]=n,O[I]=m?*g=*m,*m=0:g?*g=O:0;L-=X(s>h|d?0:p,L-N,
h+1,c[11,J=q|A>1?o=p,s)_1(111 15-1|e-o|i-nlp-b|L<-Mnp y^=a,u=J;J=q-1|A<7||m| |1s|
dIr|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>l){_ h
&&c-L<O)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-pl||I[p+=
p-O]l:l}}}Z!r&q>2||(p=O,q|A>2|o>z&1r&&++C*--A));}}}Z++O>98?O=20:e~O);P N+M*M&&N
>-1<+1924|a?N;c;}
#define D(z)_1strcmp(g,#z))
mainl){char*a,g[80];clock_t k;setbuf(stdout,O);Z fgets(g+x,69,stdin)){sscanf(g+
x,"%9s%d%d",g,&n,&D)D{quit)break D(force)f=l D(post)j=l D(nopost)j=O D(level)o=
n,E=n?n:20,0=D*6e3/E D(time)O=n/(E-L%E+l}D(new){_*l~'u')l-=32;G=I;B=y=u=f=L=O;Z
++B<l2l)*G++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&3l;}D(go)f=O D(protover)puts[
feature myname=\"Tbledo Nanochess Jan/11/20lO\" done=l")_ isalpha(*g)&&isdigit
(g[l])){a=g;B=*a++&z;B+=l0O-(*a++&z}*x;b=*a++&z;b+=l00-(*a++&z)*x;i=(*a-'q'?*a-
'r'?*a-98?*a-'n'?I[B]&z^y:ll:l2:l3:l4)^y;v u,1)_!f)strcpy(g,"go"};}D(go}{k=
clockll;D=0;n=O<50?4:5;B=2l;do{m=X(0,0,0,B,u,n);t=(clock()~k)*le2/
CLOCKS_PER_SEC;*g=B%x+96;g[l]=58-B/x;g[2]=b%x+96:g[3]=58-b/x;g[4]=I[B]-i&z?l[ia
7[16]:O;g[5l=O;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,l);printf(l+23,g};}}}

The core is the same as Toledo Nanochess, but notice the removal
of the F macro for console input, the inclusion of the time.h header,

132
Toledo Nanochess

_=:.-. .
-:- -' f _
.:;=;=;-_?
"-- - ;:;:;:;;<_:;:1;_:; _- =;_-:;:;=;.:-1 _
-- -.-:-:-:-:-:-:-=_:-- - ; .:__-1-ti-'---' -
;__ 1 ;^=-:'Iaa-1___;- =;_a-5-2;-2;i __;.=-F -2-1-;E_a ' . = __ _ ::-:.;::- __
- .- :-.'&.'1=:=:-. 1'-f.:_:.-=E==:--_1.:=-=I.E
_-:-:-..-;_:-;_'_:'___ . _- '
-'==-'.'_- ===r=- f.-_==:I< 'W2-:=-' =%=i'-'- =='=f'=- E=E=i'=.-=.=-=;-=.-
1.' ' 1-'-;;
{.'l1_.':::;::7.:':i'?'':125.:f:.25.::_-5.3.1.1'";::.::2::::-::::':,-...`I::;:7::-:.f:-:-:-:: :":-.'_:'':..--;-_-;l-'f.-f.L:::-.'J'-,` -.::-:--;-.-'_-__ I '-;_'_:-:-::-:-::_:-:;-:-:2- _:::-::f::-:-::-'-:-_'_-:-'_-_'if.-:k:_':-:-"'-::`:` `:":::"`:::-:'""-`' _ `.-.Z--=:'::'_`:::-:` ': _
tf _ _ , -_; . 9,, .,-wm..M-,,..:-.~;-1-:. _, ._ '-:-:-:c-'-1-:cf af _-:L-'_-:ff-":f.. ;;-:f.-3:-:ff-' _. ..._-. '-'-" - -- - :. ::.;::::::. . 1 .'.::::'_.: __::.- ' - -I'
. .. .... . .
; 1 7' " ' -'ffff ` ` 1" : _-5 -1-
1;* '_-,_. _-gw 5- C955 pg-Q ' ~ -- ~ - d"59.!'.d'..?_?}..._
_ _-..-.;.;.:..._...__ ff
':_.; _:_ , ' - - - 5 E -_C.- - SH Q 1: 3 r_'-15
I; ';'-_' Whlte ` : 4:55 Black: 4:55 "
1:-_ ; . f ' W 3'. -_.,\ 3 ,...;:
__' 5 T ` ,:_ ._ .;:;,' _ _:a-'-;__ - -_-_;__:; .;._l 1
` ''
___s__
'_'"""W" " _ L_l.' W"-_ ` `"`%'"""' "H WL-
""
;;;-; :. _ -' I ." -" ."-.'_' 312--' 3.---' "`l^;.'
_' ::-1;., - "-_:`::-::-_-.. `f i - - t- -- i

;.';-'=_; ;'_
_ .-tt. -_ ;;:: -- .ee
-i
_
-- ~ - _';$._ _;.-;-:;\g:;
=r ___.__ -_ _ 1
fi M i
V' VS" J--."- ` ? '- _: _:':Fffi--3l' _' I ' `:-:"".2`.'Z2T`_.-
sei '
: '-\`;-t~:' 4-; -' '_ 'til-`_'{r.f*\*' ff -; :_:-;__ -2-ii: :':. _' iii* -ww
___ - -.am-.-:--n .-dl!-u"'^ - -"~ ~'-"f ._ -1-' ' ki-2-'-'v =~'lw=l-\I
""" . 'T'--""""". ` -' -_ .."1"-' ~` -- -_:':`; .; - ' - ' .:'::~_:`_:: TF.-.-r. -'
..`;__1=-
;_
___'=-iii.
;..; `
1:;aa:z;-ii;;.a.;;.-=;:_:;=;=
;::;:5_;'1"";:'_'-'-::1:: 4;-
.::_::----=_:_=_=:i:_=;:;:_:;=_:_:
-v..'..: SF":`:f:I1::[::;-;:' " ' . .
_;-_.
' '-
"E"3-_ ';_.=.
M- ~ =';;'- ' x\.`:"
`1 -
i-==.<`i-' - 9 ---=2-=I: _ -
-2;;-5; -ii-\'-9
. _- _==;;-;a-;;;-;>z;;E5E2 L.<I'l'-'
--rl`,=,-11 ". = - :'=
' :-'-'
'_ - _,-_
ea _. __ ...__ `_._I \3G. ..

5----5 l' 1.1:-


-.:_.r: --
_
mn-$1
__
- -- __ --gt~=,-,'
_ 13" "
*1-a,\ - _- _. _ ---
` l-" -"'-'^ .-'-
.~:-'1-~'.,-
. '

> _'-? fiar.:_ 2 ._ _ 2::


_;_-__
5 1-uu-au:-mi
f.-:~..'r

:
.-7' '..
.fa, _:__-_.
'lif '-gi* :::'_:._ _:_':-:_:::-:_
"F ~
d-nuu=a-:rx
.___

--
_ . . _:
f *-.f,'f '_. .<-a,=,\.q-=== _
'*-:-.-::.. '.*.-'-F --
'_..
4-?-<-fs=e-o=
_ .___._ _ .'__
5=s.._=
- _- -:-*-^-:'-.'3'>.' " 1:
--
W
=
.-"?.5-' 'Ni'-'3.f'. .
___
;-
_'i
Toledo Nanochess
_ _ - ___ _ _ Q - .;__ - _ -_.;;_____ _ - _ _- i"^.'d' '
-flf' 5
;`

,
-T s
2%___3C_;
'
`

Q.)
`
"
- ." .', .~-.f-
1'' "'_'_"-I

tt ;

'lS';',;"l~.,,
yn
'
-_-_

v
2-'-' _, .. ,.__` "
ki-

~
* a,.
.'I '
'-.'

1
_
' :-':':-:" -.1-'--' 'V'
;I.;-_`-_ `_' ifM"""'#.

r 1
..
-ttiS:~\ gv -T- _
- - -
.

r
' '
" .
` Eli '
')i.'~"<

-1_-
J
ejecutndose
0 3 0 ang (-355en
';='- 2-* ' ea ;- 1 '_.;I=;5?'- __ - '- __'I - - 'E1-___51' f=-
-_ 55 , . . .
_E;_.-1:--'_ ';:-' _ '_

_ _ _.,
9 |

2-* _-
__-_;-_
r W \ rf_.;{ M ,

2 Winboard Gold
'_ ,t._,;*=*s
-f=;-=-.j--=- .-;===
-H.ff ' ' \ llT t-1 * 32"*
~<~'= u ' -'.-f s@ \~ -Y
-
T@- " ag`-$593f-*-,....\-tt
-rf NW- H~.-*
':'-r~'-_\~'' =
~ ~ ~t,.,'*i
=-- --Iaa
.2
-~ run
nlng Inside

;-f;a;.a_:_ te - If.'.=I__':`__::':.`;'._
_f f_f;-f:_f
W'
al ;,,_;,F_;'-='= -'= 1'
.ln O O
f1:;f-'f- -___; -'f.~,--_-,f ;` -_;;-; ff_ '-"_-"* Z .'35w' ' .':1`:`._:'l- 47"'

:--' ,,. t .__ _- _ ,_ \. -_


-- _ -_ _ _ :ff ; ,_ , __ ,E -
-- --;_:;;;_;'._________ ':'_ 1-;
.-'I:-`:;
_;__:_-_ `\-_,
__ xf' /'\_*
'Gt-*?_'__ __'__ _; _- 'Y\';;_ _f-`--W-
@ 0 ,_ - _:_: '-
;. y- .n_- .-,-. ai _- -- _:.
**'- "_ gli, :ifi::E_ 1.1.. , -j E5-;';j_'; __;_-_;_;;I;I_I;-; 5"- _ gt
-_j ;:-_ 1:'-1555
- ; iw - _ nirfi: ' _:-_-,_-f_-~ .-___:-:_: ._.;.;:-'_:_-'_;;_;-: _:*_:';-" :`_;`.:
:._:_."::;-_:::
f!_II_'-J-.\ ;`. ___' -la .- gm _ 'RH' L.,-; 1 ;::" -

'>''.; 5
.| '- -

__; ii' _'


, _._ 'av __.\.

".-____
-
- "
--

- ` _'
_-. ._.\"

.
.' - - -

'::. ;";:i:;'
_ -- ._ -_

.
. _ '
-_ - --

_:_:
_ -*F 1-; . - .v

'_'-.;"" :
_.

- *t _, 1?* 1,
'\ ' - .W - ' -J ___,... _
_ ' __ ;\.- __ _ _ _ ,,.,,,,,,,,,w_ ---__ _
*S
-_
_ ws@ 1
_
,___ _ 1-'-' -\ -_-_---_K
__:'__"a_.-; - . _ __ _
_ $2 . f__ ,,_2___\____
v_ ;
_

. 11:1
~=;
_..._. , _
: ' '
._
I-I--I

2?;
. .|
_
'i;__
.
.
. Q
___w .I
-ac-'b-li
fl

_-'I'
' '_ '
I .Il
.
U. _
_ _
.- . -
;-
-:_
_____
-
-
=- - 'g.-:
*~'E9'
== _-s'_=>,2
1-'
v_-tel
--_ l
-5
_ -

_-.*_9:;r'l;
1 . _ Q _' ,
.-: ::= __
_ . :
-=
.. _ _
_ _. _ __
_
'|f_|: :F '||||-'_|" ""' ''|'_|:1' .'
__ _. _
_ _ _ _ _
_ __ _
'._;_.'|'|"| ^|'. -'.'..'i'-.'.':|'.'v'|'i ' '.'.".'..:. ' ' --_u|:f_||:|.:.'
_ _ . .
""|-'|:||.'|._ ".'- '"4'_._
ri-' i^ -iii"
__ '-
._ I -- -__, _.r__-
"tw_ la '_ 59 .--
5. . _
?-Jl un _--
' - 'Q - -f-'S'-'_
' '':= _-if-(Ii.-*ii-ili=I~' l$'7<ti""iii*M*H`**iii$:;Elil'
--.\:-'*.<<1\f~.-~:-.\.~:\'.
<il1====`:`='=;=f:fiittllliE5ll'llf==
-t - t"*"'t~ ."7*\---1-.-:----2'-1 "--tee-:-:P%>:':f--t"'"`-2
.'_; --= <~f-P-'L V- ...__ __ __; ___ __ _ - -~__--~ ' __-____ - r-=--.-ae-'~__....__
. __.. --.;_-;'____{>_.;;-.-_;`-.:;._;_-;g _.__,_______ _ _.,_.-1-'glgg-;,;;__ '*_.'-;-_,;-1;g1;.;.;':--'-._.._
_1;1._';- __ .;'--`;.f:,;5--='->=;1-Hi>;e=>--E1-;>-1-'_-t . ":=:j.:-;-;1==;s;?!s-se:$:;:=g4l';:.5;.<t-it;.-,_;;:;,t:5;1:f;
..;-;;:_-{_.: .f_:*.;~'e'-.,';'-:`;:_I_- '_ `. 4:-1'-r~:':::f">:f:-1:f::-;'-:117#?>$t2"*.'-2ztk-w;:<'-A-H-:-;-:-1u:~-:-:___-1 _ ~?::l~1n.~<--R -'\"-'?':-:I:i'_2:2''_~_~'-_~-'-:f::-:- I:--'1.~'-:__-:-,-'N-'-1:". _ '2__-::-_-'_- ~'_:-f'-?f'+'.~'%l::'-r-::'51f:-'I':-;-:--';-':-'2-$:-:`-;-:-:.f+:'I:-2-HT;z--:t~'.-23%:-fit:-M1-:T
"..'-;:f-
. ,___ -;-:,:-;---'-;;; ._.-...;.-t.;,;-;.;-;,; ;;--.-.=.;.;.=.:--;-:-:;;-;,:_;_- -_ ,
tw- ~'; _ _...-af:f - -: I - ~:;._ rr-_ -*
_;;'-;r;':frff__::-";-_:*;'ffffffff_f*f_ '";'f:';';':ff;:':'~=;---->--r---.:-r-_ar.=-:-N;-i: - _-_rsE'-1-- a9*v'H-1 -1

some extra variables, the small modification to the 1 string (move Pas)
and the complete rewrite of the main() function.
~ Variable f, indicates if the next movement is forced, this
means a movement without a computer answer.
Variable j, indicates if the computer must display search
information, including number of nodes analyzed.
~ Variable m, contains the score of the last search.
~ Variable n, contains the current analysis depth.
- Variable 1:, contains the amount of time used by the last
search (in centiseconds).
- Variable o, indicates the number of moves by time (zero if
Fischer style).
~ Variable L, contains the number of computer moves so far.
Variable E, indicates the number of moves left by time.
~ Variable D, contains the number of nodes searched (the
increment D++ was added to the core search function).
Variable 0, contains the time remaining (in centiseconds).
Note that this version is able to play with more depth, taking into
account the available time. It typically reaches 7-ply depth in common
tournament settings and can reach 8 or 9-ply in endgames, so it is
stronger than the non-Winboard version. Here is the commented version
of the Winboard section of the program:
/* The Winboard interface for Toledo Nanochess *J
/* (cl Copyright 2009-2010 scar Toledo Gutirrez */
/* Latest revision: Jan/ll/2010 */

#define D(z) _!strcmp(9.#z)) /* Trick for saving space */

133
Toledo Nanochess: The commented source code
main() /* Start of chess engine */
l
char *a,g[80];
clock_t k;

setbuf(stdout,O}; /* Unbuffered output */


Z fgets(g+x,69,stdin)){ /* Read a command */
sscanf(g+x,"%9s%d%d",g,&n,&D) /* Scan command and two numbers /
ntquitl /* QUIT */
break
Dlforcel /* FORCE */
f=l
Dlpost) /* POST */
j=l
Dlnopostl /* NOPOST */
j=0
Dllvll /* LEVEL */
o=n, /* Total moves by time */
E=n?n:20, /* Moves left, 20 for Fischer style */
O=D*6e3/E /* Remaining time */
D(time) /* TIME */
O=n/(E-L%E+l) /* New remaining time */
D{new}{ /* NEW */
_*l-'u') /* Reinit pointer */
l-=32;
G=I;
B=y=u=f=L=0; /* Initialize variables */
Z++B<l2l) /* Init chessboard */
*G++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&3l;
}
D(go) /* GO */
f=0 /* Removes force mode *f
D(protoverl /* PROTOVER */
puts("feature myname=\"Toledo Nanochess Nov/20/2009\" done=l")
_ isalpha(*g)&&isdigit(g[1])){ /* Algebraic movement */
a=g;
B=*a++&z; /* Origin square */
B+=100-(*a++&z)*x;
b=*a++&z; /* Target square */
b+=l00-{*a++&z)*x;
i=(*a-'q'?*a-'r'?*a-98?*a-'n'? /* Promotion piece? */
I[B]&Z^y:l1:l2:13:l4)^y;
v u,l} /* Does move */
Ef) /* If not forced... */
strcpy(g,"go"l; /* ...do computer move */
}
Dleolt /* GO */
k=clock(l: /* Get current time */
D=0; /* Total of nodes analyzed */
n=O<50?4:5; /* Start analysis depth 5/6-ply */
B=21; /* Best move square */
do{
m=X(0,0,0,B,u,n); /* Search move */
t=(clockll-k)*le2/CLOCKS_PER_SEC; /* Calculate total time */
*g=B%x+96; /* Makes string for move, origin */
g[lI=58-B/X;
g[2I=b%x+96; /* Target */
gl3]=58-b/x:
g[4I=I[B]-i&z?l[i&71l6]:0; /* Promotion */
9[5=0:
n++; /* Increase depth */
_ jl /* Post search information? */
printf("%d %d %d %d %s\n",n,m,t,D,g); /* ply,score,time,nodes,move */
}Z m>-M&m<M&t*x<O); /* Until checkmate or timeout */
_ 0) /* If not Fischer style... */
L++; /* ...increase total moves */
v u,l); /* Does move */
printf(l+23,g); /* Print move */
}
l
1

134
Toledo Nanochess

The WinBoard protocol documentation is available freely on the


Internet. There are also UCI (Universal Chess Interface) engines, which
use a protocol that differs greatly from Winboard, but the UCI protocol
is just another protocol of communication for a chess engine. Because it
was developed long after Winboard, it is more standardized and has
more features for position analysis. Some chess engines <<speak both
UCI and Winboard, and some even have their own text or graphical
interface.
The UCI protocol is handled by various interfaces, like the Arena
interface and the Chessbase interface (comes with the commercial
engine Fritz).
Winboard can handle UCI using a protocol translator known as
Polyglot, developed by Fabian Letouzey and Fonzy Bleumers.

135
Chapter 5
Toledo Javascript Chess
http://www.nanochess.org/chess4_es.html

() rginally Toledo Javascript Chess was to be published as a simple


Javascript translation of Toledo Chess 2 from 2007, but as Toledo
Nanochess enhanced the computer play, the Nanochess core was used
for Toledo Javascript Chess.
Because Javascript is an interpreted language, its speed is not very
high. So the online version can only play at 3-ply depth. Some recent
browsers are able to accept 4-ply or 5-ply depth. You can experiment it.
The Javascript language doesn't have pointers, so every invocation
of pointers had to be rewritten as array indexes. Also, the boolean OR
and AND operators have a different behavior: In C they return 0 or 1,
but in Javascript they return the last value processed.
The C preprocessor is inexistent in Javascript, so the code size
increased as all macro invocations were replaced with the equivalent
complete strings.
Fortunately, the initialization of arrays can be done easily on the
recent versions of the Javascript language.
Since its first version in 2007, I noted that it was possible to beat the
current smallest Javascript chess program available at that time, so with
Toledo Nanochess at its core, at slightly more than 3 kilobytes (source
and graphics) Toledo Javascript Chess is currently the world's smallest
chess program in Javascript.
l coded it in a single afternoon as a simple statement-to-statement
conversion of Toledo Nanochess, using the previous chessboard
interface that I wrote in 2007, which was very easy to do. For this book
l indented the source code. Since Toledo Javascript Chess is based on
Toledo Nanochess, most of the comments apply to it.
// Toledo Javascript Chess.
// (cl Copyright 2009 scar Toledo G

137
Toledo Nanochess: The commented source code
function W()
l
B = b;
for (p = 21; p < 99: ++pl {
if (q = document.getElementById("o" + p)) {
q.innerHTML = "<img width=40 src=" + (I[p] & z) + ".gif>";
q.style.borderColor = p == B ? "#ff0" : "#aae";
l
}
l

function X(w, c, h, e, S, sl
{
V8.I` az
V311' J;
VEZ' C;
V-HI' rs
'Jar qt
Vr A;
Vr rn;
V Il;

Val?9;
var P:
Val" K:
VEII' N:
Vr O;
Vr d;
V511' E;
Vr L:
Vr OF
V.1'.` t;
Q : e:
= -M * M J'-
= 78 - h << x;
=y ? -X : X;
>
= 8 I-

+
Z
$
Q'<m
W
do {
-wn- && S >= h && X{0, 0, O, 21, O, O] > M;

if lo = Ilp = 0]) {
q = o & z ^ Y?
if (q < 7) {
A: q-- & 2 ? 8 : 4;
C: 0 ~ 9 & Z ? [53, 47, 61, 51, 47, 47][q] : 57;
do {
I` = Ilp += l[Cll;
if (lw | p =: W){

e=q I p+e- U3 S;
if (l I` a tltq | A
*xl UJ
CJ ll 1 l gl || (r + 1 a z ^ yt > 9 && q | A >
if (m = !(r - 2'

return y^= U3[\J, T:=| I-I I-.l __] = O, K; G)`\_4

J: n = o & z;
E: I[p - a] & z;
t = q | E - 7 ? n : (n += 2, 5 ^ Y):
while (n <= t) {
L = r ? l[r & 7 | 32] ~ h - q : 0;
r
'
f (s)
(1 - q ? lll p - p % xl / x + 37] - l[(O - O % xl / x +
L +=
+ l[p % X + 38] * (q ? l : 2) - l[O % X + 38]
+ (o & 16) / 2 : !!m (I[p - 1] ^
+ l(I[p + 1] ^ n) + l[ U |321-99
>
'U >
+ llg * 99 + (A < 2) Q
H K -0 +
no

if (s > h 1] l < s & s == h && L > z ---f-~-

Ilpl = n, ITU] = m ? ( Ilgl = Ilml. R'1\-.._4 .J = 0) = Q ? Ilgl =


L -= X(s > h | d ? 0 - N, h 0
1

I[G + l] l J = q > 1 ? O 'U



QPQ+
n1.-I
lxr Sl; +ko
I

if (!(h ll s 1 O | i - n | p - b | L < -Ml)


return wll, G--
J = q - 1 | A < 7 B
lllsl lfl 0
_._. W
A--C N ll of 0: 2]-r of > M;
I[O] = O;

138
Toledo Javascript Chess
Ilpl = r;
m ? (I[m] = I[g], I[g] = 0) : g ? I[g] = 9 ^ y : 0;
l
if (L > N l| s > 1 aa L == N aa th aa Math.randam{) < 0.5) {
IlG] = O;
if (s > 1) {
if (h aa c - L < 0)
return Y ^= 8, G--, L;
if (Eh)
i = n, B :C)_,b'.:p;
}
N = L;
l
n += J || (g P; ITI = p < O ? g - 3 ; g + 2,
I[m] < Z | Itm + o - pl || rtp += p - o]) P 1 = 0;
1
l
}
} while (lr & q >
2 ll lp .--
0, q ] A > 2 | o > z & tr && ++C * --Al) ;
l
}
} while (++O > 98 ? O: 20 : e - O) :
return y ^= 8, G--, N + M * M aa N > -x + 1924 | a ? N = 0;
}

function Y(s)
{
i = (I[Sl ^ yl & 2;
if (i > 8) {
b = S;
Wll;
} else {
if (B && i < 9) {
b = S;
i = I[B] & 2;
if (li & 7) == 1 & (b < 29 I b > 90))
i = 14 - document.getElementById("t"l.selectedndex ^ y;
X(0, O, 0, 21, u, ll:
if ly)
SetTime0ut("X(0,0,0,2l,u,2/*pLy*/),X(0,0,0,2l,u,l)", 250);
l
}
l

Vr 1:
Val' M:
V z:
Vf Xi
V312' G:
Val' I;
Vl' b:
Val' u:
Val' Y;
Vf i;
Var B;

ll;
120;
10;
15;
_-
10000;
3
X
HN 0 [5l' 3! 4! 6! 2! 4! 3! 5! ll' ll' 1! ll ll ll ll lf

KO 9, 9, 9, 9, 9, 13, 11, 12, 14, 10, 12, ll, 13,


'ICI LO \D\O ko!- Om LA-3 CD UN 297, 495, 846,
- I-4' G 1'-1' 2, 2, 1, 0, -1,
_1_ 1_ _ _I-vt -11, -9, 9, 11,
1-'

10, 20, - \OC3 -11, -io, -20,


-21, -19, -12, -8, 8, 12, 19, 21];
B:i:y:u:Q;

while (B++ < 120)


I[B - 1] = B % X ? B / x % x < 2 | B % x < 2 ? 7 = B / x a 4 ? 0 = 1[i++] | 16 = 7;

1139
Toledo Nanochess: The commented source code

for (a 2 <table cellspacing=0 align=center>, i = 18; i < 100;


a += ++i % 10 - 9 ? "<th width=40 height=40 onclick=Y("
+ i + ) style=\'border:2px solid #aae\' id=o"
+ i + " bgcolor=# + (i * 0.9 & l ? 9090d0>" : c0c0ff>")
: (i++, "<tr>)) ;
a += "<th colspan=8><select id=t><option>Q<option>R<option>B;
document.write(a + <option>N</select></table>");
Wlls

The program is almost completely self-contained, except for the use


of external images. Another version exists which displays the board
using Unicode figures exclusively for the chessmen. Being
self-contained, it is easy to incorporate it into a web page or to use an
HTML <ifra.me> to reference it inside another web page.
At the beginning, the script will build the chessboard using an
HTML table of eight rows by eight columns. The W function is in charge
of updating the chessboard, the Z function is called to update a single
square, and the Y function is called whenever the user clicks on the
chessboard. A small <se1ect:> control allows the player to select the
promotion piece for pawns.
To play, simply click on the desired piece and then on the target
square. Illegal moves will not be accepted, and afterwards the computer
will answer the move.

Although playing at only 3-ply depth, the computer will manage to


overcome the player if he doesn't make reasonable moves. lt is an
interesting opponent for kids recently introduced to the game of chess.
I worked hard to uphold the compatibility of the script, so it should
work on a wide range of browsers and computers, and even on an Apple
iPhone.
l_.;_.*t;^_=,_;;_;g,____,__3m______;tg_,__;_;5_}W;__,_,____at _fy_,gg-gpra-;a_.__;_,;m_, 2;?__ ._'_ _ ?_`_`l_ t __=`=. ,___ _., _ _ , _-_ _,_,f _-_, _ _ _ _ s_ ga, , , , ,___f _ _ , ,_;-*r-_,_, , :__.__._, . _ ._ ._._t _ ___;:-_-;.37;;,_l<2f'a
- _--_--~_._,_._--_-'~-__
.. ..___..-.-----........._..-.-.----. ...--........__...__-.................._..............-......._................................................-..,-... -...___...._.____...___. _...._..1...._....-...._._...............__-.-.-...._-_-_-_-_-._-_-_-__-.-.-.-.-_.-.-.-.__

T:-I._-ll:-:":-:?_1__:+ " '?`-11:-H "-afv.'.-ass: 1l{r`:..:a~<_'2*'--.rr-l-1'! *F '


;4____\1_ 3 `._,,. ::.._. W .;,_._..__\.,,._._. ,\__ ` " '. -771:: :::f`f::f::_." " __ _ 2 2 V _

_ _- Q 19
. TW-'br-EN '

` >.'-9;'-";',' ' .:_' :_:-1;" `' :_:'_'_:_: :gli


-3 -13 .;. ;_ -.-:a;:_ _;-::-;__ __ :-_;~"- ---
2' -:l>.-_-'-:2:-:PF:- -_ ;'_':-ii" "-:-' _;'::t'7 : _-:
____ -_'_`:::f::::F::`$'3.-.-__'-"::-.-:fx-_-.$212117'?.-_-__ _ -,-:-
'_''
: Ill'-l 1 -
i 22:5; ;
-;;;r_t_-
_ ';:;_;t_ ::-:;:_
--::;_<;='- Y->tr;rfr===_=I=-=-tr-'
3.f:;:-: :-1 7: 1 1 : ; _-: : ; 1:-:
- ~_5.~-:.-: _ :.2
3;' _::::' "_::::`:' "f._f`':?- I`I
fe-?2-f:??f=?t==:;r=-='='t-=;==;;=;-2-2-r5-2--f-=x?tfr;:f=m2;tz=;--es-=f;; :;;f-i-t;;n;-; -ft-2-;=t==<lt t-:ses -
i 11:f :=f==:5:;t_a=e=rae2=>;;;z=;:?z:;-2-E;*2;=22:Btt t=-2:ari;if-;:;:;-=1=t= O Q O a V aS( :fl t
-`"f:5IFff-5$`<'--ilii'-I12711-ffi-ii7"_-ifli'-g If'I'-Z-'I_.l`;, ll`!;:i:l:: `-7'.\"'"-`7"`t'l:^~
1' 1::-:-:-:::c*'l'>:'l^'El:3:'<t1':-:-_:-'17.-:f::l:-i:f:',-___-it-:-3:l:-1:-1-I:'2-::-:g+_ '-'- : - 1-: _ ; ' ;;T_\`-9-$1'-_~;;~f
'-1-I-1--$1--1-1-I 1-1-*F-fEH?.l2-a;;:1_;;__I;I;I;I_:::::11::j:1i:t1_I'{::::-el-ctl- :1:iH-. E15 :-' :-.~`:; -HL:-'.~`\f.i `l.`-_.~_:l$
t se haasamamamm-1 .L{_:,l'\'l;--.....,.....;_Y;_$. _i;.____

Q 2223:; :`:;' (_,-_1::::::: C11 ` '


iii' 'Hi "$ft-`'-:f`:
955 funmng ln
hl hA1IEr7
a;msaTaaaveeW
:~ '_ str.-_.. ._.;\ _ vr -
tllftlL-eef~rmmaBehw
'* ' 1
1 _
9 -iii-_-;-"` 5-.
ii* trssrss a 1
' _:_:.'-----_---:-:tt-Itzi-.--'tN
:_::;
-----4;' --
;:_:' __::_.-:_:-::
------:=4<;;=z:-:1:l1:5:':I:':-::;i$'"2-3;i:':;"' `-'_:,
:::age-:;t::;';;::;::_'-_:--_:-;,.
:Sln \t.
:::2' ":::'_-'f' 'if-:::::' "::::f_';.'\'f3c:i`;,i:;::;:_:_':If-f3__1 *ig-" ';-lt-tk'
i `==.-#1-1ttaarasfaa
`_ __ ._ .___
15.-1.--.feaatea;-=ea:=-;=;:-,,,_;_-;_.-._er.me
\'"'{':-:=-'l.---.f._'ill>"`1::.\!-:_-
__.' _ .___._ ,`_______ .~_
~ *-
_
big '_\,f::_; _
Jes
es
x wf-om-21`-`-'.':'.=-`1:--F
.`
, W
.:_
_ _ _
1,1' *
,a
5 _
5'-gg:- := sa
2-
;_;-: _x
av*~reses. Beerae- B mtheme,
" =:.<-':.E~`;'E:.'`~.;`-"
ma~.\rmeeeeemsf..-_.:;;:;;.;._;
-.-. ,:

. __. ____L',-..ta_h _ ,_._ __

. =r.-' A -xa =_ t= ~'.+. :_ :':- ri

140
Toledo Javascript Chess

5.1 Source code forks


The GIF graphics representing the chessmen use up a number of
bytes. In total the thirteen files use 967 bytes, although the images are
only 8x8 pixels.
So I prepared two text versions of this program. One is the smallest
of all (2159 bytes) using only letters (P/N/B/R/Q/K) just like the C text
version. The other uses Unicode graphics for the chess pieces (2299
bytes). It has not replaced the simple text version because certain
platforms do not have Unicode charsets.
The popularity of my Javascript chess program has surprised me.
Currently there are at least eight source code forks, all of them sharing
the same core but with different interfaces designed by various people.
For example, there's an Italian one with an interface based on CSS and
an Australian version (www.roo1oose.com) with graphics integrated
without using the HTML <:.mg> tag.
But two of the most astonishing forks I have seen are one from
Latvia by Chessforeva (a 3-D version with animation, zoom and limited
rotation, fast enough to work 'on all browsers) and the other from Italy
by Stefano Gioffr, based on a 3D chessboard renderer developed by
Jacob Seidelin. http://chessforeva.appspot.com/C0_Toledo.htm
Links to these forks are available on my site.

gsm; :ar: nf :qu--.=' 5a;a<=-:s Hmr-1:-yu :..~.=;r `


Q? .=_-- ; ht::$-_,,.x-1,1.:-u1ff.;;.1:',1-p~=l-n;-Qnn- -Q - -'; _ _',,I
" ,__ " ' ` ` ` . ` l .,_ _ '_ '
:G Ararsn.-rariu.-:ac .\!a:-hn-: mzcxnsx-nie-:ci urrzssrfnnno save? G ;'=P1o :.-:.~uo~ tu. Cu-9.- ;-f='1 Sfugsma ;.,hmnm; - tac x bl.axl:_: '^'-
'-"?H=?wW1 ma. f 1 '==-';;-:__'ls;;;a::-af;. f&=Ia:afar;;:~*F-;;;f_';=:=;as;2a
:f'-':f.-.- 1.1 ;,';.'.f; =; -J
.'~'.\'-'-.-".'
-',1,,.,,'
J
.:: ; I f,g,<,- ilzfgg,
.J '
1"" i;~.. ,. -'
I . I ' ..'.-.
"
. - . -3.. . .-.
- ' .'.'.,,-'-E-
..-. . .
.,-. ..;i: '^ -1+ .g-:'.-*.I_f:-_:;'.'-'- '1'-*-'
' ..,- .- - -_-.
-":
HI.
-.*-s-.=?.<s;:s;*-:=.-=.%s<.-=-ss.- aas f....:=f=;======:=;=;2 $'== :;a~;=====;1; a _ -;;

The 3-D version


of Toledo
Javascript Chess
from Italy by
Stefano Gioffr.
La versin 3-D
de Toledo
li
Javascript Chess
l tu de Italia por
Stefano Gioffr.

141
Toledo Nanochess: The commented source code
""`""f *'* fP2%1=l=$'%1="lR1?-t*= ss>HHr;>l:3E:>?=:ltf;=*-=s:=-= ;=;;1'a;1.;:;;;55f;ql________ mi w ~< + + :f>f:;<-_~_}__~_~___- v
-mar.-_aaat-3 rs%__----- ___, . __.vJ... V

gvzlzixo iz-iia 15 $q'::<':=_+? 1-',-.'.':f$t<'e: u''.wll:f_-" Ryu-.'.e _ _ j_ _ _- ; _ _ ` ---;

:::;:`:":_:-::::f_'_'_'' if _,-'-_ -'g'.: , - -^"'*'_'.":,f'.'I:-!i_'f.r.'9 ^n:;1':.-.C'_*.\,'\'.' -1-fl. "F 2112-@ -f- .-: '-_- -
........ ............................................. __ __

--
\l_;"' k-. EL- _.
-'.-_-:-: '\ '-.`-".'.'.
-_ "ir-2-:-2-_
-`-----'^ '
.~_ 1.-.-.--.\.
_ _. '.-_.._.
-''_'..'..-.'.
-~_\'__:k:
'_-._
_ 5:.'-.W
_j____-=;. :-1;.^.'.-j: _ -.'..=.'.
_- .'..-...._-_-_-_I_
9~*.=> :mz-zmiecsa 1 rstaa
-:?_":1^5.-`t5_-I?_-."*- _ _ `:`:5.-:'-. _f:'-:: :_1-."9 _"'::Iftr-;` `:::'-1"-_ -:-::\-_-:-:-'-._ _2';;;;;';';;_:;_;--_`5 ._ '-S -,_ ', - '-,- 'r _" _.-1..

vi 1
'- ,_*;;*"- -*" '*
- '-" ^'
'
'-15 "-;-._=_
.gin
_vsa:_:-:-;-::;;>:-;::;2g:2;'-
fzfisaf sa 1: =f_==_..__.-'-1_:-:-'.-.'-;:_
_.___:f::; .=:-1-__--'-2.1:-ii-:-:-t_-'-:_'
_';-;._ _._-_=a:sa-_;== '-1:. ':_:_-::-:-:-:-:-t-t-:-:;:;:;:-1;':-._"'-'-:-:-':-:-:-:
_=_::a:;"__-ss:5. =__-;_ "'_:_=a:2:',_e. -==_ ___.-:;t.-:
==_~::~_=I2_-_ --;---:-1-.'-_-1-:_
_=2=; ;= =-;_,__ _~sE::1i_ __:iz_;*` fi;
la-:-:-:-:-1-:-:-1-:-1-:-2-12324-:c:-:-:-'-;_-;:-:-;-:t-i:-;:t-:-_j-1;;-:-.$55:-- ;:-:-:-:-_-ir:-:-:-Fi:-2:-1-:-55
'- -:'_ 'Z-:-; -;:::___ ._:;.;._ ---_-___;__;_-:';:; '.___'-'-__._.__-__:;;:-;-:-::, - Q'--;'-mg:-;;;;;--;;;;;;_';; _ '__-;----==;;;;;;' '_ -;:;;-_;;;-;,:; _-4 _ -_-_-__-_;--;
-'_--31ifrffwf:"'
" %;__.`__;:`:;:Q`I7:3:::-'-_-.-;-I-:I:7: __ ':Z~-'--`_`:.--_'-1*f ':lt_::"` ';f: :`:::::::::f:::-1 ` '::
t-_ Nx N. -* _ __ __--41;;
----.-->-_-_-_-.ug . *.*-.-- _- \' H 4 #2 E _t-- ~ _ _5:1: -. 1' -:-:-:-:-:cc-::- -:f-: -f
__- _ __,__,_,__,_ _,_' 4 15.7 __* __ _______` ,wm -*_-,__ :::-:':'_ :-:-;-_ 5:":-;":':;';i: __ _ -: ,;f_+'-;1:"<
__.\_-->-_-_ f_g` __..-sa ::-:;:-:-L-:-;-:-.-:-;;:-_-q:-:-:-:- ^ :-:;-::;-'^ ___-_:-`_-:-.-_'-:;:: __--yia
' - "$l,~`J``!'C -:-:-:-:'-_:_-' fl _-_ __ ;;;;;;;;':fgs _ ;:-:'-^-:_;_2 al .-:-'__::_:_:.;:c:` (_f~::;:;-;;;-;_;;:f-l:-:-_-:~;.f ' la_ _
1E';a;='F_j=i=__1_; ; ; 5fE;:5E;`=f';-'E'-*f" =:-:-:-:-:-:-:-:-:=:-:-:-:-:-:-:-:-:-:
1$<-:-:f:2:+:I:<-:-2-:-:-:ft-:-te-t
__=.._._._._._"._._._._._._._._.___` '_ -3-_
;5;'_;I;E=E5i5E;Ei:;E5E;:3E;E5E _
,_ _$.__;_-_._:_=;._
'<- :t:;-:-:-:-:5--'-:m \ .---::-----:--:-:-:---- _ - 32,-_
5' :-:-:-:-:-:-:-:-:-:-:-:-:-1-:-:-:-:-:- if-
-_-====;=:f:=:=:=:=,=;=;=:=;=:=;=;=;==- ,:=- -___-:=f-' :=:'<=:=:a1_=:=:==s5;s;r;===:=:=:_ ii
W" mi es v= se ii __; _* r f ~
ii `
--:------;--1-2-t-;-t-I-2-2-1;
:-:-:-1-:-:-::-:-_-:-:-:-e-r-2-15"
;:'5;=:;.t--=ia';l:-ggfp
-1-:-:_-1-:-:-:-::-;-:-:-:-:-:-:-:--'
_-_-.__.._..._._.__-_._._._._.\

_
_
_* ' :t-_-:-:-:-:':-~:--::--~\:-

E=PE;E;_;_;-'-'-\'=I_=15;3='~.-_--Hb;--_
_..._...._._..\_...\\_-
--f.-5-_;_=_;'
:-1 ~
..;:_--.-__-._-.___&__
:-;~'.'-:-1-:-:-;-:-:-:-:-:-Z-:-2-Q:-1;\ 1'* 2-, :-:-:-:-:-:-:\':'-"\-:mea
-;~ -'~:-:\:-\:-\\\\~
=3.<;=-_\_=-_1:=5;f;1:=s;;_-
ll:
:;:'; _;_';';j_"_ 251;. _ ;;;;i
;_22>^- td .- g
,<.:____.\;.;._.__._._.\_.__._.___-_-_-_._:_?&_____.___
_ _ _ _-_I;__-;1_;f$_';I;2-
4'
,- ;::-:-:r::::':3 ~'-'-**-
m
-1-Ig-3---"-f*
gg--'---I-2:1-_-::-i
.52-; ;_;_; ;r-xf -_--;;_f_;;' ,;;:=;_; 3 -
'-:aiii-f-_ *-_
,_______;,_._.___________________;___________?_____:__:_1

--;-_-52935
-
-1-_-I--^--'fg--; 'I
:- -_
%
1_ :-_::::-::-:::$
,',--:------'--1
l he 3-D version of
. .-.-. --.-.-. _- .'.=.'.'.'.'.'.'.'.-.'.'.'.'.'.'.'.'._' ' '-_' "''- \'.=.'.-.'.'.'.'.'.'-'-"-'--'-'.'- 1- . -_'-' H '_"_--'_-_'-I--.'_.'.'.'..'. wl.-_.'_'..__.-.-.-. \'.'.'-N.-' \".\ '' _._._....... . '.- ', ,1-'-III!-I--? I
__-.i=a=a=a=a=a:;=a=a=;=a:a=a=%=;===2_=a=a==> -af-=;=i==:=a=&=ai=2=:5=as =ie
,_-:-_-_-_-.-.-.-M-_-_-_-_-_ -J'-=_<-' "f'-';i__;?=s: s:%i=s='=a=z=sa:=s=its '-.-:=.<a%_=:_=:'_=fl.**= : ====;=at=; ss=;=r-*-1
'_\- -_\-_-_~-_-_-_-_-_-A-_-_-_e-_<-;_~_\-;;.-~.$\`1~ 1-W 3l=$$====-=-==-\.F_'-*3_**_---'_ -_- -f<l::l< gf-l lll _-;q
:-t*_':_.*_ =- _-_=s_l~_.sta- _=f=-_==:==_=_:1'
_:3-:;<-::t;:5g;g::;_;:;:;:_g;:;;:;:;;;;:;:;: -, ";:;:;;;:;:;;;_;';::;:;:;:;1;:; p :;>_t;'g:;::;:;:;:;'L;:;:;t;:;:;:;:\;;_;_:_:4._;f __:; _--_t.-_-M-__ `q::-:_::-":_::::;__,:t-l_::_;;:::-:-:_' - ht;-_-_l-f'---"':'
-:_.;_-
._._ -I-I-ffflj-232-Z-Z
... _ ...___ ij-2-I.~---'-'---'''~'-2--H
_. .. ....-......_..._._- _ _ `_......_.._1...;.~_.;...
- ___-_-__.,-_._..._-...,__ _.
:Is: *__
_ \.;...-?--.'.?-Z-2-I---.;;.
......-.._._-_;._.._... . _,~"'^^.-_ ,".-_-_-_-_~.-_\`j`.-'<.'N'--.'
-_~.'\'-_ ' ' -- - _ $__'_.`Z._I;.% '.;_;'_ `_.;I1_L '{;I-.;\^._j.;:$ Ii .
.-;_:::::_ : ,f-_ ;:-;'';';:;;:;;;' _;_;
zrszfasa-:ari$sr=;:z=a:;-2==:a=*i====s==;=5=;==a=s=::;-=a=;==:i _:zI'f"t7'__
'f:j:`<f-fffrzfi:jt!f:jZ:ff:}!
=a=e-:._`';_:;:t:I1:E:f::::::f{::2:f$1:"
a;i=2=arias:a=:5;i:i:=2_=zs:i*3_ -_-:i;2"":'.
=e'=_ \':f:[;::::::::1;If: _rf_y_:f$$5fJ
5- a>,gn_5=_>.HW
"=: 3.155\ ll
_
5'_f_f_'__.;-I_P_:.<~_'
_Egq;::;::1:::-'ring'
12=
E-E-E-Eli-E:-2:lfi l :::-:-1-111;":-:Mil _:-:-zr g.g\-:';-21-I--F'-': I
1-:f=;f=*-E=:==:===E:;=i=fu'::E'="v"''r:='*>5 =EfE=EfE==E=51 :E ==E=E=ErE=E: E1512 l-r-:ef -'f5r_tu <:5=3=::i=i:_2:Er5=:E:25=_E==5'F2 --f_ j'='-'=fi=_-*= `=i1Ei:;==5E$==Ei5='.,;ElE_l;; j;:;:; _ ___,-_',_,_~___a;-.g 5 5 3 5 5 : 5 : : : :'= :_:_=_ ' *-=' =?_a_'5'if1:1=i:rif
_;-\=: :;=:=:=:=I: =:=;:2:=:=1==:1:-__ :I:15;-1;:;::f;=;-:;=:-::=;f;=;=;:;=- " -;g:';r_-1`:1:=:;::5;ar;r .'--_'--_-'=-=;il='-,fima:=:====:=:=::=3- -\ g:=_<;=*:f;''-;----:-1-lilgr-=_=1==_-I_r1I_=::k=;> -=-=-=;r;=- 1-: =;==;f;s'=;=r;=-==;=sr;=-';
::*"'::1:f:1:::`::1:::1:I:f:::1:' _:- 2:" ':3:::::?:::::-_-1:2:::-_::" _ _'t-.t:h-.1:-._"-_!-.-_;-_-."- :?"$ 1'i'ff:::':-.riti-.I ri _' 1" .*:-5--W'-' - " "'"-1-I-'I':`_:"%":"' 11"-'1:-ft. 1'i::":"I.-:i_;_'_-13.1:
'gggsgqrgagsgs;:;a;f;a;a;a;;;a;as____-1.,t:==a;a=is==s=3s;=:;=f===_:=ga:=_j-_s'_g:s=s:aa;a=a=;::=;ss==_____==as::;at=s:2=sr=;:a=i=s *
_$^if5:f*;"FH'
... _(._ $$:`15fi;f:::'
. . ;:f:fzii '-f-
_\............._...-. " :::::E` ':1-TF-::1: i l '- ' -_...-...-.-.-_..
*:':l:f:F ::::1$::E7:: _;t ::"5fha-33 *"-5.`:i 'E:2i~t:-*3: LQ 'FE'-' --`.I-_; '7i----
f"i
- .-2
-9:* - "'--H li1.E.9'
- - <`- '$*I1
1 --` "-1*' 712-I
:$_ff:; ;:-,:g__ :;;;:;:;:;:;:;::;:;:;r;:;;;:;::;:;:;; _, 11 =;:;:;-:;:;1;,_'
...-. .
-'-_._'...-.
-:::; ' -' 2
::::::::::i:::1:;I:: 'tf-`*4 2 5 _.\.\..\\...\..\.~._
`;::::2:1::%2:::I:N- 1--
*,<.,_,__:r1_ _, :_:;:-il-_f-ft :-f:;:=::,l:5 :::_____:;3$:_--_~v.- _t.-
_-_;$:I
"_-_ _l;-I;Z-I'F;.?- 'lII;II`II2[I1`B'
>_:I:::I:2:;::::1::;1:7:::: "f:'ff_ `:T: :1:=:"-:I-I-_ __.;2;
-:_Li .;. 5 L:::l:l:::f:1:;2-:=:'Ff -:'::' gll :::-R21::f::1:1;-^:1:1:T::1:+ lf",,;_3-"^' l -'-_;.;f-2-___-_A_-:-:Q;' 3}<:-__?,W-__f$__f~'
as._;< <~~"' _~~'-'.- _-._.~.._'"'-":-;g:_:' S1`>:*$
.\__._._._._.\..\r._.-fh-._f ._._._._._._._.__._.__._._._._.___._._ m
e-f=-?~"*'---,mag
{."` '".'\__ .`
Q :_v_- .___._._- 3_ _ _.__.____.. _ _ ',
$'';;;;j'; C;;;'~-'-"'~ '',$_''..$'. "-1-'-'f _" _jI'!_I;D_`;EIQ;!-
_1\._, __.,__.\.._.__. _\.._~2___f.~1;.(._._._..___-__.-____,_._._-._`__-__,_\_._.__
'f'- '-_
_ .'-
`-.2wv'- _' --fi-'P ":.'F
'- -.iv `..'.'$_-_
'_ ._ "_.'-F
_-._ - f .'_. ...
_? HIH'-"`I.
__.- ~._ _;
.
}_-_-_-_;-_-:~:-_c_;f_,\'::~
:;:__' -:,;-:';-_ :;:;;;:;:;:;:;:;:;:;:;:;:;:;:;:;:::;:;:.-. 1-.=;._-_ .' =E=_'-Ea'Eeu;=me.;;:;:;:;;:5;;_;;;;_;;f;:_;;:_
w;-'_ _\.-
'- -._- '_ :;'_,.;_:;;_;r-_,_1_' 12: _{--l-'.\-_-.-1~-gg
__ _ - '_._q.--;;;;;;;:;: ;;:-'_;:;;;_:;;:;;-1;:;:;'-;;;_:;:;:;:;:- 1_-.v '1.;;-;;;_____;_-f
, ;-,~ _
1- _::: :: ^%' _,--_. --l
:r':___-:_~ _ __:-;_ --/_
_____5 __________<_._ _____-::::-:_.;1;2;_;;._ 2-':-'M2-fl 3.-_-_-__~_-;-.'.S:$_ :-:::;:;::-:_:$f$$l :- ::;:-:;:-:;5,?:`::z:;;;-;-;;
$_.'':{:::2::E::::::}::::::}:::` _ ' \-:;:E_::;:;:;:_:_:;:::;:::;::::;: il _` `$.~_$'. ;: ;:;:;::;:"_; :__ 'q'.;:qr, - 2::-'-:;1__g._,_t- 'S3'fcq::;:;;;:;:::; r{:::; 1:I:1*,1:_?_;:-:,?__.<'c Q __,-.__\_;
I'-;21:;-;f--;g; 5 gl;:;-!:;;!;;:;:_-::;::;:__:_::::;: __E _-. $1 :;:_:::::-___, -:::;_: - ~ :'-:;:g:;:::;;:;:::;;;:;:i 25 _*-:$1:-:f.\-:aah lg f '-
-`-::;:;:2:-:-:-:-:;:::;:::::-:;:;: _ .if_ -_;;:_::;:;:;:;::;:-_:-;:;:;;;:;:;:;:1ggt-':;$:-'l:_;;;:;::;f:\.__ _' :;: ___ _;g;:;:;:5:;:;:;:;:;:;r;:;:;::;.4~2l;9::llf:k~*-7' _ __ _
=:'=:f-.;.;.;.;.;.;.;.5.;-;-;-1-;-;-1-;-1.;
--.-.-.-. =E=E=E1I~'ErE:=E1E:_fE=E:i:5:f=E=:I;__?5= _;__-:-;:--:;-:-;.'-;-:.5-:5:'-:-.-g5;
:-:-;5-_1-::; ;:-5:-::l;_ -5.W. -; ;==;_>_ -. _-:-;-:-: ,1;_==- -sm-_. -_ -__;;;=,=:5g:5:3-;;3
;:--:-;-:~:-::-:-:-:-:-:'-:'-:-: :3:,_"_:s
_-:-:-:- S+=;1___r,'_,'~_fg__1;_;
'""
-f :-:f:-:-:-:::-:-:-F::~:::-:-:-:-:-: :-:-;-r-:`-:t-1-.-.--:-w-_-E-_--:-r-::P_- " 1
:-:::-:-:-::;:;:;:-:-:;::;::;:-:-:-:-__:;:<t<-:;:<>'
rsl
_ ' ""-:
`:_
tw- " -wa-
1-,_
"'
-2-\;-I-::;
:-:;_;:;:-:-:-:-:-:-:;:-::-:-:;:-::-:~::-:en _ _ t-
\-'-S133? _l:.::: _:5:>l';_:"
-:-7-:-:-:- : '-
:!::7-f:r:;::;:`'L::;::'f.
l:-:-:--:-'.-:-"-'-:-:-"'---:'
""t '-`_~:-2-;-1':-. '-_'-1--:-:-:\';.l-`!-___. wf-I-:~-:t'-'-" - - ::--:-F;
~ `:--"\:_
~;---:-:-'_<--:-_ :-:-:-:--' -x-:-,:- :f-:-_-_-:-"-_- ._ su-:~:_-'
_ f
'-~<-
I-:-:-:-:--:
:;.:;__;:;:;-_:;:;:}:;:;.;:;::_;1L-,\ 'W1 _ ii #5_\_:-_;:;r;::;q-:;::$:-_:3:; .t '2-2.* ` tt ._ ;
`:7;L3-
_ '-2-2-:-2.-2-T-___,;" '-:-1-;-,_ _ \,_"
_
53'-'_ Sf 21;,-'I2:>-:`~`:. ':l;l:'7:2
_- -:-_-2-:-25;-_
:-:-:-:-.:.'-*'--_- '-:-:-:-_ -:'---_- - _:-:-:-:-:'-:\,
-:~:-:-:-:-.-:-_<.
,-_-.-:`~:m
:-:-:-:SIR
'-:~:-'-'._--
La versin 3-D de
Toledo Javascript Chess
'--ii' - \ ' -:-:-'.32-2-'~:-_a,--;-'3"_- _; ""-:- - -q=:-:-_\'-:-'-:- _; :-:-:-:-_HW'- :-:-:-:-:' `-;- ' ' -'-2-5'-`*'\
"'''- * - _ !7'' _ l3'-_<-_ "t'?!?;' '~`~ * '~_ 5' - 1'?-:::::_"'~:f:_-"` "'-':I3"""""__. 513131111 ` "")'
'Ff -` ` 5"-';'_"'R ` " `::`-_. : 21:- ._-'- :::-"::f"';:' 6131315 It' ' -`.""F
::'-f'$`
_~___; '- _ ' fI'_.,c__;-__>;;
'",_-:^;;:;_5:=:1e-_
.-"~:- '_ :F: IIII-:_
-:;;__~---f''_ -:E..{
f:I;:I:>.`,~__.,~" -Iiifff
_;'._ "'<-_ .-"..\'`~"f'3f.i :;_"-
1215:-
"-':-_~::-t:;;;:;::;_;r;2::;:;t::::I;>"-* "-__-_?,-Q
-- -2- " ,: '- '-;~:- -* :-:-:-'-:--'-1-:~:-'-:-::-:-*;-__- __ "
l;_-I-1-'4. ` . ' .1'..- :.;-;.;;___
-se
-_ .hs-'f!* ---.' ____`3_._ ' ' -_.2 -..,_ __. -_;._.;f-;.;;Z_';.;.;;_;__ ,. _; ' _ -R-.
':-1-';.-::c--_*-,--;-_
:-:-P-:lt-_:
$:1_\'-_-.."'_; "iia
"~':::-5"
:- _-' ' _:< Q-2-:-:_~-\-_":-ec..
- .:- -:nt _ _'-gr-;-:--.W-;\ ~:-:-:--'t;'-.*.-$~_\.
1:I:=:?_---'=.-"'_-;1-'
_' ; - 3'-:P 25:-R-s'-2-'.<-:gq
' _.-1- _ -I;+~
hi* ' _.-_- - -f
_ -'.-;~ ~:-:~.- _-.''
.:`:.- --'L-
-
_ 5.'-ir-iv
2-:-:-::-~-::-:-:-:-~~:~:-'
'~_\_ _ - -:_-::-:L-1-:-::-:-:-'
-rc-;:<:c<:.-:t ~:-_'-H..
_-:-:-:vr--_
-r::-:-'-:-:: '-\-_ -0_-_ -: ''
' _ --_-~'1511:-ti':::f:f:1:S-:i:
'--:I: -\-`_`::'-::';_\ :1':fE::_-:;:;;11;;-;f;_-:{:j-' -_"-".\__ ~'_ ---r;;,;__j-'f-_._._;gi:_;l' _ ,-2.; -l.:'-'- -_)2-2:-::E:1;:::;;_5:;Et:._j::;
'I' JR
uk
-_-.ff
de Latvia por
:: :_- ' :I:f::~:1-:-:-:-:-:-:-;-::-=:-:-;:1::- *-- .:-_-:Ji-_-_ -g-_-1-2-1-:-2 -2-1<-:-:-:-:-:-1-:-:-:<-:-:-1-1:-:-lb'
':_ :-':-_- al- ._ sx.
___-+:=':"<5':^1-*'--tc'\"SP:i:-:-'F' _-
-~_===.=`==a?at=-=\ _ - -2s--t<=;_ats.s_t=a=ass:-i==s-_~.f s=;=-:-*\-*t 2*_.;-'-=^===;a=;=;==a_-T=1'`a= ;=*mu
t-.~-:'\^.`"':1-'*:;`"'-;:i:<-:--.-__t.1t_ -\'--
?-=-~==_=:\==;t\.-r:<=;_='z; .-\
-_'lt-!:"-'
-.- t "-*""' < :"`-";:-:' : .>' :-_f'
H
- -.-:-_-__~_2'
aa
='i
-=._`"\
r_":*_===;'>~:'_=_=~__ss2 x ==?=__--m>
ir.-'_ Chessforeva
-SEA!3.2311^I`':\1':fk-_-f'f1tf__-1 :: H ' -3' I' 3 _ ` _ ' __ - -I--E-:EE-2:-22:: 2:52: '-1:1." '_`ff::: t':: - '- "
_-;?_-_-_;;_;..,__,_;;___.;~_-
`- '\`\'-'-'.-___ ?:-_-:-;-._-_-_-:-f----\_-:mi_-_-_-_-_-_-,_-_-;-:-_-:-_-_-_ ' _ _. _ ___Iii:-c-ere:af};3}::-::--:-ii;---i-:-:aa-ai

5.2 The JS1K contest


The JSIK contest (http: //js1k.com/) started on Monday,
August 2nd 2010. It was organized by Peter van der Zee with Thomas
Fuchs (author of Scriptaculous), Remy Sharp, Patrick H. Lauke and
Christopher Williams as judges, all of them expert Javascript
programmers.
The contest's objective was simple: The participants were to create
the most impressive Javascript program in 1024 bytes (i.e. 1 kilobyte)
without using any external file. The contest period closed on September
lOth.
I received news of the contest on August 8th and I felt inspired to
tackle the challenge of writing a lK chess game in Javascript. So in six
hours I managed to crunch my 2.2K Javascript chess game down to lK.
I had to remove castling, en passant and limit promotion to queen, and it
broiled down to a simple chessboard with letters for chessmen. The user
could click on the origin and target squares to move pieces.
The next day I submitted it to the contest, and you can still play it
online today at http: / j s1k. comldemo/ 226. Take note that the 1018
bytes of my Javascript code include an artificial intelligence and also
the user's interface and chessboard visualization. Not an easy thing to
implement, as noted by several people on the Intemet.
Two hours after publication, the enthusiast Laxminarayan Kamath
sent me an e-mail telling me I should use Unicode graphics and giving
me an optimization tip that I would use later. On Wednesday the llth,
after another six hours of work I cut more than 50 bytes, freeing up

142
Toledo Javascript Chess

enough space for me to use Unicode graphics for the chess pieces. I
sized up the chessboard for comfortable visualization and I also
illuminated clicked square. On the same day I sent this update to the
contest (it was entry #298, available at
http : / /j s1k. com/ demo/ 298) and the graphics surprised the public.
A few days after, Spaniard Romn Corts kindly shared with me
some optimization tips for saving bytes. At the same time I rewrote the
artificial intelligence to save space, and with the extra space I
introduced variety in the gameplay (Math . random) and also the instant
update of the chessboard on the final click. This was the third update
(http: // js1k.com/demo/ 435) and it received a multitude of
excellent comments, hundreds of mentions on Twitter and thousands of
visitors from American, Spanish, Chinese, Japanese, Russian, French
and German forums and blogs. I've estimated that this version was
played by at least 25,000 people around the world.
An anonymous German reported that it was easy to force my
program to fall for a fool's mate, and I realized that a few extra bytes of
intel1igence would solve the problem. I also implemented the
illumination of the last moved piece. This was the fourth update
(http: //j slk. com/demo/699).

On the same day that I submitted the update, I casually received an


e-mail from English Matt Round. He informed me of his article about a
game of my chess program against the legendary lK ZX8l Chess, and
my chess program called a draw instead of giving mate. I knew
irnmediatly that my program could be enhanced, so I was on the job
again, and it was very difficult to crunch these last bytes (here I
finally used Kamath's optimization tip). I did it and that was my last
update (http : / /j s lk . com/ demo/ 7 50) before the contest closed.
._`._.- --__., _ _ _5Sm"'
H_ __ __ _,_ __ _,-.- -_ _ ___ _ -f`._\ _.- _ - -Q- __:-if'-::-'15'`5^*'*""""'5';5'5`:~-'5'-:'^f''~f~'"-55%'-If;Lt'-l'7f-::5'f'-'~^:>;:-f~f^::5"""-:::*'5-f-*51555'*'5''-^:':`~f5ref::-"'
-.-.-.
_-_~_'-_._~__._ __; _-__ _;-._-'_ _ , __'_____..'-__ ____._ _ _' __.. _ ' __;.-_^ '^_"iv5-:e5;:~L5ei4'9555:-"-"5-5-H-L
___, \\f`_{* " __ -_ '_" 5

__ _ _ - __:: :_ _ 1; _; .;i.: _ -_
'-:_ __-__:___`__
-;_;3-:1_ss-:$3
_5<f$r__1; l;41t:4si95:; l2'?2l;__;2;2=l$tlle__a_igfs<s_5;; =2;5;_; ; ; ;; f.__;.;_::; ;;_;_=;_;_; ;_';_; _;_;_;1;:==_;-;_;__;__;_f3$__;-_;_;_;__;___j__
19. ,.,,,; _,.,_._.-uf; __..,_._,_.,__. ,._,

'^'_=g-_=__i'_a-____:-; ___&_f- ^` C5 -3-_ -__:;_' -_____;_;_'_*_TH_fal_:f_'__'_'F_Tf~ 2_af;-_`__a_;~'`e_- (13 __?-fi. gg __ _-5-__.~,g;_-.~_~::


-$5 -- i- 5 5 _55:'5:5:5
'_ - _ _ _ _ __ ___.. _ .___._

__2*1`-'-?|:~u1:n: ' ri-mts vw; -'-f5-`- J'11e1'n1s*' ` - ` " ' ll '` 1'-'s 2 +2 W 0:1-ee 55:. ` "*L't:--Ji "sam 5 5 55 5" 5' 5 5 5 5553

15- J lll HW WW im 11; sab. :ll amm wbwmsmnfzz-03


'Emu ik dem.-1|buH1-er 1.1. :dr s hi-:C ,\,_,__, K.-___m_ S-_,m_,_ ___,-f,_ f __-,_; __ ____.__ _W_____,,_m

_ - - - - ii- "^-15 - -if-I'l';'';"__ _ __ `_*5-5I;:;J_`-i`~': ?__ __ ` __ _ _ _-__<I-':-*'-f;r;';:__-r- >.:_:-'-;-_'7-r-:F3-'>: ' __'\.t'_-:L-'*_:_':-2; - -- Q_f_1-29;-'~_:-_-I;''? _
1555555: ''=*>-_:-_-1:1..-,$12
5*`3L!?*5'5 -b. :-:_^ _-; > -- __:-_- 2;: '-_:-,F- flil-
_;-l n- i_*`-M;_-_. ll'* _ 1 ___ = .nf
-E=1<" ' _- __""
_ -' ___ _ -1'_-_-_-==i_*- `;_w.---_
'=:I=_ aa? 5 _-_-_;nz-_: -F2?
-: - Jl-.:-:-7-;*.*.'_.'-I ' _- - _ f-`\IfT''f/.-'- -- -- -- _" '_`<"' .r^~-_.'- 5; _;f/:f:f'_l "" ^ ' - ` `\"::;- -'13-ff _
-_f-_'-_~.;g_-_ _~::-':<m: - _<-:-_\t-::-:-';-'_<-' - :~^-'-_14_:ff- -- 5 - $199 <;__ __ - _ -l-':ff- ' 1 :-_-._f <:,__-5 _~__;-:-______-_~,
-_==f-s-:__~ r_-_-:
_ __=_~;:-+_1'z5:f-- _ - ff-_;-f_%:=-'
_ ___..__ f'5;- -- -- _ -'::i'-_--_-_- _. _ _ -_ _
_ ,_ _ __-Y
~,_ - _ _ __, _-.fi __ .::>_<__ =-_ __. es _ ._ _~:+:::-:::-:-: o
-E-_-__'-1:-_!.{ - - _, _ D -_-__?. _ _ _.-p ._<-_--.>_x~.-.- -- - -'---a=_-.=.--\--f- _ -_---/- _~f-_..----1t-_~_- _.;.;
"l ' " - -_ - xf -,rr - - - __ _ _
__ __hi; _\',__ :f-E' :_-,_'
- .02 ._ 311:35592 `\" `:-;LEl-E-' _`f __ 5'- _-
a.- -: _ -;-:--:-1% 5 - - ' - +_4"f'f"'~:'f'-Fl*
':,_-ff 1>~;'_'- _ :__ _-:-'-'f-:-"
:1~:;: *-:ll-'Ze
l;_1`_:: - ' - : :_:_.__:--.-_~:
. "'_ -_ -t- \ __ 'I
`31_'_'._f-:5'5:
1-F
;_ _ :-:-_-^:`f
- ___j___f___._ 'i':
-'-I_r_____ _ _ _ .m : - H-_-.32-' :J:-12.2' _; _ -'^,;7'f~`;:-:*-
_ ____:{______
5_.-_-y_-__- _ _ _ ` __ 5'5 `*"fc_'-1 I
1*; ''_i:`-- ' 5" `2^ '
__ _ -_-_. _tu___ __-P.
`:__ ,5'
af
__'_ __ ' L _' ' "5' f .f;' - $'~"""' "`f_-"f'- :-:-1-I-'-_:':f'--';;;_
_? 'p -`=~";'5'_E-5 - - _ _ _._\- _;1'IK_- _ _ W.-;-'2 _
- - _ ;-1-;._-;-;-;-' _
1:1 - - " _ - - ' ` ''1:;:: - '-l- _ .f _- - ` _ I. T .i _ ' ' l- _ _ "_f_ ~ 'f _' -.- _.` ' - '- :-:-:-:--:~21:1;-: u
:__ _' 221;".-:iz:-_-az; _ -'___::_:-_1_4_'-_t-_. '
__:;___________:"1':"_"" ______,_________ """"*"'_.____________""""`*'*'m,,________ ' :_:-'z -
_ ;_-_'.__-;t_5f-_-f - .5 __ '_!! .at ~ ~~
l ;,____';_'_g''1'.5- - -f - -;.; __ ;;f-_'-- _ _ _ _ _ ;-3 2' '_ _
:a_=::-j.-_\_m.'~__:___^______ _:-nit:-.:t__;.;_-_-r; __-____-_;-_-____,,.a_,,-1%:-:L-_cz._____ _
-_ _- _ _:_ _ _ _ ;__-:;'_-;- __ ,_':-:_:
___-` ___-alfrl:-_-_:_-_'f_4$';-_ f -
_______i___
-'._<:;:-'-_;
` t e
.;. _.'_._Z _'__. --___. '.__-__.'_ 55;- - -_'__j,_.'. .-_ --.- -'--_-_-,ft _ _ __ _-_-__-_-,_,-_ - _1- _-__.._;:;._.;.._ _ __ _ _ _ ___;-_-1-___. _ -_. _ _ _-_-,_;_-,;, -_-__,-_-_ __ '_._
:--_~= f -:__-::_--'
.'. -W---: -f--- 1: -5 i'~- -"'f_`;'_>-::::'fx-_-_ --
- _-'_' _' 5:->
S.-__,~l'_ _
'II' '_ _
_>__-'-.f-_-5-_` 'I`1" ` -L.'.'_
-
' 5 - " =;-:-:r:.,s:#_-:s___:~
_=:$e$=''=5:z:-_-_* _ __-___:-` _' *-_-_:-_--if.--_f_-1'*
1. \ 1 -- f>_:- '-2%_-%=?.%**-"_ - - -?_:-_~1_5.f!:'__i. '_2.-';
- f -__-'_-_---__ $ Isa-,ll
m
-===
_ -- - -
-_-_--_-*f<1-5"!_- _ ;-_-;:_1_<;_-: 1:_ ___;_ _; 1=: .'<:-_-i: _<_f'2-:%; :==a:-:_:-:__:'-:_.: :_- _ __.:- ----:-::
.-._=.-_-_ :: ._$::_-_:_-:5f_f,;:__f:__-:::_: _. __ =-$f_:-:-_.__-;
_f'f_:5_f_?'__,2?"?<i:_<_ 5 - '__-__-__-=f:__-_<,a'?=f f:<2::_ -=....,_.4
=i=i=i=:<==r_==5;-
' :_ 1-_::-_\:-:flq _ _ _:;__-: -*-:_<;_-;; : _ _ -:-3::-___f_;';g ,:rH--ff.-_
___; 1T J--25115;__-_ _.._;,__.-:_{_
_)__<-/___.-_.
f_.,;__;;:-:-_;_~,_ -3.+.~;
_
;_::`_;'--'__.-
_- ___-_ __,_ _ ._._4._ __;".' _
_ _' :-_-:-_'-_-'-fpi-l _
,_.__-'~ _--f
-^-_~:'-';'-\'-'--.
_.._.._-__--
` - - t;-L-!-I-1-:altar:-:-:-1-: :-:__:_ $:-:`_::;-11.-:vs-:-_
__`_.._._ -__-_-_-___-___-_-- -
'_:'_'_::_:: s5.\":-a$_'-:_-- ii:-:fi ,_`._-__.__-Y
-._ .__._..___-__..__..-_
- -` -- ._._.,- - .(2-L-:w;ca:_:-:all:-:_ ,,- f_\-_
_; ,
_;._., - 4 .- fr --_:--_-_--__-_f_ __., ,,___._-_- _-_----1'--,_--_-__-_--_ -- -- _ - _-__--fl2f!.-..- _--\
__ __ _ _-:-,..,;:,-I" -x _;-___;-1-_ _:-_:_ 9 -_:-'M-mx _' _ .f_.-...fu ._-__'___j__;,_$'j_;-:_-__1;-_'_jj-;; __-'_'._?'.-;J_-j-_f_j.__ ___?.-.___.;._--;`-.; _':-'1'____ -__
_ $
""'_f'?li_`f_:" ' 5:' $':'rf'?'$':__ _ _ _'-F *:i:ff'fS>' _ -:f:'_^i$:-'-:f_; 1 );::?_-:':_:; _*_:_:-;'? _}; _.-:$:_1_~_'_~1;':;:j 7 `_'___l_'f- '* :-:g__-;-:;';'
f:1'}','`;';'-'i_ '_ ;-"\`^_`.;-'_;2`- 21';-';t.5:-'f-J55 "^ -;:5:`fl"5`157 '::':' ' ' ' __'::'::'_ '-5'5_:1-+9: '' .f_ ` " `:t-:f`^\$_ -_-:-'~_'f1:'5 " 1 '5 0 `-'!-}-7'5:<`_-1'_: ' `\'-1:l-:_-_-
:_ f.-pr-_-v'._..,.,_.,___.__
-_
- -:_*_-:-;-:-.i:-:_-_-`-.-.=~m_w-~<
: -*-_~.'' .<-;-;-:;-'
_
_-: - _' '_--'<-'-lf;- _*_.1'/--W
- -;_ - _ _
_ a..*__._:'
;''1'T+'f_ --w- :- __
__..__;.:_M
_:-.~'_~'^>.-.-
__ _ ._ -L :_-_-_-_.-_-:h
~';: _- ' *--f..'
- _
_';.'.;_';,.; -
I5--M-_-_-._--._-_-\
_
- _- -_
'';'_r_-Ig-'_-I__1r2
',-:- _:__.;f-'_-3;:
,
_. _ _ .______,_,.)___ _ _ .__ __.______-._ - - ._ _ (__, _-___-_ .f _ 1 ___.~__ ra mi _ -' - Iv .'.".v'._EE_~<\_-'_ _ _ ;u,'.'-'_'\'_'.'_'._f'. ,--_-\.-- -_-
_-; _ P 1;-4 P :-;-;-_f-,__,':-+ _ mi-.F-,;; '5_- 1 _ __ __ .'-_ ;.'~;::-:-H-.f -: 551.-_-:-:
1. ;;; : --\;;l';`.fJ_; _ _ '.:'f'.^ .I *Y---1;_-:-'I'-I\'$ . P ' 5- _~\$" 1 : 2
__ :':'ri:-""'5';i::::I: 5 ';-,f -
355-12-_'-'I 4
___::5_`(,-_;:__
(_: "f;-. _
- jj',--':'4`_-_
_
_
_ -"-.-:-_-_*-_-_~::-_-
'.51:'_'I5'55.;:':5:;_`_5
.---*__-
t5-72'5':5:-__
,;-; -2;:_1-i,,,__:::- :::_ ::::'f$_EE)_'-__;'f"::: l flglg 1' 1 __ $:1;$:::g:F_:_:_f_' __ _ ____f:f:;_ _-,f,__'ij_l __ _ _ - ':- _[::_;;,5!j;2-;::_:_:`___-__ ;f''f _;`I':`
-_- , _-, 1. _. 'I->_.- --.-.-_-.'-' - .'.'.-,-' lr- __ _ 5.- ._ _ ..rr f- ;-_-_-H. .-1 -1. ___* ' jg.-...-_ i-av __ __ .'.'_' _- --_2'.-P._.* -_- .'.;'._'-.;;.j-
'=:`'fif5-`' -\ '5lf1F2-`=- --'I-`_1?_. B` '-':-:_-"-1:23-' *-`*1_' _ 5.-- __;=s:s*_<l_=;`-:;1:'.-=2:;;-- =_=1I111"'===13;z:=;-____-_-_-_;;;- -111'_'""1='11___-I-:-2;@-_~_# - -1 ':_'_f_~g___f_::$:-:fF:' :' $-;E-_-::-:--:-_-

Mi primera y quinta
{ _.;;_ -__-_-_:_ A -.;1_'______-__\_-_. Q __;-3.; -___\ _ _ ___._.,_._.,,_._._ ___ _ __,._______.`._,,_.____. __ _,_.,__,___,__._._.,__._.___ _ ~ _. _
:'-:'<'=='_5__-=h_ :_ ==v:_=<:<:=='_=_= - - ':'='==-kvr-5 "-^'~f\-*-*':'< ' 1 5'-_*-' 5'-?;\*;__;"=f__'f`-"E1-5-55' ' ' " M __ 1-;;'_'};i'*"""<yl_ f ' :'91-fif z-=f5f=*`=: ' '
:-}'$5`*5 `::#_\:':':'$ -- ':?:1I'::'_f_'_~_ "_<,--:_ ;`-_i;_:-. l l-1:1;-_ _ ,';_f;_`:5-fi',-`I_\''iE-_:_; '_ _ _ _
__.5511555
_/ _''-''`f'2` __;__;__2_-E_E___E_'_1__.$____,_F___.
__;i;E;;-313251 si_ _11_=_1___ _5-___.5_>`;_.-_;__;';_F '.__$__.__..
*_;_ 1 _ -2;HH-
-__z_::;_`:';:f-r_:__{_<_:$,.____
_: '- :V _ _ _:;*;_=~`____`___-'-;'=-
"==`=-~

entrada en el concurso
l _ -___ ...'...|||||.| ||:_____jf _ _|_| ' _ _ _. '._ _:_ _: un |.-._.|||||.,,

. ll =;f_ ia: _'f_'_-a5.~z :''"-_f.;:.<':: :"::_'_= ~- -_ Ea" *:'s_5': f:':' - 5- 5-=l=_1->al<:5l:'=:"= 1'-":':
I. W _ - __ :::<-:P_x-:_:;,;':~:;: - -_ ~':5';,'__9:\_\:_-;:_-:-:;:_ - ;_'-"-:_:__;a'-\:-r:
-_ 1 _ :1:}_ 32-' ';::-::': _.:_:;_:{a_>f:_`_*:_ Q; _:; '-I5;:_ _ _-__I- _^ __.; _'__:_-:_-:t_:::i
'5
:-.
-:: :_: 5 -5 l''#''-
:;$f -* ' __ ;_;:
1 - - -1 'P_:;-i_g::
:_: ;-.'__-\
-1:1.-'5_>_; -' 1 'I 11 1 -
'-'--~:;_'-:-'-- _ _: : _ _ ,-':-
~' ' '_
-- -
_
-- -- _::_ _-
2-U.--^" _;':.;2-;: -_:I_-_-
- _:--_f-:__-'-:_
-
5, '" "' w'
__-fa
" '-
-
__
___-_-_-_-_-v-.1_v.-.\-_1.5.-F..\g_\15-_-...-__;-_,,
_ ..
___:-__-._--_ -';__u~:_'.__-_~____ -__-,;\___;_;__~_
~ _C4g.\\-Z-~._-_-y
_ :" 1 1 ' f;-i:=ld_1-aat '
_:_:.:___-_-_-:-:f:;:f:-2-:-:--:Fw-4-w*';:-__.'-::q;--;:;_'-:"''=";_<<"ti'E;t:;+f;;lz2$=2F=f**=`___.__-___.-`
'~'-=
_-__ 5-:mg1;If'
-___; :1:"->:';';ga_- : 5 =_<_f
-^;::_:'-_: a=_f-f=- r-gg-'
J--_\'-'
__-_; ;' fa.- __:_-'_
-_-__ - ff
.".'. _. ._ _

-
.J __ _ _

.- .___
-w

-_ ,_'_
_-_
-''-'-'-'H' .

_ .
-I _ ...

n=_~;~'j::f :;:'f'_:;'-,
_'_-- _::_f: :
_-.I
.-_'- _

;_='_;.-___-_;
-'
--__''_'_';:*_f_F; " _: _. 'at-: _:_~:-'_-:;:;f;-':>_'
-=r:\;l:'_;-f:-;s_f;_-__;
;;'_~'___-f_:- _
--.ff--_-_-_ '_
_-:... ......---:-.-

- --Y'
'_-.'..'.-.--_

-f,f1'-.^-'...
.-.-
JS1K, corriendo lado y
-._f_.~.:_j.-._.*_'_..._.._ \_-_ '.'.\ .'_'.__'.'_.:._.'.;.. ___,._. '\ -._.' "_._ _ _\_ __ ,\,-,\__-_-_ 1. _ _ _____ \ - -_- _ bj __._ ;-.__ ._-___ _ __-_ _:_: __.. ._:_-_. ___.---_ _-

'_.___-:-:-:---;-:-:-:-:'
- _
:-:~_-:-:-:-;-_:-:-::-:-:-::_--\5-swf-:'
.__.~___. __.________._
-
_____
-'-'-*NR- _
-'-:-::-:--:-"'._J_.._._._._.._._..__.___;.)._._._.__._...wn-I\_.____
__._{J___.__.._}_`p_-J_`__`
-
--_-:--.u-:-1-_-1-1-f-1-:Iv4;<_2-'~'-;-;-_:-:-:-:-:-'--'
- -
_ - \_T__-;;_,--;-E_;;___-__~_-:--q|f;g___-_-13:1:9-:_:-_f;1_:x:j_!~,-_;_;
'f-:'r-:im-F';:`fI:T. H-'-1.-*_'-.l-`'f*" -::;fi'-11'-4591:-}rxf::<1;*"'1:"`:""""*"W""""-;P*"~:-f-'-
_
1-:+32:-:;:;___:;_-'
_-___
':
\'-;:-'-'-'\'-11;:-::'
____`_____________1If_\__`wg=_
__
_. ___._-;
- _ _ -_____
_'
.___ __
\`-S'-i -"i"' $j`-,~f;-;_;,-;;_5___P,-:',-:-f-
_
-f-5;_ '_ __
_____
'
_ _ _f_se-__
_ ' ' _.;`
__________ _
' -'::i`-:-:-:-1-'_-2:-\'.|:~f _ 'Z :'::::' "
_ -
_ -nn; - __ 1'= :_-:_=_
\_._.
:f_':'.-:-:'_' f4_`-`#
_-:-__--_'cl. _ _
_. . _ _
' :
_ _____
' *,-;;-;1!_::-;:-::-:
_
1;.-,_..-:;:_I;_,_
_
'
_'f,l.,_,_,__\,
'+'- -.;`_-;
gh'---.j'{-'
3.-.)-_--_-'
if:-::1:-1?.-':2:f:>
lado.
_-_.____.-.:_______;;:ffr>_f_.xg:v __ gq __ ._ _ . _ _ _ _. -.;.;;.;,;;_;_;
.;_'____._.__._.'..'-_\._-___.'.'_'21!-_-:._.-.\..f->,.,._ _.__-_`___,.-_-_ *I-_7__-_ -_.__,;.-,-.;.-_- - _ '-;-__._
':\'_;_;IgI'_;I--;.'-'"-"''--'-L-1-__'\II--'-_'Z^'~l'jj';I__
:-_-'-_`-21:1:-_-;-.pz-:-:-:-:-:;-:_;-_;:-1.555:f:f:fix:1:I:1:>;I::1:;-:_I:f:ft;:-:-: -:-:-:-:-::f:f:1:;>11-:_-:{:f1;nl_{_::+-+,:-&.;-wtf;L:%-mi
__'-.""'f'1-'-Ljl;.I'-'>1"5=9 4:.-_-'-_-_'!I.I.-_-Z_._.--._-_._;.___' -'\_\_`\'-'
li-si-:=~r-:l;f_:_l '"__ mx_
'\ \.'~ 'I-5-'-l;__"5. _ __ _ ._ _
;__._ _
___ _ _
_ _ _ _ _ _ ,_ -
-_; .;..-
.*f{-_:__-___-'f
-;__;f

:-_.: ;- ' - " '*1:1;`:-:f-' -1-1.-:-`: '*'-:-l:r-:_'::'";rI'-'-"i:;i_1


-I':.'~'-I-1:':'_'_::'_I-":;i'ff:1:1:1:1:1:-1.2.1:*I_t'-:_;f' :;:;f:1:`:`-":'::^:-:-:::f:f:=::-:`:I: :="::::`:`-:::;:j-:':-:'-:I-:':;::f:::f::1:f:'::f':i''f::I:I::;1:I:;:f:1':f'.22-_-:X-_i:l::1:f2:1::"f :::11:~'
-_f"'_':_lE-'':'-pi ;II::1:_-`If.I::f-j: *::-'_1:':'_ _-:f:I::1:1:`__'_._I:`_4::_-::f'I'1`:';"L1_:_-:1:='I:-::f.'::1'..j=ri;:`-'::='f:I:`::=:_'-`=':`:':::_:':1:':?:I:=:`:f?'f?E=""fui-Z!:?;7:!<~- l51:E':

143
Toledo Nanochess: The commented source code

And it won! On September 25th 2010, Thomas Fuchs and Remy


Sharp demonstrated the winning entries in Berlin, Germany, during the
jsconf . eu conference. My Tiny Chess program earned 2nd place.
After the JSlK contest Was <<slashdotted>> (this is hacker jargon for
being mentioned in slashdot .org, search for the article "lK
Javascript Madness"`) via an extrapolation of recorded visits to my web
site, I estimated that at least one hundred thousand people played my
Winning entry.
Although I'm the author, I still feel pretty amazed When I see the
handful of characters that make up the program. It's so small that it
almost seems impossible that it actualy plays chess, albeit in limited
form.
// Tiny Chess. (c) Copyright 2010 scar Toledo G.
for(B=i=y=u=b=i=5-5,x=10,I=[],l=[];B++<304;I[B-l]=B%x?B/x%x<2\B%x<2?7:B/x&?0:l[i++]=
"ECDFBDCEAAAAAAAAIIIIIIIIMKLNJLKM@G@TSb~?A6J57IKJT576,+-43HLSUmgukgg OJNMLK IDHGFE.
charCodeAt(y++)-64:7);function X(c,h,e,s){c^=8;for(var o,S,C,A,R,T,G,d=e&&X(c,O
)>le4,n,N=~1e8,0=20,K=78-h<<9;++O<99;)if((o=I[T=O])&&(G=o^c}<7){A=G--&2?8:4;C=
0-9?1[61+c]=49;a0 ifta(R=1[T+=1[c11)aa11c|A<3||(R+1^)>9&acA>2){f(1(R-2a7)
)return K;n=G|(C?T>29:T<9l)?O:6^C;S=(R&&l[R&7|32]*2-h-G)+(n-O?l10:!G&&(A<2)+l);
if(e>ht|1<e&e==haas>2|a)tr[T1=n;I[o]=o;s-=x(,h+1,e,s-N);if(1(h||e-11s-o|T-b|s<
-leellreturn W(),caasetTimeout("x(8,0,2),x(a,0,1)",75);I[o]=o;I[T1=R}if(s>N||h
&S==N&&Math.random()<.5}if(N=S,e>l)if(h?s-S<O:(B=O,b=T,O))break}while(lR&G>2||(
T=o,(G||A>2|<?o>7s=o<41)a1Raa++c*--A)1}recurn-K+76a<N|aa&N}funcuion w({i=
"<tab1e>";for(u=l8;u<99;document.body.innerHTML=i+=++u%x-9?
"<th width=6O height=6O onc1ick='I[b="+u+
"]>8?w():X(0,0,l)'style='font-size:50px'bgco1or=#+(u-B?u*.9&l||9:"d")+
"0f0eO>&#"+(I[u]?9808+l[67+I[u]]:l60):u++&&"<tr>"}B=b}W()

Exclusively in this book you can now read the indented and
commented source code:
// Tiny chess.
// (c) Copyright 2010 scar Toledo G.
// 2nd place winner at http://js1k.com/
for(B=i=y=u=b=i=5-5, // Simply to say Biyubi and initialize to O
// Variables 'y','u' are unused, 'i' used twice.
x=10, // Useful constant
I=[] // Array for chessboard
l=[]; // Array for common constants table
B++<304;
I[B-1] = UJ
dP x < 2 | B % x < 2 ?
// Constant for chessboard frontier
mdp.. U3*-l`-~> ><\-J x & 4 ? 0 // Empty squares
: l[i++] = // Put a piece while decoding constant table
"ECDFBDCEAAAAAAAAIIIIIIIIMKLNJLKM@G@TSb~?A6J57IKJT576,+-48HLSUmgukgg OJNMLK IDHGFE".
charCodeAt(y++) - 64:7);

// Workhorse function: search move, checks and does legal movement


function X(c,h,e,s)
{
c^=8; // Current side changes
for(var O,S,C,A,R,T,G,
d=e&&X(c,O)>le4, // Detect king in check
nf
N=-le8, // Current best score
O=20, // Current square in exploration

144
Toledo Javascript Chess
K=78-h<<9; // Optimized score for fast mate
++O<99;)
if((0 = I[T = 0]) && (G = ^ Q <:<`7{ // For each square with an own piece
A = G-- & 2 ? : 8 4, // Number of movements possible for piece
C = O - 9 ? l[6l + G] : 49,- // Pointer to table of movements
do
if (1(R
(ita = I[T += 1[c]]) aa
sa tae
alo | A<3 // Move piece and check if empty square
|| (R + 1 ^ c) > 9 aa
sa G A > 2) { // Or valid capture
if (I(R
(Ita 2 a 7)) // Capture king?
return K; // Return checkmate
n = G I (C ? T > 29 : T < 91) ? O : 6 ^ c;
C; // Check for promotion
s = (R te
aa 1[R a 7 \l 32] * 2 - h - G) + // Score capture minus delay+piece
(H O ? 110 = 1G && (A < 2) + 1); // Scoring for promotion or advance
if (ele > h // Still plies to search?
|[ 1 < e & e == h && S > 2 | d) { // Or time to do quiescent search?
I[T] = n; // Do move on chessboard
I[O] = 0;
S -= X(c,
Xtc, h + l,
1, e, S - N);
Ni; // Search yet another level
if (!(h || e - l | B - O | T - b I S < -1e4)) // Legal movement?
return W{)
Wlf // Ok, update board
c && setTimeout("X(8,0,2),X(8,0,1)", 75); // Computer will play
// Note the '2' that means search...
// ...to 3-ply, you can increase it.
I[O] = 0; // Restore chessboard
I[T] = R
1
if (S > N // Better score?
|| ah
th a s == N aa
sa Mach.ranaa()
Mach.randa() < .5) // Or same and root move and random?
if (N = S, e > 1)
if (h ? s - S < O // Alpha-beta cut?
: (B =Ob= T, 0)) // or annotate new move
break
}
while (IR & G > 2 // Continue to move sliders
|| (T = o, // Reinit origin square
(G Il A > 2 | (c ? O > 78 : O < 41) & ER) // Double pawn move
&& ++C * --A // Next possible move for piece
}
return -K + 768 < N | d && N // Return score or stalemate if not in check
}

//
// Chessboard update function
//
// The main saving space thing here is that the entire page is updated as a charm
// with a direct assignation to document.body.innerHTML, in my 2.2K Javascript Chess
// the chessboard is builded separately, here it is built and updated in same place.
//
// Uses a HTML <table> with squares of 60x60 pixels, filled with two colors
// for chess squares and special color for selected square. It is used an "electric"
// green color, casually to save space, but I like it.
//
// The content of each <th> cell (centers and makes bolder) is a Unicode graphic
// character for the chesspiece, uses reference table indexed by 9808, also uses
// 160 (non-breakable space) so a selectable character appears in all browsers.
//
// Note that font-size:50px is used to preserve
preserva bold style of <th>
//
// The onclick event does direct checking of own's piece (for selecting it) any other
// thing will try to move piece (start square in variable 'B', end square in 'b')
//
// Note that for each chessboard update the end square is put as start square so it
// illuminates last piece moved.
//
function W()
{
i="<table>";
for(u=l8;
u<99;
document.body.innerHTML = 1 += ++u % x - 9 ?
"<th width=6O height=60 onclick='I[b=" + u + // On click selects piece

145
Toledo Nanochess: The commented source code
"1>8?W():X(0,0,l}'style:'font-size:50px'bgcolor=# + // Or plays
tu - B ? u * .9 & l || 9 : "d) + "OfOeO>&#" +
(I[u] ? 9808 + 1[67 + I[u]] : 160)
: u++ aa "<tr>)
B=b
}
// First time running, create the chessboard
Wli

//
// This source code was always worked in fifteen minified lines, it was clear
// enough for me :P, only after winning I*ve documented it :)
//
// As you can see there are simply too many comments and tricks to save space and
// there could be more comments! for bit operations, tables, uses of variables, etc.
//
// I had to accept that this is a very complicated program, not for the faint-hearted
// programmer nor for the novice Javascript programmer.
//
// This is revision 26 of source code (fifth revision for JSlK)
//

You can find on my Website the crunched source code for the
version With integrated castling and en passant, coded in l25l bytes.
Por the record, I managed to create a version With castling and en
passant in 1024 bytes (yes, it is possiblel) but the visualization stays in
black and White. The gameplay quality is bad, it works as a prototype,
but it was not nice enough for the contest. lt is archived, so there is any
eccentric people there Who Would pay to see it? ;-)

146
Chapter 6
Toledo Java Chess

T he Java version of Toledo Chess was developed based on my


simple assumption that if the syntax Was similar, then it should be
very easy to do the World's smallest chess program in Java. Remember
that Javascript Was created by Brendan Eich as a derivative of Java, that
Was created by James Gosling as a derivative of C++, that Was created
by Bjame Stroustrup as a derivative of C, that Was created by Dennis
Ritchie as a derivative of BCPL, this latter languages origin being
almost lost in the dawn of computer era. But it is just a metaphor
describing how current languages are built on top of previous proven
languages.
It could have been called Toledo Oak Chess, as Oak Was the
original name of Java, but Gosling had an unfortunate run-in With a
registered trademark.
Toledo Java Chess is an almost direct translation from the
Javascript version. Being more strict, Java imposes several requirements
to the programmer, one of them being that a boolean value cannot be
used interchangeably With an integer. lt took me several days to get
around the restrictions of Java. Obviously it has somewhat damaged the
possibilties of an International Java Obfuscated Code Contest, although
there exists a curious 4K Java game contest (check
http: / /java4k . com).

On the other hand it is absolutely necessary to develop an envelope


for the program, in this case the Applet class that allows the Java
application to work inside a window Within a web browser.
The envelope methods are:
Method init ( ), used during the creation of the applet, in
this case it Will initialize the chessboard and will preload
the required images, Which are reused from Toledo
Javascript Chess. It will also start mouse service signaling.

147
Toledo Nanochess: The commented source code

~ Method stop(), indicates termination of the applet. For


this program it only needs to disable mouse service
signaling.
* Method update (), the browser signals to the applet that
there is need for repainting the graphical context.
Method paint ( ), called to draw the complete chessboard.
Note the related Z function that will update the complete
chessboard (instead of a single square like in the Javascript
version).
Methods Such as mouseExited( ) , mousePressed( ) ,
mouseC1icked() and mouse-.Entered() are all unneeded
and therefore empty.
- Method mousenele-.ased( ) , called when the mouse button
is released. The applet will check where it has been clicked.
Method getApp1e1:Info(), returns infonnation about the
applet.
Note that in Java the word "method" is synonymous with the word
"function", but I prefer the latter.
The source code as published on my website is formatted in an
awkward way and I worked that way, as Java is a free-form language.
For this book, I pretty-printed it with Netbeans, an IDE for Java
developing. Here is the source code:
//(c}20lO Oscar Toledo G.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;

public class toledo_chess extends Applet implemente MouseListener {

int B, i, y, u, b, Il] = new int[4ll], G = 120, ll] = {5, 3, 4, 6, 2, 4, 3, 5,


1, 1, l, 1, 1, l, l, l,
9, 9, 9, 9, 9, 9, 9, 9,
13, ll, l2, 14, lO, l2, ll, 13,
O, ll, 0, 34, 33, 55, 94,
O, 1, 2, 3, 3, 2, 1, O,
-l, l, -lO, 10, -ll, -9, 9, 11, lO, 20, -9, -ll, -10, -20,
-21, -19, -12, -8, 8, 12, 19, 21,
53, 47, 51, 51, 47, 47
};
Imagel] im;
static final int x = 10, 2 = l5, M = 10000;

public void initll {


for (B = i = y = u = b = O; B++ < 120;) {
Its-1]=s%><1=o?s/:<%;<<2ls%><<2?'?;(B/xa
4) l= O ? 0 : l[i++] l 16 : 7;
}
im = new Image[l6];
for l; b < 15; b++} {
if lb < 7 | b > 8) {
im[b] = this.getlmage(this.getDocumentBasel), b + .gif"l;
}
}

148
Toledo Java Chess
addMouseListener(this};
}

public void stopll (


removeMouseListener(this);
l

public void update(Graphics gl {


paintlgl;
}

public void paint(Graphics g) {


int x, y, c = 21, a;
boolean n = false;
for (y = 0; y < 320; y +=
40) {
for (x = 0; x < 320; x += 40) {
g.drawImage(im[I[c] & 2], x, y, 40, 40, n ? new Color(l44, 144,
208) : new Color(l92, 192, 255), this)
if (C == B) {
g.setColor(new Color(255, 255, 01);
g.drawRect(x, y, 39, 39);
g.drawRect(x + 1, y + 1, 37, 37);
}
-
C++ I

n = ln;

-I-:2;

3(`)*-' = ln;
}
}

void Z() {
paint(getGraphics());
}

public void mouseExited(MouseEvent el {


}

public void mousePressed(MouseEvent el {


}

public void mouseClicked(MouseEvent el {


1

public void mouseEntered(MouseEvent e) {


}

public void mouseRe1eased(MouseEvent el {


int s = e.getX(l / 40 + (e.getYl) / 40 * x + 21);
i = (I[s] ^ Y) & Z;
if li > 3) l
B :SI:
Zll;
} else if (B != 0 && i < 9) {
b :S:
i = I[Bl & Z;
if ((i & 7) == 1 & (b < 29 | b > 90)) {
j_= 14 ^ y,
}
X(0, 0, 0, 21. U; li;
B =();
Z ll;
if (y > 0) {
X(O, 0, O,21, u, 4/*ply*/l;
X(0, 0, 0, 21. uf 1);
B: 0;

Zll:
}
}
}

149
Toledo Nanochess: The commented source code

public String getAppletInfo() {


return "Toledo Java Chess by Oscar Toledo G.";
}

int X{int w, int c, int h, int e, int S, int sl {


int t, o, L, E, d, O = e, N = -M * M, K = 78 - h << X,
Pl Q; nf mr Ar qf rr C,
a = Y > O ? -X : X;
boolean D, J;
A...
Y 3;
G++;
D = w > 0 || s > 0 aa s >= h && Xl, O, O, 21, 0, 0) > M;
do {
if (ro = Ilp = Oll > O) {
q = o a Z ^ y;
if iq < 7l {
A = lq -- & 2) > O ? 8 : 4;
C = lo & Z) != 9 ? l[59 + q] : 57;
do {
r : Ilp +2 l-'
if (w <
g: 1])--^ != S ? O : S;
if H Av-
( HQ *HO-.,_l
| A < 3 || g > O) || (r + 1 & 2 ^ y) >
RR"'-* - VV CDC) W V tx) f*'

if l wHot
. F)
llo- 2*@
*-1 Qel@-_}_\--J.-' := 2)
2 {

Y ^= 8;
I[G--] = O;
return K;

El-..-I 0;
O & Z;
true;
I[p - a] & Z;
B
QH-m l"h rq>olEe=7){
t = n;
} else [
n += 2;
t = 6 ^ y;
l
whi le {n <= t) {
L = (r > 0 ? l[r & 7 | 32] * 9 - h - q : 0);
if (s > 0) {
L += (q t= 1 ? ltp / X + 37] - li@ / X +
+ llp % x + 38] - l[O % x +
+ o / 16 * 8 :
(m > 0 ? 9 : 0)) +
Q A l[p % x + 38] - l
- l] ^ < 1 ? l : 0)
+ 1] < 1 ? l : 0)
7 | 32] If- KO - 99
KO

+-I-l-++ Av
111!-''J l\)C21 l-'KO >
- U5
O '-/G--_-_-1 C)

+
>- "'- -'-.F_'|--' -. - . U
W
> < l ? l : 0);
III M
U
HH KO '- _.-1-Jn-\_]

}
if (s > h || l < s & s == h && L > z | D) {
Ilpl = H;
I[Ol = 0;
if {m > O) {
Ilo] = Ilml;
I[m] = O;
} else if lg > O) {
Ilgl = 0;
}
L -= xls > h | D ? o = p, L -
Ito + 11, E = q > 0 l PFV F
H ., , 01-* p, sl,
|_.I. < 1 & s == 1
RI'h 52" == O & i == n & p == b & L > -M) {
OWW
return u = E;
}

150
Toledo Java Chess
J = = m > 0
ll UIQ l-' --w Vd O < 2
|| X{ Ao~ C)I-`^ CQ;:: l\J l-*HA G nai si > M;
I[Ol = 0:
Ilpl = r;
if (m > O) {
Ilml = Ilgl;
Ilgl = 0:
} else if (g > 0) {
Ilo) = 9 ^ y;
l
l
if (L > N) {
I[G] = O;
if (s > 1) {
if (h > O && c - L < 0) {
Y ^= 3;
G--;
return L;
)
if lh < ll {
i = n;
B = O;
b = P;
)
)
N = L;
l
if (J) {
n++;
} else {
9 = PF
m = p < O ? g - 3 : g + 2;
if (I[m] < z | I[m + - p] > 0
ll Ilp += P ~ O] > G o-e r'

n-i-+_

)
l
l
)
1
} while (r < 1 & q > 2
|| (lp = O) > 0)
&& (q > O ] A > 2 | o > z & r < l)
&& ++C > 0 && ~-A > 0);
}
}
if (++O > 98) {
O = 20;
}
} while (e l= O):
Y ^= 8;
G-e;
return N t= M * M as N > -K + 1924 | D ? N ; 0;
}
l

The X function directly relates to the source code of Toledo


Nanochess.
Java is a lot faster than Javascript, so the computer search level is
fixed at 4-ply, but the current Java Virtual Machines (JVM) are not very
optimized so they are still not near the speed of the C language versions
which on most recent machines will play at 5-ply almost immediately.
There are lot of things that can be done with the source code,

151
Toledo Nanochess: The commented source code

especially for porting to new platforms supporting the Java language,


like cellphones and handheld devices, though these days Javascript is
gaining popularity over Java on the client side.
;:-v ' ' ` ""`11111:I:>1-':I:I:1:1:i<:I-?`f"-1:'--:tft-' l-?>`2`-"-trltttt ' tftt';t:<:j'tlE:l?fftt'-<
p rttser-:-Iif 1-31.. . r-1 1 3;
f._._.,. ~.-.l~.l\.-.l.)w-.-_-,.l~.\\`-\~-t-\,v~\w-.\\\\~~ \~\-.-. -.- ~ -- `t- .

2 " ~'**=*.-:-,f,.*,ar-c.:* e:.= 1 :}=:~ te-Ma'-ara'

#.'_c'-.'v~.-:Q -Bzzm* '.'-2: 'F.=.-r":1'tf'?:<' -er~w:<\-:_: -tm.-:lv-

:L" 'tii-'
v sk .\-1-----'-._ |'........l...|'||'||-||nt | |\\.\|\n\\|\\'\.\.\

_- -_|..-, ..!'1s--_-,.. _| .,,,__-r1_-___l_ , -,_;.-_. ;*._1__ r... ._- -< --te '...._..1-"_ 1.-_-., s-tes cl'
mi-'#5->'f1`lr`ffff -.tt -'-. i L'-_~='=r._ f -' f--:--"--:fria .J "fs'-.11" .- Z' 1nc; _'_'-1' -'.=::-.-=l
-1 "-'or-tir
__}I T-;t=,::_ .'.af-f.-__:_=_--'s Jcv'-2.-:--: '-gti'-'f1=ss
-' 72-i l-1-i-^-' liffflt las '-2 ::-_:-1. ' -.- _ ::::r :lt-: ;f.-e::- tz; .f--2-.u t-:ml L- -su L 1;* ::e1-=.t'.--it' 1~- - i;2
-- - _-... ...
=_ :nose ;I;1=-""-E-='f~ "ae="^"'-r-:;1I;=""'=
_' -5,, __.; 1, ' ll :E5:=' ,_'.-_j_ ,E;'= gig "f'*E;, _,,:
- *'~*"-W
, _ -*ft-'***`ft-ft_, ai; 9; f;,==r=.s\-~,$-;-"a;~;r-se'rm-
_'"a =-2:1.'=52:f2=:?f;.;e=r;==@==32;
_%%;"';-;;1-5;_"a%<;
; ;t;2f1f::_t_r+:'1~'+5;t=_2;.2?;;_;-,;_;2` I Ja a
--fut-1 -tr ----=- -. ,-- ---tf 3;" '-til - O V
21:_. -M ;='a =_ _
. _,., , a` :s1_2-...___.,-.,:1________-
-.l..-.-'..-!'.. ' _- _.-.-.-.-...-__-_-_-;-ur.-r-\;`* _
__._____-.,;n_-,,__________...__
_, *
J-fW~3 :''__ l L-l)-``li*$: f`':i'-',L3`fi'`:`:-i1l..- .
_ :._:::;..:. ::l_-;;';','$i,i',1{F'$I;_' "-:-ZI$i7:~::''::-:`:-:::::::"t$F:, .;"~"
'., ,".'_.
-21_.,_;1_-_ r':;H :_:_ ;g.___ H %f. =`e`' "gtff11*F:f;i;;;-3,;-i iiitlil1;;g;2as gifii-_.mt-
_ _' - =;>_.'-:3-=;"<<1__;-5-_;'_{;-5, ;:`:':-f' ' "'f-: : 1 Q-i$-ri: ;:1:` :I: : :_-__:;_:':_;;:; :-:;::;::;:; :';
"mt
._-Q. "-. " . 2-:::}::` t -975 ::-. > -2-2 , 3:-:s :'.'.` t t"F`!.`:::S:'::7;-.:`
3513"" -1
`\ ese _, D .'.'
,
-rr. -', --
il-
-.-- vi. x-.
tt <
t_;_-F1-_t'-_'-_::_-1'ft';-'-.c-:;'_.____;_tgt_,.____;-"-'__@:-`$?Fl'..i"!?1`:J:*>:::1;:-di-:.tt-.1.3..'R
...
I I I I t e
_;;;-;-;.;-;-;-;.:;; ' ---;-:-:-,~;-- _.-r0...;-:-:-';:-t-:-:;-1;:cft-_-:-L-:c-.t-:;:;:;r_:-:-:::-:-:-:_:}1h'-:-'i:
:f::f:::.:`:`:`:if:7:-frff:-:::---:-:1::-:- 1 t '---_''-lif. _ . "'<'-.~':`:l::r:irltl z
=-ef
-i,'-,-,- - - ~ - - :=$_-t~_r'_sf.`.-;_-; ;;.;I~;L2_>.~ .,'3tng.-_,,-;t;______
^'':::::-:;}::TF'-`t:'..''-"';;::_f;f:::::_ ' --7____.l.f "' :'-:;`::f::;I::`=-'i2:''::
>~.;_..,, _. it _ _ _ -r-'-1-- - - tli.=`f-*fi-)
tg , -;arr:';-:am r-,;:=-5;;;-=;;;;;;_;-;;_a:=-"-;;=- .- ':-:;:;:;,, aV a
_f.i:iiF%, Hi2313:1:-::7::I:::.. 5:"-t~ 0
. *.-' _ -;~;-I- -:-'-'-'-I-:-t-
ft- -;-2-j-_f-.-.-_-
_- -_-_-.\.-.-.->;-:-:-:-:-:-: 2-1-:-::-$`t-)t-..~.-.2i--'~- - -' "W ' ' ' ' ''~.
Il :. ' _- _--2' '-:-.-l-.f--^7Ht-$-:--:--_--_-1-:-_-_;
:_=i.- -griil - 2,&_f; ;;2;r`_f,;r~':atgg,;:;.;.; ;.; z; ; ,-._
.rs -- ...-.-..:::':-..'5.t-t
gp -';.-.; _ _ T5? ,_ _.`- __
*W
<
tu ?-LE-E-E-Eliii -II-li-"" -:--F -I ' >, le f `
ftnu,-,,-,
,,-.-. `\_.-_-.-_-_--.~_~_---_-.;:....w...-.-.-.._...-..
_ __ ._ l- th . 1_ .'.w.'.'
.- ..-....f..-~2-uH.-''5.>..-...-.,-.-
. "- .-':. ;-

1 -1; |-._--;-;-'- .-1::- -_.=_.r!t-:|1'_; I' -':'- -F '1'- v-_'-'-j l1 5- --._ -'Ill
-1 L. -1

'- '-1-1.-te". ::; H'-_-1-1 r-fs af-"l ::r:- ..f:- V _f.. -_-- _~_~
"2-, -_ \- -_.--. _- - --- --
ff . G.: ta- u 2' '_...*'~-:uf

`-;- ._;r-f-'-. :;::'.f';-1_:I- It-' - I- 1 tr:-1 '_ iz'-o' . -- !.<r.-{=...=:_: ~ v -'ak ff ., - f=-=" :its
' '. .-
.;_'-:ft;,'_;J, 11--_ -_;-f -_ | f .,_- .~-I,-E--_.;,;
.'.., .'._.',.|.
,;. , - '. -
<,'., ..<~ -I-.... .a - "' 'r.-t."
-Q- '--
\-.---"- .
"f _i

rr-1:_;: ` :::;__ rr; -2; tr --.&:<;;:.= '_.' ~-'_ '_-'f-----1. | _ -'-;'f_I- :I-;f ;;;:;:-;;.;

_;-1 _ _{ 1 ;-j-;-; ;-; ; , _ _ _-, _ , , ,-;-;-;-;-;-;-;-;-;-; ;;;-;'-2 1 1 I 2-; :S I I;-2 ; : : -_-.-.`-.n-..-`~_~'--~~~-_'~- -I'-J-JJ;--'--LAI-JI:

ltlc .\\`. 2+?1?): -;-:-: -: :if :`: : 2 2'-: :`-:: 1: 4" - J-Il' :ifi
"\ "'*>+t~r~H~~"""""""`3$l'4-la--a-.""`'
Appendix A
Bibliography

A guide through the most confusing parts of C language, written


with a pleasant style.
Expert C Programming. Peter van der Linden. SunSoft
Press, Prentice-Hall.
There are a lot of things that you can do using ANSI C only.
ANSI and ISO Standard C Programmer's Reference. P.J.
Plauger and Jim Brodie. Microsoft Press.
A lot of computer chess history that you will not find elsewhere.
' Computer Schach. Ludek Pachman, Vas I. Khnmund.
Wilhelm Heyne Verlag, Munich.
Toledo Chess l serves as a point of reference for minimum
"intelligence".
PDF paper "Information Content of Human Intelligence
and Life", written by mathematician Warren D. Smith.
http://www.math.temple.edu/~wds/homepage/dnainfo.pdf

153
Appendix B
Recommended websites

For the latest news about my chess programs and interesting links:
http://nanochess.org/
The biggest discussion forum about computer chess.
http://www.talkchess.com/
Toumaments between chess engines: ChessWar and OpenWar.
http://www.open-aurec.com/chesswar/
These computer chess fans are trying to list all known chess
programs
I
http://www.computer-chess.org/
Tips and techniques for writing chess programs.
http://ches sprogramming.wikispaces.com

1 55
Appendix C
Toledo Nanochess games

ln this appendix, some games played by Toledo Nanochess are


described.

C.1 Toledo Nanochess versus MicroMax v1.6


These are the two possible games of the bare Toledo Nanochess versus
the bare MicroMax v1.6 (both without Winboard interface). Toledo
Nanochess won both games. ,,.,,,, __
ado;
fas.-.ty
/gr
f?
//Ay

[Event "Test"]
`_S1te
' It ? H ] 1 . ~- /,. ' , f
:Date "2009.02.l3"] 7
jaime "19;41=1o-11 g%g%g%
Rd "W
`White Toledo Nanochess Feb/13/2009"]
W/y %f "" 'y %y
- ac micro ax v . " ? 1%?
isut --Wi 16] % @ 9
1. C4 Nc 2. Nc3 e5 3. e4 Nf6 4. d3 Bd 5. Nge2 Ng4 6. f3 Nf 7. g4 O-0
8. Be3 Be7 9. Rbl d6 10. b a5 ll. b5 Nb8 12. a4 h5 13. gxh5 Nxh5 14. Ng3
Bh 15. Rgl Be6 16. Qd2 Bxg3+ 17. hxg3 Nd7 18. g4 Nhf 19. Qh2 g6 20. Rhl
Nh5 21. gxh5 Qe7 22. hxg fxg6 23. Qh8 Kf7 24. Rh7 Ke8 25. Rxe7 Kxe7 26. Qh7
Bf7 27. Nd5 Kd8 28. Bh3 c6 29. Qh4 Kc8 30. Bxd7 Kb8 31. Qe7 c5 32. Qxf8
Be8 33. b6 Ra6 34. Qxe8 1-0

(Event Test"] / / /
Zsir;e"?"1 % %
(nace -~2oo9.o2.13=-1 ga '
:Time "l'.9':I58:33"l
_Round - ] n, daa?, 2%?
lwhite "microMax vl.6"] ?? ? g
'Black "Toledo Nanochess Feb/13/2009"] ZV I y 7bQ%?V
:Re 5 uir; to-1"]
- _//we 'Y
fx? y

l. Nc3 Nc6 2. d4 d5 3. e3 f5 4. Bb5 Qd6 5. Bd2 Bd7 6. Qh5 g6 7. Qh4 a6


8. Bd3 e6 9. Nf3 Rd8 10. O-O-O+ Be7 ll. Ng5 h6 12. f Bf 13. Qg3 hxg5
14. fxg5 Qxg3 l5. hxg3 Rxhl 16. Rxhl Bxg5 17. Kd1+ Nge7 18. Rh8 Kf7 19. Rxd8
Nxd8 20. Ke2+ c6 21. Na4 b5 22. Nc5 Bc8 23. Ba5 Nb7 24. Nxb7 Bxb7 25. Bc7
Bf6 26. Bd6 No8 27. Bf4 c5 28. c3 g5 29. Bc7 c4 30. Bc2 Ne? 31. Bd Nc8
32. Bc5 Bc6 33. Kf3+ a5 34. ge fxg4+ 35. Kxg4 Bd7 36. g3 Kg7 37. e4 e5+
38. Kf3 dxe4+ 39. Bxe exd4 40. cxd4 Be7 41. Bxe7 Nxe7 42. Ke3 Be6 43. Kf3+
b4 44. Ke3 Kf7 45. Kf3+ Bd5 46. Bxd5 Nxd 47. b3 c3 48. Ke2 Nf 49. Ke3
Ne4 50. Kd3 Nxg3 51. a4 Nf5 52. d5 Ke7 53. Ke2 Kd6 54. Kd3 Kxd5 55. Ke2
Nd4+ 56. Kel Nxb3 57. Kdl Nc5 58. Kc2 Nxa4 59. Kcl b3 60. Kdl Nc5 61. Kcl
c2 62. Kd2 Kd4 63. Kel b2 64. Ke2 b1=Q 65. Kf3 Qgl 66. Ke2 Qg2+ 67. Kel
cl=Q# 0-1

157
Toledo Nanochess: The commented source code

C.2 Nunn match http://www.nanochess.org/match.pgn

Afterwards I did a Nunn match of the same two bare engines. A Nunn
match is a tournament where both chess programs fight with ten
predetermined start positions, altemating sides. The result were 5 wins
for Toledo Nanochess, ll games tied and 4 wins for MicroMax vl.6.
As I was using the bare engines with fixed depth, the indication of
Timecontrol doesn't means anything.
Recent versions of Toledo Nanochess and MicroMax vl .6 for
WnBoard added iterative analysis so these results are only for historical
reference as they would change depending on machine and time control.
[Event "Test] ~f
,fewer _ ._
(bate --2oos.o3.os"l .,\ h:\ _` ,
IR nd lu . \\\\\
Il-'iliilte "Toledo Nanochess Mar/0'"r'2009"]
:Black "microMax vl.6"]
5
A7 mu
"U7 me
teI

\\\*`s
b~\\:`\ \t

:Result l/2-1/2"] V/I


jsco "s33"l '
:Pl C lllll "65"] " ;/ gl'/ly "17

lTieontrol "240+2] g

l. e4 c5 2. Nf3 e6 3. d4 cxd 4. Nxdd Nc 5. Nb5 Nf6 6. Nlc3 d few \illig _


2\\ \ \ mi U1

8. Bg5 a6 9. Na3 b5 10. Bxf gxf ll. Nd5 f5 12. c3 Bg7 13. exf5 Bx \\\\\:\
14. b4 O-O 15. ge Bee 16. Rgl Qh 17. h3 Qh 18. g5 Qg6 l9. Ne3 h5
20. f3 Bf5 21. Nxf5 Qxf 22. Qd5 Rac8 23. g6 Qf4 24. Ke2 Ne7 25. Qxd Rxc3
26. gxf7+ Kh8 27. Bg2 Qe3+ 28. Kfl Nf5 29. Qg Qd3+ 30. Kel Qe3+ 31. Kfl Qd3+
32. Kel Qe3+ 33. Kfl l/2-l/2

_Event "Test] /// gg? ??


jste@ -'1"1 E %
ratd-'gpo?.o3.os='l W//V/?%9//%V/%V \
:White microMax vl 6] , y
fet k tr 1 ae na .ha-es M /cv/2oo9--1


:PlyCount "lO6"] l /
A%y % s%
ls%y_Ay,A%%
\\

_s mot 2009 . . . . __] _


jriacotal f=2to+2~-1 / /1% / p
l. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc 5. Nb5 Nf 6. Nlc3 d 7. Bf4 e5
8. Bg5 a6 9. Na3 b5 10. Bxf gxf ll. Nd5 f5 12. c3 Bg7 13. exf5 Bxf5
14. Ne3 Qd7 l5. Nxf5 Qxf5 16. Qxd Qe4+ 17. Be2 Qxg2 l8. O-O-O Rd8 19. Rhgl Qee
20. Rg4 Rxd 21. Rxe Rxd1+ 22. Kxdl O-O 23. Bf3 f5 24. Rel e4 25. Bh5 b4
26. Nbl Rb8 27. Be2 bxc3 28. Nxc3 Bxc3 29. Bc4+ Kf8 30. bxc3 Ne5 31. Bxa Rb
32. Be2 Rbl+ 33. Kd2 Rb2+ 34. Ke3 Rxa2 35. Kf Nd3+ 36. Bxd3 Rxf2+ 37. Ke5 exd3
38. Rdl d2 39. Kf Rxh2 40. Kxf5 Ke8 41. Ke4 Ke? 42. Ke3 h5 43. Rxd2 Rh3+
44. Kd4 Kf 45. Rf2+ Kg5 46. Rf7 Rh4+ 47. Ke5 Rc4 48. Rf3 Rc5+ 49. Ke4 Rc8
50. Rf5+ Kg6 51. Rf3 Kg5 52. Rf5+ Kg 53. Rf3 Kg5 l/2-l/2

158
Toledo Nanochess games

_EVEI'1l_'. "TS1"] y f /ly ""'

jsice '-2"] y
josue'-2oo9.o3.os--1
:Round "3"]
(White "Toledo Nanochess Mar/07/2009"] pz y 2, 'l
(Black microMax vl.6"] _ _ ,a,g/
ui' 42;
(Result "1/2-1/2'-1 W/
\ \
Isco "ss9"l %
jPlyCount "l03"] y %?y
jrimecentmi --24o+2-11 %Q s_;tt`
~.\\\\; -!~%\

1. e4 C5 2. Nf3 Nc6 3. d cxd 4. NXd4 Nf6 5. Nc3 d6 6. BC4 e6 7. Be3 a6


8. Qe2 Qc7 9. O~O-O Be7 10. Bb3 O-O ll. f4 Nxd 12. Rxd4 h5 13. h4 Bd7
l4. a4 Kh7 15. e5 dxe5 16. Rc4 Bc 17. Bd2 Bd6 18. fxe5 Bxe5 19. Na2 Ng4
20. Nb4 Rac8 21. Rxc bxc 22. Nxa Qd6 23. Bb4 Bf4+ 24. Kbl c5 25. Bxc5 Rxc5
26. Nxc5 Qxc5 27. g3 Qc 28. Rel Be5 29. c4 Qc7 30. Bc2+ g6 31. Rfl Bxg3
32. b4 Bxh4 33. Bxg6+ Kxg 34. Rhl Bf6 35. Qe4+ Kg5 36. Qd3 Qa7 37. Qh7 Rh8
38. Qc2 Ne3 39. Qee Bd4 40. Qh4+ Kf5 41. Qf2+ Ke4 42. Rel Qxa4 43. Qg2+ Kd3
44. Qe2+ Kc3 45. Qb2+ Kxcd 46. Qe2+ Kc3 47. Qb2+ Kd3 48. Qe2+ Ke4 49. Qg2+ Kd3
50. Qe2+ Ke 51. Qg2+ Kd3 52. Qe2+ l/2-1/2

je t "T et] A i i
jsi tt s 7%
jo te --2oos.o3.os-ft 7 ''//
jtmuna --4--1 // V /
[White micromax vl.6"] l
"
Black tt Toledo Nanochess Mar/07/2009 tr ] T /
2%? //
jaesulr; ~-1/2-1/2'-1 ffy
jnco "Ba9"1 Q
R W,
IPlyCount "l3l"] $\s\:__
ai y *
?\\\\$ /a
Q
TimeControl "240+2"] B(p Z g

1. e4 c5 2. Nf3 Nc6 3. de cxd4 4. Nxdd Nf6 5. Nc3 d6 6. Bc4 e6 7. Be3 a6


8. Qe2 Qc7 9. O-O-O Be7 10. Bb3 O-O ll. Qc4 eS 12. Nd5 Nxd5 13. Nxc6 bxc
14. exd5 Bb? 15. f4 exf 16. Bxf4 g5 17. Be3 Rac8 18. Qg4 cxd5 19. Qf5 h6
20. Bxd5 Bxd5 21. Rxd5 Qc4 22. a3 Qe2 23. Bf2 Bf 24. Rxd Be5 25. Rxh6 Rfe8
26. Kbl Bg7 27. Rh3 Qe4 28. Qxe Rxe 29. Re3 f5 30. Rxe4 fxe4 31. Rel Rf8
32. Bc5 Rf5 33. Bd6 Rd5 34. Bg3 Rd2 35. Rxe4 Rxg2 36. Ra4 Kf7 37. Rxa Bf8
38. Be5 Re2 39. Rf6+ Ke7 40. Rf5 Bh6 41. Bg3 g4 42. Rh5 Be3 43. Rh4 Rg2
44. Rxg Ke6 45. Re4+ Kd7 46. Rxe3 Rg1+ 47. Ka2 Rcl 48. Kb3 Kd8 49. BE4 Rfl
50. Re Rf3+ 51. Kc4 Rf2 52. Kd3 Rf3+ 53. Ke2 Rh3 54. Re3 Rh5 55. Kd3 Rd5+
56. Ke4 Rc5 57. Rd3+ Ke8 58. Rd2 Rc4+ 59. Ke5 Rc7 60. Ke6 Rb7 61. Be5 Ra7
62. Rf2 Re7+ 63. Kd6 Ra7 64. Ke6 Re7+ 65. Kd Ra? 66. Ke6 l/2-1/2

:Event "Test]
:Site "?"]
:D te "2009.03.08"] V
fRund "5"] y
jwhite "Toledo Nanochess Mar/07/2009"] V
fBlack microMax v1.6"]
:Result "l/2-l/2"]
:ECO Cl9"] y -s,\
fPlyCount "ll5"]
[TimeControl "240+2"] Nun
* >\\\\\t -\\*~`

\ssl
s

`{n\_\,<
1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Qc7 7. Nf3 Ne7
8. a4 b6 9. Bb5+ Bd7 10. Bd3 Nbc6 ll. O~O f5 12. Bg5 O-O 13. dxc5 Ng6
14. cxb axb6 15. Rel h6 16. Bd2 Nce7 17. Nd4 Nxe5 18. Bf4 N7g6 19. Qd2 Kf7
20. Bxe5 Nxe5 21. Qf Kf6 22. h4 Bxa 23. Nxf5 g5 24. Qd4 exf5 25. Rabl Rfb8
26. g4 fxg 27. f4 gxf3 28. Rb Bc6 29. Kf2 Rb7 30. Re3 Ke 31. c4 Rab8
32. hxg5 hxg5 33. c3 Re8 34. Bg6 Rf8 35. cxd5+ Bxd5 36. Kfl Rf4 37. Qd3 Bc4
38. Rxc Rxc 39. Qf5+ Kd5 40. Bh5 g4 41. Be8 Qg7 42. Bb5 Rcc7 43. Ba6 Rb8
44. c4+ Kd 45. Qf4 Rf7 46. Qd4+ Ke6 47. c5 bxc5 48. Bc4+ Kf5 49. Qe4+ Kg5
50. Bxf7 Nxf7 51. Qe7+ Kf5 52. Qxc5+ Ne5 53. Qc2+ Ke6 54. Qc4+ Kd6 55. Qd4+ Ke
56. Qc4+ Kd 57. Qd4+ Ke 58. Qc4+ 1/2-l/2

159
Toledo Nanochess: The commented source code

IEvent "Test] 1
Isite. "t>l %,g
jose@ --2009.03.08'-1 % /, // %
:Round "6"] f? J
ilfihite "IttiCI`OM':1X V1 . 6"]
`Black
eau "Toledo
H _ H Nanochess Mar/0?/2009"] .%?y.WW
f \ yn
2%? %

ia ,
TimeControl *240+2]
%%%e%f%

R3*
\\\

1. e4 e6 2. d4 d5 3. NC3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 QC? 7. Nf3 Ne?


8. a4 b 9. Bb5+ Bd? 10. Bd3 Nbc ll. O-O cxd4 12. cxd4 f6 13. B4 Nf5
14. Bxf5 exf5 15. Qd2 g5 16. Bg3 f4 17. exf h6 18. c4 fxg3 19. cxd5 gxh2+
20. Nxh2 Na5 2l. Qe2+ Kf? 22. Qe?+ Kg 23. g4 Rag8 24. Nf3 NC4 25. Racl Qd8
26. Qe4+ Kxf 27. RXC4 a5 28. Ne5 Rg? 29. Kg2 Rhh7 30. Qbl h5 3l. Rhl Bxg4
32. Nxg4+ hxg4 33. Rc6+ K7 34. Qf5+ Ke8 35. Re6+ Kd7 36. Rxb6+ Ke8
37. Re6+ Kd? 38. Rxh? Rxh? 39. Rh6+ Kc? 40. Rxh?+ Kb8 41. Qbl+ Qb
42 . Qxb6+ Kc8 43. Qc7# l-0

` ven "es"
/
nace -'2oo9.o3.os~1 /% Z 79 /
(sauna --7--1 % sus
:White "Toledo Nanochess Mar/0?/2009"] d f /'y
(Black microMax vl.6] /
:Res lt "l/2 l/2"]

irrr,
_ Oun u

lTieControl "240+2]
1) I
eddk

/$7 V


.... .-17

1. e4 e5 2. NE3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O b5 6. Bb3 Be? 7. Rel O-O
8. c3 d6 9. h3 Na5 10. Bc2 c5 ll. d Qc? 12. Nbd2 cxd 13. cxd4 Be 14. d5 Bd?
15. b4 Qc3 16. Rbl Rac8 1?. bxa5 Qxc2 18. Qxc2 Rxc2 l9. a3 h5 20. Nb3 Ra2
21. Bb2 Nxe 22. Ncl Rxb2 23. Rxb2 Nc5 24. Nd2 Bd8 25. Ndb3 Nb? 26. g4 hxgd
2?. hxgd Bxg 28. Rfl Nxa5 29. Nxa5 Bxa5 30. f3 Bc3 31. Rb3 Bd4+ 32. Kh2 Bf5
33. Ne2 Bc5 34. Ng3 Bg 35. f4 f6 36. fxe fxe 3?. Rxf8+ Kxf8 38. Rc3 Ke?
39. Kh3 Bf2 40. RCS Bxg 41. Kxg3 Be4 42. Rxa Bxd5 43. Ra?+ Kf 44. Rd? Ke@
45. Rxg? Be4 46. Rc? Kd5 4?. Rc3 Kde 48. Rb3 Bd3 49. Rb4+ Kd5 50. Kf2 Kc5
51. Rb3 Kd 52. Rb4+ BC4 53. Rb2 Bd3 54. Rb4+ Bc 55. Rb2 Bd 56. Rb4+ l/2-l/2

[Event "Test] ,

;Dat 2009.03.08"] A V BV QV ' V


IRoud "8"l y y yl
[White "microMax vl.6"] Zi Z
:Black Toledo Nanochess Mar/0?r2009]
` H _ II ? /? W '/,

;t,,, 1 f/9,, %,e,,a


[PlyCount lO5] l
:TimeControl "240+2"]

l. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf 5. O-O b5 6. Bb3 Be? 7. Rel O-O


8. c3_d6 9. h3 Na5 10. Bc2 c5 ll. d4 Qc? 12. Nbd2 cxd4 13. cxd4 exd
14. Nxd4 Nc l5. N2f3 Bb? 16. Bf Rfe8 1?. Nf5 Rad8 l8. Bd3 h5 19. a4 bxa
20. Qxa Bf8 21. Bg5 d5 22. Nh6+ gxh 23. Bxf Be? 24. Bc3 Bc5 25. exd5 Rxel+
26. Rxel Qb 2?. Qh4 Kf8 28. dxc Bxc6 29. Ne5 Rd6 30. Bf5 Rd5 31. Be4 Rxe5
32. Bxe5 Bxe 33. Rxe f5 34. R4 Qe 35. Qxh5 Ke? 36. Rxf5 Qa2 37. Kh2 Qe6
38. Rf QC4 39. Qxh Kd? 40. Rxa Qd5 41. Qg?+ Kd8 42. Ra8+ Qxa8 43. Qh8+ Kd7
44. Qxa8 Bxf2 45. Qe Bb6 46. Qd5+ Ke? 4?. Qd6+ Kf? 48. Qxb Ke? 49. Kg3 Kd7
50. Qd6+ Ke8 51. Qe6+ Rf8 52. Qd7 Kg8 53. Qg?# l-0

160
Toledo Nanochess games

:Event "Test] ygy

7/
rear@ --2oo9_o3_os~'1
:Round "9"] %7//927
:White "Toledo Nanochess Mar/0?/2009] f 4
:Black "microMax vl.6] \
F- \\ .\ R /
[Resul "0-1") ???//uu i.,\\"tl s
\\\\\\*

jsco "se--1 ?/% 7
lt 7 6 u ] Z? .

jrimecantrai - 24o+2 1- 1 % %Q
1. d d5 2. c c6 3. Nf3 e6 . cxd5 exd5 5. Nc3 Nf6 6. Bg5 Be? 7. Qc2 Nbd?
8. e3 O-O 9. Bd3 Re8 lO. O-O Nf8 ll. b Bxb 12. Ne2 Bg 13. Rabl a5
l. h3 Bxf3 l5. gxf3 h6 16. Bxf6 Qxf 17. f Ne6 18. a3 Bxa3 19. Rxb? Nd8
20. Rb3 Bd 21. f3 g6 22. Ral Rxe3 23. Qd2 Rxf3 2. Rxa5 Rxa5 25. Qxa5 Rxh3
26. Qd2 Ne 27. Qc3 Nxf 28. Nxf Qxf 29. Qb2 Rh2 30. Qxh2 Qxh2+ 31. Kfl Bg3
32. Rb8+ Kg7 33. Rb2 Qxb2 34. Be2 Bh 35. Kgl Q:<e2 36. Khl Bg3 37. Kgl Qf2+
38 . Khl Qh2# 0-l

vnt " TESZ " ]


_ 1 te I "P"
- A / %,
I oa c a " 20219 _ 03 _ os - 1 V 7 7
:R und "10"] Q///<2%;//V /V
:Wite "microMax v1.6] y la
:Black "Toledo Nanochess Mar/07/2009"] %
VWJ l4Z % f/
ia-seat@ -~1/241/2'-1 W % %
sco "1:36"] "
1P1yc0unr; "ios-~1 7 /ay
TimeControl 2O+2"] g Z l>
\
l_\-x\\

1. d d5 2. c c6 3. Nf3 e6 . cxd5 exd5 5. NC3 Nf6 6. Bg5 Be? 7. Qc2 Nbd7


8. e3 O-O 9. Bd3 Re8 10. O-O Nf8 11. h3 Be6 12. Qb3 b5 13. Ne5 Bd? l. e h6
15. Bxf gxf 16. Nxd7 Nxd7 1?. exd5 Nb8 18. Be f5 19. Bxf5 b 20. Ne2 Qxd
21. Qxd cxd5 22. Nf Na6 23. Nxd5 Rad8 2. Be Bg5 25. Bf3 Rd6 26. Rfel Red8
27. Re5 Kf8 28. Kfl f6 29. Rf5 R8d7 30. Rdl h5 31. Rd3 Kg? 32. Rb3 h
33. Be Nc? 3. Nxc? Rxc? 35. Rxb Bd2 36. Ra Re6 3?. Ke2 Rxe+ 38. Kxd2 Rce?
39. Kd3 Kg 40. Rf3 Rel l. Ra6 Rdl+ 2. Kc2 Rxd 43. Raxf6+ Kg? . Kc3 Rdl
5. Rf Rc?+ 6. Kb3 Rd6 ?. Rxh Rg 8. Rg Rxg 9. hxg Rb?+ 50. Kc3 Kg
51. Rf5 Rc?+ 52. Kd Rb? 53. Kc3 Rc?+ 5. Kd Rb? 55. Kc3 1/2-1/2

:Event "Test] /
aa.)
(T

:Date
' 1171:

" I . "1
.
1 _
/.,,./.'%....,_- /.-,. ..... ,.%

:Round "ll"] T %; H< /...,/2,, ,


:White "Toledo Nanochess Mar/0?/2009"] z
:Black "microMaX vl . 6"]
'f
3-\\
:Result l-0"] ' 7' 27
taco --nas-=1 _
tplycounr; wir] RB -_ _,
-.

Irimecontro1='24o+2"] seles3s\t\5\ e, l
1. d Nf6 2. c g6 3. Nc3 d5 . cxd5 Nxd5 5. e Nxc3 6. bxc3 Bg? 7. Nf3 c5
8. Rbl O-O 9. Be2 cxd 10. cxd Nc6 ll. d5 Ne5 12. Qd2 Ng 13. h3 Bh6
l. QC3 Bg7 15. Qd3 Ne5 16. NXe5 Bxe5 17. f Bf 18. Bd2 Bh+ 19. g3 Bf6
20. Rh2 h5 21. g Bh+ 22. Kdl hxg 23. hxg Bf6 24. e5 Bg7 25. Qh3 f6
26. Qh?+ Kf? 2?. e6+ Bxe 28. dxe6+ Kxe 29. Rxb7 Rh8 30. Bc+ Kd
31. Qxg Rxh2 32. Qd3+ KC6 33. Qe4+ Kc5 34. Rc?+ QXC7 35. Qd5+ Kb 36. Ba5# 1-O

161
Toledo Nanochess: The commented source code

_EVI't. "TESlI."] V 9 % %'-:/


V /2? W /

S-te "?"] y
:Date 2009.03.08l /2%?
fRound "l2"] l I ;//
white tmicranax v1.s~1 s~~%y 4%?, a
:Black "Toledo Nanochess Mar/0?/2009"] , _
:Result l/2-l/2"] gg
(Eco "os5"]
_,s\ R Z?
[PlyCount "97"]
[TimeControl 20+2"]

si
\\s
1. d Nf 2. c g6 3. No3 d5 . cxd5 Nxd5 5. e Nxc3 6. bxc3 Bg? ?. Nf3 c5
8. Rbl O-O 9. Be2 cxd l0. cxd f5 ll. Qc2 fxe l2. Qxe Nc6 l3. Bc+ Kh8
l. Qd5 Bxd 15. O-O Qxd5 16. Bxd5 e5 1?. Be3 Rd8 18. Be a5 19. Bxc bxc
20. Nxd exd 21. Rbdl c5 22. Bg5 Rd5 23. f Ra6 2. Kf2 Bg 25. Rdel Rb
26. Kg3 h5 2?. Re? Re 28. Rbl Rxe? 29. Bxe? c 30. Rcl c3 31. Bf6+ Kg8
32. Be5 g5 33. Rel c2 3. Rol d3 35. Bc3 d2 36. Bxd2 Rd3+ 3?. Be3 Rxe3+
38. Kf2 Re2+ 39. Kg3 gxf+ 0. Kxf Rxg2 l. h Bdl 2. Ke Rh2 3. Kd Rxh+
. Kc3 Rh3+ 5. Kd2 Rh2+ . Ke3 Rh3+ 7. Kd2 Rh2+ 8. Ke3 Rh3+ 9. Kd2 l/2-l/2

:vent "Test] ,/
I ite "?" di?
~\\\\ _L\\\\ res
1oate "2oo9.os.oa"] %f 2
jsouna "13l 1 g%, y 2,
:White "Toledo Nanochess Mar/0?/2009"]
:Black "microMax'vl.6"]
(Result l/2-l/2"]
1 gg?
?? ??? 1%??
*Rab- st _\\\_
`
:Egg ~E15"] *RR
%
D:%;
y A/2,,m-?7 s
\ '~.\`\1\ \\`

gplycaunt test]
jrimecentral "24o+2" 1 \
\

1. d Nf 2. c e6 3. N3 b6 . g3 Ba 5. b3 Bh+ 6. Bd2 Be? 7. Bg2 c6


8. Bc3 d5 9. Ne5 Nfd7 lO. Nxd? Nxd? ll. Nd2 O~O l2. O-O Rc8 13. e f5
l. exf5 exf5 15. a Nf6 l6. f Kf? 17. Rel dxc l8. bxc Rc? 19. Qb3 Bc8
20. c5+ Nd5 21. h Be 22. cxb Rb? 23. Rxe Kxe 2. Qc Qxb 25. Ba5 Qxa5
26. Qxc6+ Bd 2?. Rel+ Ne3 28. Rxe3+ Kf? 29. Qxb?+ Qc? 30. Bd5+ Kg
31. Re6+ Rf6 32. Qxc7 Bxc7 33. Re? Bb6 3. Nb3 Rd 35. Re5 Rf 36. a5 Bd8
3? Bed Bc? 38. Rc5 Bd 39. Bxf5+ Rxf5 0. Rc Rf6 l. d5 Be? 2. Rc? Rf?
3. f5+ K6 . Nd2 Ke5 5. Nc+ Kxd5 6. Ne3+ Ke ?. Nc Kd5 8. Ne3+ Ke
9. Nc Kd5 l/2-l/2

:Event "Test] R
Sit "?"l zy gy
:Dat "2009.03.08"] %%'ZZV
:Round "l"] gy /
:White microMax vl.6"] ?? I mQ Z
:Black "Toledo Nanochess Mar/0?/2009"] \
:Result "O-1"]
:ECO El5"] U
'
, sssg.
lPlyCount 80]
jrimacantrel "24o+2"]
,
/


tie
g
hn,N
m\>-
Wire
,
1. d Nf 2. c e 3. Nf3 b . g3 Ba6 5. b3 Bh+ 6. Bd2 Be? ?. Bg2 c6
8. Bc3 d5 9. Ne5 Nfd? 10. Nxd? Nxd? ll. Nd2 O-O 12. O-O Rc8 13. e f5
l. exf5 Rxf5 l5. f Qe8 16. Bf3 C5 17. Qcl cxd 18. Bxd Bd6 19. Kf2 Bc5
20. Bxc5 Nxc5 21. Qbl Rd8 22. Bg Rf 23. Ke3 e5 2. f5 dxc 25. bxc Qd?
26. Rdl Qd+ 2?. Kf3 Bb?+ 28. Ke2 Qxg+ 29. Ke3 Rxf5 30. Qxf5 Qxf5 31. Ke2 Qg+
32. Ke3 Qh3 33. Nfl Rf8 S. Kd2 Qg2+ 35. Kcl Rxfl 36. Rxfl Qxfl+ 3?. Kb2 Qf2+
ss. xas oe3+ 39. Kba oa2+ 40. Kbs ob2# o~1

1l52
Toledo Nanochess games

:Event "Test] ff m ~%-%


\

'site ""1
:Date "2009.03.08"]
:Round "15]
Ewhite "Toledo Nanochess Mar/O7/2009"]
[Black "microMax v1.6"] l :\'\'
Result "1/2-1/2--1
jEc0 "E98"]
&
!=`H 1 /
*
Ili i
PlyCount "98"]
rfrimecnuml 1-24o+2--1 \\%
%
WW >
Y
`f
Q\
23%
\\
M; W
< ~\\~< -\\\
_

1. d Nf6 2. C4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 O-O 6. Nf3 e5 7. O-O Nc6


8. d5 Ne7 9. Nel Ne8 10. Be3 f5 ll. exf5 Nxf 12. g4 Nxe3 13. fxe3 Nf6
14. g5 Ne8 15. Rxf8+ Kxf8 16. h4 Ke7 17. a3 Bf5 18. e Bd7 19. b4 a5
20. Rbl axb4 21. axb4 Ra3 22. Qcl Qa8 23. C5 Qa7 24. Qe3 dxc 25. bxc5 Qa5
26. d6+ cxd 27. cxd6+ Nxd 28. Nd5+ Kf7 29. Bd3 Bc 30. N02 Ra4 31. Nb Ra2
32. NC4 Nxc4 33. Bxc4+ Ke7 34. Bxa2 Qxa2 35. Qc5+ Kf7 36. Rfl+ Ke 37. Rdl K7
38. Nb Qa 39. Qc4+ Ke7 40. Nd5+ Kf7 41. Rfl+ Ke 42. Nf4+ Kd 43. Qe6+ Kc?
44. Qe7+ Kb8 45. Ne6 Qa7+ 46. Rf2 Qal+ 47. Rfl Qa7+ 48. Rf2 Qal+
49. Rfl Qa7+ 1/2-1/2

;EYent:est"] %%%Z
_S1te . 1 y ff.-.a.-.<, /. U/
.NM
jnane -12oo9.o3.os"]
;Round 16 ] ,z
/
\
-5;\~\\\ /j

`
B-

Iwhite "microMax vl.6"] gg? 'vwg y //
:Black "Toledo Nanochess Mar/O7/2009"] %
/
IResult "O-1"] '
1Eco "E98]
:PlyCount 76"]
En g~\\\ :l
:B4

jTimeControl "240+2"] \\\\\II \.\\\\:\\\\\ U3?


=I{j;~
HH.
__k\\\\?\"\\ ~\\

1. d4 Nf 2. c4 g6 3. Nc3 Bg7 4. a4 d 5. Be2 O-O 6. Nf3 e5 7. O-O Nc


8. d5 Ne7 9. Nel Ne8 10. Be3 C6 ll. Nd3 f5 12. Bf3 fxe 13. Bxe4 Bd7
14. Qb3 QC7 15. 4 exf 16. Rxf4 Rxf4 17. NX4 BXC3 18. Qxc3 a5 19. Kf2 g5
20. Nd3 h6 21. Kf3 b5 22. Rfl b4 23. Qcl N6 24. Bd4 Nxe4 25. Kxe Re8
26. Kf3 cxd5 27. cxd5 Qb7 28. QC4 Bb5 29. Qb3 a4 30. QC2 Qxd5+ 31. Kg3 Qxd
32. QC7 Qh4+ 33. Kf3 Nd5 34. g3 Qe4+ 35. KE2 Nxc7 36. Kgl Bc6 37. Nel Qd4+
38. Rf2 Rxe1# O-1

@$]
` ven " es "

juan@ -1009.03.08-']
%%%
:Round l7"] ZV ' '
_W1'u.te Toledo Nanochess Mar/07/2009 1
:Black microMax vl.6"] / A9' ,y \\.\-xq
Q \-
@;%;2;f:
LMUW
: ly cun /
///7
,%%%M f w
f

gy'
,4/

%v
Ili
\\\\\{

_T1meContro1 "240+2"]

l. C4 e5 2. NC3 Nc6 3. g3 g6 4. Bg2 Bg7 5. e3 Nge7 6. Nge2 O-O 7. O-O d6


8. d3 Be 9. Qa f5 10. h4 Kf7 ll. Bf3 a5 12. a3 Bf 13. Bd2 a4 14. dxe Ne5
15. Nd BXC4 16. Rfel C5 17. exf5 cxd4 18. Bxb7 dxc3 19. Bxc3 Qe8 20. QC2 Bd3
21. Qdl Rd8 22. f Bxf 23. Bd5+ Nxd5 24. Qxd5+ Be 25. Qxa5 Nf3+ 26. KE2 Nxel
27. Kxel Ra8 28. Qc7+ Qe? 29. Qxe7+ Kxe7 30. a4 Bb3 31. a5 Bd5 32. Ra4 Bc6
33. Rc Kd7 34. Bxf Rxf 35. b BE3 36. K2 Bd5 37. Rd4 Be6 38. ed Bg4
39. eS Re6 40. Kg2 Kc6 41. exd Rxd 42. b5+ Kc5 43. Rxd Kxd 44. a6 Kc5
45. a7 Rxa7 46. Kf2 Kxb5 47. Kg2 Ra2+ 48. Kgl Bh3 49. Khl Rg2 50. g4 Rxg4
51. Kh2 Bfl 52. h5 gxh5 53. f5 Bd3 54. f6 Bc 55. Kh3 Be 56. Kh2 Kc5
57. Kh3 Kd5 58. Kh2 Ke5 59. f7 Bxf7 60. Kh3 Be 61. Kh2 Rg5 62. Khl Bf5
63. Kh2 Rg6 64. Khl Be4+ 65. Kh2 Kf 66. Kh3 Rg2 67. Kh4 Rh2# 0-l

163
Toledo Nanochess: The commented source code

`Event "Test] /%
:Site "?"] f
[Date "2oo9.o3.os"1 /2%?
:Round "l8"]
:White "microMax vl.6]

^~%y'~~?///
W \!:eslI9_
w '

:Black Toledo Nanochess Mar/O7/2009] _/ "-es\


l
\.\ *'
1Reeult "O-1'* ] % UN/
eco "A25"1 R IIE\\\\\
\\\\\
V "%W 27
P1YCount "56"] %"%f%%?V4Z%%
ITimeControl "2O+2"] gi , E

1. c e5 2. Nc3 NC6 3. g3 g . Bg2 Bg7 5. e3 Nge7 6. Nge2 O-O 7. O-O d6


8. d3 Be 9. Qb Na5 10. Qb c5 ll. Qa Rc8 12. Bd2 Bd7 13. Nb5 Bxb5
l. Qxb b6 15. f E5 16. KE2 a6 17. Qxa exf 18. Nxf Kf7 19. Bd5+ Nxd
20. Nxd5 Rb8 21. Bxa bxa 22. Qa7+ Kg8 23. Ne7+ Kh8 Z. NC6 Rxb2+
25. Kf3 Qg5 26. h3 Qh5+ 27. g QXh3+ 28. Kf Qxg# 0-1

{Event "Test]
:Site "?"] W _
:Date 2009.03.08"]
1Round l9"]
:White Toledo Nanochess Mar/O7/2009"] Fdw
;Black microMax vl.6]
\
>-
:Result l/2-l/2"]
:ECO "B97]
lv %kN
%
l>
III?
:PlyCount 50"] // 1 1

:TimeControl 20+2] Q %I
III* $119 `EI e
1. e C5 2. Nf3 d 3. d cxd . Nxd NES 5. N03 a6 6. Bg5 e6 7. f Qb
8. Q2 Qxb2 9. Rbl Qa3 10. Ndb5 axb ll. BXf6 gxf 12. Bxb5+ N06 13. Qd Be7
l. Qc Bd7 15. g Qa7 16. a Qe3+ 17. Ne2 Q3 18. Rgl Qh3 19. C3 Qxh2
20. Kd2 O-O 21. Rbdl Kg7 22. Rhl Qg2 23. Rhgl Qh2 2. Rhl Qg2
25. Rhgl Qh2 l/2-1/2

:Event "Test]
Site ?"]
:Date "2009.03.08"]
[Round "20]
\
:White "microMax v1.6]
IBlack Toledo Nanochess Mar/O7/2009"]
Reeult O-1"]

\>-e\t
ECO B97] %%7 I ?'f 7
jPlyCount "86"]
[TimeControl "2O+2"] D3\

1. e c5 2. Nf3 d6 3. d cxd . Nxd Nf 5. Nc3 a6 6. Bg5 e6 7. f Qb


8. Qd2 Qxb2 9. Rbl Qa3 10. Bd3 Nc6 ll. Bxf gxf 12. N3 Nb 13. Bc b5
l. Nxb5 Nxc2+ 15. Qxc2 axb 16. Bxb5+ Kd8 17. O-O Qxa2 18. QC3 Rg8
19. Qxf6+ Be7 20. Qb2 E5 21. BC6 Ra 22. Bb5 Ra5 23. Bd3 fxe 2. Bxe Qxb2
25. Rxb2 h5 26. Kf2 d5 27. Rd2 Bc5+ 28. Nd dxe 29. Rbl Ra 30. Ke3 e5
31. fxe5 Rg 32. h3 Ra3+ 33. KE2 e3+ 3. Kgl exd2 35. hxg Bxd+
36. Kh2 Bxe5+ 37. g3 Rxg3 38. Rdl Bxg 39. Rxd2+ Rd3+ 0. Kg2 Rxd2+
l. Khl Bf3+ 2. Kgl Bd+ 3. Kfl Rdl# 0-1

C.3 Some other games


Here are more games of Toledo Nanochess, extracted from the now
extinct chess tournaments ChessWar and OpenWar organized by
Olivier Deville.

164-
Toledo Nanochess games

:Event "Chesswar XIV Promotion m/20'"]


ISite "DELL-E6600"]
:Date "2009.0.25"] '
:Round "2.95"]
:White "Toledo Nanochese]
:Black "Belofte O.2.8"] l-f-
"\<

:Result "l-0 ]
zco ==A4.o--1
"""'y `:\\\%\\\\l
*Q
le;l l7\R\\
eee
lwhieeele -'1299--1 %7
lelaekslo "1o1o'-1 V/ '
`
lknnotator "l. -0.0l"] \

\\\\\. -.\\\`
:PlyCount "7"] f..4 te
:EventDate "2009.??.??"]

1. c {-0.01/6 0.7} 1... e6 2. d {+0.00/6 1.2} 2... h6 3. e {-0.01/6 2.2}


3... Qh . NC3 {-0.02/6 5} 4... Bb 5. Bd3 {-0.02/6 6} 5... NC6 6. g3 {
+0.06/6 7} 6... Qf6 7. e5 {+0.0l/6 } 7... Nxe5 8. dxe5 {+2.10/6 3) 8... Bxc3+
9. bxc3 {+2.09/6 3} 9... Qe7 10. f {-0.03/6 } 10... Qc5 ll. Qe2 {+0.05/6 7}
11... Ne? 12. Be3 {+0.07/6 7) 12... Qa5 13. Rcl {-0.07/6 91 13... a6 l. h {
-0.07/6 5} l... O-O 15. Nf3 {-0.11/6 5} 15... d6 16. g {-0.14/6 6} 16... dxe5
17. fxe5 {+O.83/6 3} 17... Rd8 18. Qc2 {-0.06/6 10) 18... Kf8 19. g5 {~0.06/6 7
} 19... h5 20. O-O {-0.07/6 5} 20... Bd7 21. Qf2 {-0.11/6 6} 21... Kg8 22. Be
{-0.07/6 6} 22... BCS 23. Nel {+O.7/6 7) 23... Kf8 24. Qxf7# {
+770.7/6 9 Xboard adjudication: Checkmate} l-O

:Eventn Openmar 6th Edltlon 15 + 5 ]


_S1te QUAD ] gy gy. gy
Date --2009.07.05-'J
aeund I-5.6'-1 /,f /% @
_White "Mainsworthy 6.Ol.7"] zz; ,;// V
:Black "Toledo Nanochess"] ?. -7 ////1,,
:Result "O~l"1 // gggg
joimecenurel I-9oo+5'-1 % % % %
jmqnetacer +o.o6"] "'% 'f '\` E
_
[Number "l90"1 -R 5-R

1. e C5 2. Be2 d5 {+0.06/6 0.9} 3. Bb5+ NC6 {+0.03/6 0.7} 4. exd5 Qxd5


{+0.95/6 2.7} 5. Qf3 Qd6 {-0.13/6 2} 6. Kfl e5 {+0.00/6 7} 7. Nc3 Nf
{+0.0l/6 5} 8. Qd3 Be6 {+0.03/6 5} 9. Qxd Bxd {+8.2/6 2,2} 10. N3 a6
{+0.01/5 3} ll. Bxc6+ bxc6 {+2.96/6 l.} 12. a3 e {+0.0/6 3} 13. Ng5 Bd5
{-0.02/6 } l. Nxd5 cxd5 {+3.08/6 l.O} 15. g3 h6 {+0.08/6 l.O} 16. Nh3 Rb8
{-0.06/6 0.6} 17. d3 g5 {-0.07/6 1.5} 18. dxe dxe {+0.83/6 l.} 19. a
Rh7 {-0.09/6 2.l} 20. Ngl Ng {-0.18/6 l.8} 21. f3 exf3 {-0.10/6 l.6} 22.
Nxf3 Be {-0.06/6 } 23. h3 Bxb2 {-1.28/6 2.5} 24. Bxb2 Ne3+ {+O.87/6 2.3}
25. Kgl Rxb2 {+l.9/6 1.8) 26. Rel RXC2 {-2.13/6 1.9) 27. Rxe3+ Kf8
{+0.02/6 l.O} 28. Rh2 Rc {+0.ll/6 2.U} 29. a5 Ra {+O.86/6 2.3} 30. Rb2
Rxa5 {+O.98/6 2.3} 31. Rb8+ Kg? {+0.02/6 0.6} 32. Rbl f6 {+0.06/6 0.7} 33.
Re7+ Kg6 {-1.79/6 0.8) 34. Reb7 Rxb7 {+0.02/6 O.9} 35. Rxb7 Ra3
{+0.0l/6 l.l} 36. Kg2 Ra2+ {+0.02/6 l.6} 37. Kfl Ra3 {+0.03/6 2.3} 38. Kg2
Ra2+ {+0.02/6 1.6} 39. Kgl Rc2 {+0.03/6 l.8} O. Rb3 Ro1+ {+0.02/6 2.3} l.
Kg2 Rc2+ {+0.02/6 2.0] 2. Kgl Rc1+ {+0.02/6 2.3} 3. Kg2 Rc2+
{+0.02/6 2.0} . Kfl Ra2 {-0.02/6 2.3} 5. Kgl h5 {+0.02/6 l.8} 46. Re3
Kf5 {+0.02/6 2.l} 7. Rb3 Ke {+0.02/6 1.9} 8. Nxg5+ fxg5 {+3.09/6 O.3}
9. Khl Ral+ {+0.0/6 l.2} 50. Rbl Rxbl+ {+.97/6 0.2) 51. Kh2 Kf3
{+0.9l/6 0.l} 52. h gxh {+l.95/6 O.l} 53. gxh c {+757.76/6 0.l} 54. Kh3
Rhl# {+778.23/6 O.1}
{Xboard adjudication: Checkmate} 0-1

165
About theanthor
I

scar Toledo Gutirrez is an experienced computer programmer at


1
Familia Toledo Organization. He has Written hundreds of programs in
several programming languages. He performs various activities,
collaborates in the design of the Fenix Operating System and the Biyubi
Internet Browser, gives talks at universities and does game design and
programming consulting. He is also the creator of the Wor1d`s smallest
chess programs Written in C, Java and Javascript and he Was also the
first Mexican to Win the IOCCC (International Obfuscated C Code
Contest): Best Game (2005), Best of Show (2007), Best Small Program
(2007), Most Portable Chess Set (2007) and Best Non-chess Game
(2012), and 2nd place Winner at the first JSlK contest (2010).

169
Toledo Nanochess ns the world's current smallest chess
program written in the C computer language.

Now for the flrst tlme un th|s book ls published the


complete documented source code, commented
line-by-line.

You w|II flnd.

1 A brief history of computer chess


I The basics of chess programs
u Hlstory of Toledo Chess 1 and 2 (IOCCC wlnners)
I Toledo Javascript Chess T
I JS1K 2010 Chess entry commented (2nd place wmner)
1 Toledo Java Chess

You might also like