New 'Micro' Chess Engine - Iota 0.1

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Daniel White
Posts: 33
Joined: Wed Mar 07, 2012 4:15 pm
Location: England

New 'Micro' Chess Engine - Iota 0.1

Post by Daniel White »

After finding it difficult to improve my first engine AdroitChess, development stopped towards the end of March and I moved onto other projects. However recently I have found some time and decided it would be a good challenge to make a 'micro' engine (<2kb non-blank source), much like microMax and Toledo Nanochess.

Three days later and I am ready to release Yoda version 0.1. This version is simply a foundation with no serious attempt made to save characters or improve strength. It has the following features:
* 1788 bytes in size (no comments or white space)
* Alpha-beta full width search
* Static evaluation consisting of material and centre bonus for pawns, knights and bishops.
* Partial UCI support, understanding 'uci', 'isready', 'position', 'quit' and 'go'. This is enough to play a game under Arena, at least.
* Time management - Using the infomation in the 'go' command and node counts.
* All rules of chess except underpromotion (it will neither play nor accept these).

Below is the source code:

Code: Select all

#include <stdio.h>
#define V break;
#define v return
#define X strtok&#40;0," ")
#define Q 9999
#define Z ;if&#40;!strncmp&#40;g,
int B&#91;Q&#93;,z&#91;&#93;=&#123;205,199,200,217,196,200,199,205&#125;,M,l=1<<24,N,E,C,d,f,G,H,
L&#91;&#93;=&#123;10,8,21,0,8,18,0,13,1,16,15,17,0,14,18,31,33,0,1,16,0,15,16,17,0&#125;,q=Q*2;
char g&#91;Q&#93;, *i;

int R&#40;int D, int a, int b, int P, int n, int O, int o, int p, int r&#41;&#123;
  ++N;
  if (!--D&#41;
    v E;
  int c=0, F=0, J, K, T, A, U, S, h, e, I, j, k;
  for&#40;;F<128;F=F+9&~8&#41;
  for&#40;K=L&#91;J=L&#91;&#40;A=B&#91;F&#93;)&7&#93;&#93;;K && A&M;
      K=&#40;K>0 & B&#91;F&#93;%8!=2&#41; ? -K &#58; L&#91;++J&#93;)
  for&#40;T=F+K;1;T+=K&#41; &#123;
    if &#40;A%128==34 & F+K==T&#41; /* Adjust black pawns to move downwards */
      T+=2*&#40;K=-K&#41;;
    if (&#40;T&136&#41; || (&#40;U=B&#91;T&#93;)&M&#41; || &#40;A%8==2 && abs&#40;K&#41;==16 && U&#41; ||
        &#40;A%8==2 & K*K!=256 & !U & T!=n&#41; ||
        &#40;A%8==4 & abs&#40;F-T&#41;==2 & &#40;U || !&#40;A & B&#91;T>F ? T+1 &#58; T-2&#93;&128&#41;))) V
    if &#40;T==O | T==o | U%8==4&#41; v q; /* Illegal previous move? */
    h=&#40;A%8==2 & abs&#40;T-F&#41;==32&#41; ? T+F>>1 &#58; q; /* Find current ep square */
    /* Make move */
    I=j=k=q;if &#40;A%8==4 & abs&#40;T-F&#41;==2&#41; &#123; if &#40;B&#91;T-1&#93;) V /* Castling stuff */
      B&#91;j=&#40;I=F&#41;+T>>1&#93;=B&#91;k=T>F ? T+1 &#58; T-2&#93;;B&#91;k&#93;=0; &#125;
    B&#91;T&#93;=A&127;B&#91;F&#93;=0;e=&#40;U%32&#41;*50; /* Move pieces and calculate eval change */
    if &#40;A%32<9&#41; e+=B&#91;T+8&#93;-B&#91;F+8&#93;; /* Positional eval update */
    if &#40;A%8==2 && (&#40;T+K+1&#41;&128&#41;) &#123; B&#91;T&#93;^=27;e+=1150; &#125; /* Promotion */
    if &#40;A%8==2 & T==n&#41; &#123; B&#91;n^16&#93;=0;e+=100; &#125; /* En-passent capture */
    M^=96;E=-E-e; /* Swap side to move and update eval */
    if &#40;F==p & T==r&#41; &#123; C=h;d=I;f=j;v q; &#125; /* Exit early to make move */
    S=-R&#40;D, -b, -a, P+1, h, I, j, q, q&#41;;c|=S>-q; /* Recursive search */
    B&#91;F&#93;=A;B&#91;T&#93;=U; /* Undo move */
    if &#40;A%8==2 & T==n&#41; B&#91;n^16&#93;=A^96; /* Undo promotion */
    if &#40;A%8==4 & abs&#40;T-F&#41;==2&#41; &#123; B&#91;k&#93;=B&#91;j&#93;;B&#91;j&#93;=0; &#125; /* Undo castling */
    E=-E-e;M^=96; /* Reset eval and side to move */
    if &#40;N>l&#41; v q; /* Time to end search? */
    if &#40;S>a&#41; &#123; /* New best move? */
      a=S; /* New best score */
      if (!P&#41; &#123; G=F;H=T; &#125; /* If root set global to/from */
      if &#40;S>=b&#41; v b; &#125; /* Beta cutoff */
    if ((&#40;A&135&#41;==130 & abs&#40;F-T&#41;==16&#41; || /* Double pawn moves and castling */
        &#40;A%8==4 & abs&#40;F-T&#41;==1&#41; & !U&#41; ;  /* need extra iteration */
    else if &#40;U | !&#40;A&8&#41;) V /* Capture or not slider, exit loop */
  &#125;
  /* No legal moves - checkmate/stalemate */
  if (!c&#41; &#123; M^=96;a=&#40;R&#40;3, -Q, Q, 1, q, q, q, q, q&#41;==q&#41; ? P-Q/2 &#58; 0;M^=96; &#125;
  v a; &#125; /* Return score for this node */

main&#40;) &#123;
  int s, F, t, u;
  N=0; /* Reset node counter */
  strtok&#40;gets&#40;g&#41;, " ") /* Wait for commands */
  Z"uci",4&#41;) puts&#40;"id name Y\nid author D\nuciok")
  Z"i",1&#41;) puts&#40;"readyok")
  Z"q",1&#41;) exit&#40;0&#41;
  Z"p",1&#41;) &#123;
    C=d=f=q; /* Reset board */
    for&#40;s=E=0;s<8;++s&#41; &#123;
      B&#91;s+16&#93;=194;B&#91;s+96&#93;=162;B&#91;s+112&#93;=&#40;B&#91;s&#93;=z&#91;s&#93;)-32;
      B&#91;s+32&#93;=B&#91;s+48&#93;=B&#91;s+&#40;M=64&#41;&#93;=B&#91;s+80&#93;=F=0;
      for&#40;;F<8;++F&#41;B&#91;s*16+F+8&#93;=&#40;s&4?s^7&#58;s&#41;+&#40;F&4?F^7&#58;F&#41;; &#125;
    X; /* Make moves given by the GUI */
    for&#40;X;i=X;) R&#40;2,-Q,Q,1,C,d,f,*i-97+&#40;i&#91;1&#93;-49&#41;*16,i&#91;2&#93;-97+&#40;i&#91;3&#93;-49&#41;*16&#41;; &#125;
  Z"go", 2&#41;) &#123;
    for&#40;;i=X;) /* Parse time left */
      if (!strcmp&#40;i+1, "time") & *i==&#40;M&64?119&#58;98&#41;) l=atoi&#40;X&#41;<<9;
    /* Search and print best move */
    for&#40;s=2;N<l;++s&#41; if&#40;R&#40;s,-Q,Q,0,C,d,f,q,q&#41;-q&#41; &#123; t=G;u=H; &#125;
      printf&#40;"bestmove %c%i%c%i%c\n", t%16+97, t/16+1, u%16+97, u/16+1,
             (&#40;B&#91;t&#93;%8==2 && &#40;u/16==0 || u/16==7&#41;) ? 'q' &#58; 0&#41;); &#125;
  fflush&#40;stdout&#41;; /* Ensure our data reaches the GUI */
  main&#40;); &#125; /* 'Loop' back to start */
Hopefully somebody here will find this interesting.

[moderation]
I updated the thread name to Iota instead of Yoda.
/Julien
[/moderation]
User avatar
hgm
Posts: 27789
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by hgm »

Congratulations with your engine! I will certainly check it out one day. (But currently I am a bit busy.) One remark about the name, though:

Did you know there already exists an engine called Yoda? (And that, confusingly enough, the first name of its author is also Daniel?) See, for instance:

http://www.open-aurec.com/chesswar/Open ... penwar.htm
Daniel White
Posts: 33
Joined: Wed Mar 07, 2012 4:15 pm
Location: England

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Daniel White »

Oh my bad, I did a quick search and found nothing so I figured it was unique. I guess I'll have to find a new small character to name it after.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Rein Halbersma »

Daniel White wrote:Oh my bad, I did a quick search and found nothing so I figured it was unique. I guess I'll have to find a new small character to name it after.
Iota?
User avatar
hgm
Posts: 27789
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by hgm »

Smeagol? Thorin? Bilbo?
Daniel White
Posts: 33
Joined: Wed Mar 07, 2012 4:15 pm
Location: England

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Daniel White »

hgm wrote:Smeagol? Thorin? Bilbo?
I had considered the above but Yoda is a much more awesome character :p.
Rein Halbersma wrote:Iota?
I think I quite like this suggestion, thanks!
User avatar
Jim Ablett
Posts: 1383
Joined: Fri Jul 14, 2006 7:56 am
Location: London, England
Full name: Jim Ablett

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Jim Ablett »

Hi Daniel,

Very well done. It's quite remarkable you can get working engine in such a small amount of code.

I compiled a very small windows executable using Tiny C + Upx compression and got the binary size down to an incredible 3.50 kb.

I named it 'Iota' to avoid confusion with other engine.

https://dl.dropbox.com/u/5047625/iota-10-32-tcc-ja.zip

Jim.
Adam Hair
Posts: 3226
Joined: Wed May 06, 2009 10:31 pm
Location: Fuquay-Varina, North Carolina

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Adam Hair »

Jim Ablett wrote:Hi Daniel,

Very well done. It's quite remarkable you can get working engine in such a small amount of code.

I compiled a very small windows executable using Tiny C + Upx compression and got the binary size down to an incredible 3.50 kb.

I named it 'Iota' to avoid confusion with other engine.

https://dl.dropbox.com/u/5047625/iota-10-32-tcc-ja.zip

Jim.
Thanks, Jim. Another engine for the Also-Rans list (as soon as Daniel okays the use of Iota for the name).
Edmund
Posts: 670
Joined: Mon Dec 03, 2007 3:01 pm
Location: Barcelona, Spain

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Edmund »

Jim Ablett wrote:Hi Daniel,

Very well done. It's quite remarkable you can get working engine in such a small amount of code.

I compiled a very small windows executable using Tiny C + Upx compression and got the binary size down to an incredible 3.50 kb.

I named it 'Iota' to avoid confusion with other engine.

https://dl.dropbox.com/u/5047625/iota-10-32-tcc-ja.zip

Jim.
I thought Tiny C was just notable for the small size of the compiler, not the size of its compiles. Couldn't you get better results with intel compiler optimizing for size?
Daniel White
Posts: 33
Joined: Wed Mar 07, 2012 4:15 pm
Location: England

Re: New 'Micro' Chess Engine - Yoda 0.1

Post by Daniel White »

Adam Hair wrote:
Jim Ablett wrote:Hi Daniel,

Very well done. It's quite remarkable you can get working engine in such a small amount of code.

I compiled a very small windows executable using Tiny C + Upx compression and got the binary size down to an incredible 3.50 kb.

I named it 'Iota' to avoid confusion with other engine.

https://dl.dropbox.com/u/5047625/iota-10-32-tcc-ja.zip

Jim.
Thanks, Jim. Another engine for the Also-Rans list (as soon as Daniel okays the use of Iota for the name).
Iota is fine by me! I'll update the original post now... (edit: turns out I'm not allowed to do so)
Last edited by Daniel White on Sat Jul 07, 2012 5:32 pm, edited 1 time in total.