Diepeveen's move generator

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Hrvoje Horvatic

Diepeveen's move generator

Post by Hrvoje Horvatic »

I'm puzzled about the speed of square-oriented vs bitboard-based move generators... I've checked existing open source programs and the best result I got was from cpw (0x88 based), which was about 20-25% slower than crafty (baseline bitboard engine with magic-based slider attacks)... I've checked both sources, and they seem to do the same thing, both are intel-compiled, so at first blush my crude comparison seems legit...

The rumor has it that Diepeveen's table-based move generator is THE move generator, and that it beats "beancounters" easily, because it's cache optimized...

Has anyone actually tried to do a comparison? a real comparison? Instead of just arguing? I would have done it, but don't have a complete source code, only some small patches left in a forum by Vincent here and there... which I couldn't turn into a working move generator... :oops:

hmmmm? anybody?
Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: Diepeveen's move generator

Post by Gerd Isenberg »

I just found some more code of Vincent's generator in Mridul Muralidharan's Random thought blog:
http://mridulm.blogspot.de/2004/06/perm ... ut-up.html
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: Diepeveen's move generator

Post by ZirconiumX »

A discussion in the Olympus ICS came up about this.

The result was we thought that it was useless, because he didn't explain how the arrays worked, jus gave code which we weren't even sure worked.

If it did work, and VD would tell us how it worked, then we would use it hands down, because it seems quick.

Matthew:out
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Hrvoje Horvatic

Re: Diepeveen's move generator

Post by Hrvoje Horvatic »

Gerd Isenberg wrote:I just found some more code of Vincent's generator in Mridul Muralidharan's Random thought blog:
http://mridulm.blogspot.de/2004/06/perm ... ut-up.html
Gerd to the rescue... :D

I'v looked at the code, and it looks usable... many parts of a complete move generator are missing, but it seems that most important parts are there, procedure for initialization of arrays (table), and a two procedures for using those arrays for generating moves... I might be more lucky than Matthew...

I'll report results later...
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Diepeveen's move generator

Post by diep »

Gerd Isenberg wrote:I just found some more code of Vincent's generator in Mridul Muralidharan's Random thought blog:
http://mridulm.blogspot.de/2004/06/perm ... ut-up.html
I have a slightly improved version, which i made in 2005, i'll post it here some hours from now.

It orders the PieceList a tad different, so that removes 2 branches from
which at least 1 real slow.

Which effectively speeds it up a lot.

The generation table is still the same though.
I'll post that code a tad later over here.

Also you want of course unsigned char's and unsigned integers
if you want to compile 64 bits - no need to mention that to you.

The advantages of the move generator are:

a) relative small tables needed to generate moves (when compared to bitboards)

b) very straightforward semi-legal move generation

We can prove it's faster than bitboards to generate moves with it,
as we don't need to get bits out of a bitboard, which is a real slow operation for bitboards.

Note i designed the original table concept around 1996-1998

I would need to lookup the exact year to know for sure which year it was.
Would be findable in my source code.

In 2005 for a fast beancounter i removed some slow branches by redoing the piecelist.

This move generator will run fast on ARM cpu's as well.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Diepeveen's move generator

Post by diep »

ZirconiumX wrote:A discussion in the Olympus ICS came up about this.

The result was we thought that it was useless, because he didn't explain how the arrays worked, jus gave code which we weren't even sure worked.

If it did work, and VD would tell us how it worked, then we would use it hands down, because it seems quick.

Matthew:out
What's this for focking nonsense.

I emailed the entire code, which includes building up the tables, to at least 30 persons past years. To 100% of those who asked.

It's possible i posted it to CCC one day as well - not sure about it.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Diepeveen's move generator

Post by diep »

Hrvoje Horvatic wrote:
Gerd Isenberg wrote:I just found some more code of Vincent's generator in Mridul Muralidharan's Random thought blog:
http://mridulm.blogspot.de/2004/06/perm ... ut-up.html
Gerd to the rescue... :D

I'v looked at the code, and it looks usable... many parts of a complete move generator are missing, but it seems that most important parts are there, procedure for initialization of arrays (table), and a two procedures for using those arrays for generating moves... I might be more lucky than Matthew...

I'll report results later...
Had you considered shipping me an e-mail?

I responded to 100% of everyone who emailed with a C file that has everything.

And if you lookup old discussions that's what i asked people to do.
The reason i don't have it on a homepage is simple: i don't have a homepage currently.

This is the ultimate proof of how bad CCC works.

RGCC back then was much better. If you googled back then you could find everything.

CCC as a closed forum is way more complicated there.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Diepeveen's move generator

Post by diep »

Hrvoje Horvatic wrote:I'm puzzled about the speed of square-oriented vs bitboard-based move generators... I've checked existing open source programs and the best result I got was from cpw (0x88 based), which was about 20-25% slower than crafty (baseline bitboard engine with magic-based slider attacks)... I've checked both sources, and they seem to do the same thing, both are intel-compiled, so at first blush my crude comparison seems legit...

The rumor has it that Diepeveen's table-based move generator is THE move generator, and that it beats "beancounters" easily, because it's cache optimized...

Has anyone actually tried to do a comparison? a real comparison? Instead of just arguing? I would have done it, but don't have a complete source code, only some small patches left in a forum by Vincent here and there... which I couldn't turn into a working move generator... :oops:

hmmmm? anybody?
You really should ship an email you know.
But here is the latest revision of gpl.c. An earlier version i shipped to Stallman to include in gnuchess 6 at the time.

I'll post after that what i do since 2005 in diepsnel.c a fast chessprogram getting 2.5 million nps. It's just a small change.

Please note the code below is for 32 bits compiles. It is at x64 FASTER to use 'unsigned int' and 'unsigned char' everywhere instead of 'int' which is signed.

Gerd can explain all this.

Also note the way how the moves are in this code. You also can do things the crafty way there and just

*move++ = ... ;

In Diep a move exists out of 2 integers, which is not as fast obviously as using 1, yet that 2.5 mln nps beancounter (at a K7 2.1Ghz and that's without PGO in fact) is compatible with Diep, which slows it tad down obviously. Also as you see i already assign scores to moves while generating, so then you just pick the highest score and play that move first. It removes at least 1 slow loop for the SEE during search.

This is a search optimized move generator in fact. So it's not meant to be used for stuff like perft obviously.

So if you want bare nps speed - use 1 unsigned integer for speed.

Code: Select all

/*
Gnu public license here.
See copy of it at FSF (free software foundation)
*/

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


int
  color[64], // having 0 = white, 1 = black, 2 = neutral
  board[64], // having 0 = empty, pawn=1,knight=2,bishop=3,rook=4,queen=5,king=6
  snelbord[64], // for white same as board[64], for black same as white but with a +8 for each piece
                // like whitepawn = 1, blackpawn = 9


  gentable[3][64][128], //* 24k loper, toren, dame *
  iskippos[64][64],     /*      l t d */
  ipiecepos[7][64][32], /* 0 = witte pion, 1 = zwarte pion, 2 = knight ... 6 = koning */
  ipawndir[2][64][4];   /* slagzetten */


void QuickFullMoveList(int side,struct Move *EP) {
/* Generate semi-legal moves in fast manner
*/
  int to,xside,*psq,sq,*t;

  xside = side^1;
  to    = EP->zet&63;
  if( board[to] == pawn ) { /* for enpassant */
    int from = (EP->zet>>6)&63;
    if( to-from == 16 || from-to == 16 ) {
      int f,*w,u;
      f = (to+from)>>1;
      w = ipawndir[xside][f];
      u = *w++;
      if( color[u] == side && board[u] == pawn ) {
        genindex->score = 1000;
        QuickLink&#40;&#40;u<<6&#41;|f|move_captures|move_enpassant&#41;;
      &#125;

      if&#40; &#40;u=*w&#41; != 128 && color&#91;u&#93; == side && board&#91;u&#93; == pawn ) &#123;
        genindex->score = 1000;
        QuickLink&#40;&#40;u<<6&#41;|f|move_captures|move_enpassant&#41;;
      &#125;
    &#125;
  &#125;

  if&#40; !castld&#91;side&#93; ) &#123;
    int u = PieceList&#91;side&#93;&#91;0&#93;;
    if&#40; quickcastle&#40;side,u,u+2&#41; ) &#123;
      genindex->score = 0;
      QuickLink&#40;&#40;u<<6&#41;|&#40;u+2&#41;|move_castles&#41;;
    &#125;
    if&#40; quickcastle&#40;side,u,u-2&#41; ) &#123;
      genindex->score = 0;
      QuickLink&#40;&#40;u<<6&#41;|&#40;u-2&#41;|move_castles&#41;;
    &#125;
  &#125;

  t    = cancapside&#91;side&#93;;
  psq  = &quickpiecelist&#91;side&#93;&#91;12&#93;; /* Q R B */
  while&#40; &#40;sq=*psq++) != 128 ) &#123;
    int SRsq  = &#40;sq<<6&#41;;
    int piece = board&#91;sq&#93;;
    int *s,*v,*w,u;

    s = andscan&#91;0&#93;;
    v = ipiecepos&#91;piece&#93;&#91;sq&#93;;
    w = iskippos&#91;sq&#93;;
    u = *v++;
    do &#123;
      int p1=snelbord&#91;u&#93;,sh=w&#91;u&#93;;
      v += &#40;s&#91;p1&#93;&sh&#41;;
      if&#40; (&#40;p1-1&#41;>>3&#41; != side ) &#123;
        genindex->score = pvals&#91;p1&#93;;
        QuickLink&#40;SRsq|u|t&#91;p1&#93;);
      &#125;
    &#125; while&#40; &#40;u=*v++) != 128 );
  &#125;

  psq  = &quickpiecelist&#91;side&#93;&#91;26&#93;; /* pawns */
  while&#40; &#40;sq=*psq++) != 128 ) &#123;
    int SRsq  = &#40;sq<<6&#41;;
    int u,*v,*w;
    v = ipiecepos&#91;side&#93;&#91;sq&#93;;
    w = ipawndir&#91;side&#93;&#91;sq&#93;;
    u = *v++;
    if&#40; row&#40;u&#41; != 0 && row&#40;u&#41; != 7 ) &#123;
      if&#40; color&#91;u&#93; == neutral&#41; &#123;
        genindex->score = 0;
        QuickLink&#40;SRsq|u&#41;;
        if&#40; &#40;u=*v&#41; != 128 && color&#91;u&#93; == neutral ) &#123; /* indien u == sq dan false */
          genindex->score = 0;
          QuickLink&#40;SRsq|u&#41;;
        &#125;
      &#125;

      u = *w++;
      if&#40; color&#91;u&#93; == xside ) &#123; /* ppos bevat geen 100, maar sq. */
        genindex->score = pvals&#91;snelbord&#91;u&#93;&#93;;
        QuickLink&#40;SRsq|u|move_captures&#41;;
      &#125;
      if&#40; &#40;u=*w&#41; != 128 && color&#91;u&#93; == xside ) &#123; /* zelf ben je per definitie side */
        genindex->score = pvals&#91;snelbord&#91;u&#93;&#93;;
        QuickLink&#40;SRsq|u|move_captures&#41;;
      &#125;
    &#125;
    else &#123;
      if&#40; color&#91;u&#93; == neutral&#41; &#123;
        genindex->score = pvals&#91;queen&#93;;
        QuickLink&#40;SRsq|u|move_pqueen&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_pknight&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_prook&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_pbishop&#41;;
      &#125;
      u = *w++;
      if&#40; color&#91;u&#93; == xside&#41; &#123;/* captures */
        genindex->score = pvals&#91;queen&#93;;
        QuickLink&#40;SRsq|u|move_captures|move_pqueen&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_pknight&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_prook&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_pbishop&#41;;
      &#125;

      if&#40; &#40;u=*w&#41; != 128 && color&#91;u&#93; == xside&#41; &#123;
        genindex->score = pvals&#91;queen&#93;;
        QuickLink&#40;SRsq|u|move_captures|move_pqueen&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_pknight&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_prook&#41;;
        genindex->score = 0;
        QuickLink&#40;SRsq|u|move_captures|move_pbishop&#41;;
      &#125;
    &#125;
  &#125;

  psq = quickpiecelist&#91;side&#93;; /* K N */
  while&#40; &#40;sq=*psq++) != 128 ) &#123;
    int SRsq  = &#40;sq<<6&#41;;
    int piece = board&#91;sq&#93;;

    int u,*v;
    v = ipiecepos&#91;piece&#93;&#91;sq&#93;;
    u = *v++;
    do &#123;
      int p1 = snelbord&#91;u&#93;;
      if&#40; (&#40;p1-1&#41;>>3&#41; != side ) &#123;
        genindex->score = pvals&#91;p1&#93;;
        QuickLink&#40;SRsq|u|t&#91;p1&#93;);
      &#125;
    &#125; while&#40; &#40;u=*v++) != 128 );
  &#125;

&#125; /* End QuickFullMoveList&#40;) */

void InitGens&#40;void&#41; &#123;
  /* vul tabellen voor een 8x8 bord */
  int
    paardspring&#91;8&#93;  = &#123;15,-15,17,-17,6,-6,10,-10&#125;,
    koningvlucht&#91;8&#93; = &#123;7,-7,9,-9,8,-8,1,-1&#125;,
    alldirec&#91;3&#93;&#91;8&#93;  = &#123; /* delta richtingen op een 8x8 bord */
      &#123;7,-7,9,-9,0,0,0,0&#125;,
      &#123;8,-8,1,-1,0,0,0,0&#125;,
      &#123;7,-7,9,-9,8,-8,1,-1&#125;
    &#125;,
    nsq,sq,flag,i,j,next_sq,rij,piece,np,lijn,m,ms,c,t,old_sq,
    skipm&#91;16&#93;,
    rij8&#91;2&#93;      = &#123;7,0&#125;,
    rij2&#91;2&#93;      = &#123;1,6&#125;,
    slalinks&#91;2&#93;  = &#123;7,-9&#125;,
    slarechts&#91;2&#93; = &#123;9,-7&#125;,
    veuren&#91;2&#93;    = &#123;8,-8&#125;,

    /* 12x12 bord delta-coordinaten */
    numberpiece&#91;3&#93; = &#123;bishop,rook,queen&#125;,
    numberfields&#91;3&#93; = &#123;4,4,8&#125;,
    direc&#91;3&#93;&#91;10&#93; = &#123; /* richtingen op een 12x12 bord */
     &#123;11,-11,13,-13,0,0,0,0,0,0&#125;, /* loper */
     &#123;12,-12,1 ,-1 ,0,0,0,0,0,0&#125;, /* toren */
     &#123;11,-11,13,-13,12,-12,1 ,-1,0,0&#125;  /* dame */
    &#125;,
    vlucht&#91;8&#93; = &#123;11,-11,13,-13,12,-12,1 ,-1&#125;, /* koning */
    spring&#91;8&#93; = &#123;23,-23,25,-25,10,-10,14,-14&#125;;/* paard */

  for&#40; sq = 0 ; sq < 64 ; sq++ )
    for&#40; m = 0 ; m < 64 ; m++ )
      iskippos&#91;sq&#93;&#91;m&#93; = 0;

  for&#40; i = 0 ; i < 7 ; i++ ) /* default value */
    for&#40; sq = 0 ; sq < 64 ; sq++ )
      for&#40; m = 0 ; m < 32 ; m++ )
        ipiecepos&#91;i&#93;&#91;sq&#93;&#91;m&#93; = 128;

  /* pionnen */
  for&#40; sq = 0 ; sq < 64 ; sq++ ) &#123;
    lijn = sq&7;
    rij  = sq/8;
    nsq  = 26 + rij*12 + lijn;

    for&#40; c = white ; c <= black ; c++ ) &#123; /* pion&#58; wit en zwart */
      if&#40; rij == rij8&#91;c&#93; )
        ipawndir&#91;c&#93;&#91;sq&#93;&#91;0&#93; = 128;
      else &#123;
        m = 0;
        if&#40; lijn != 7 ) &#123;
          ipawndir&#91;c&#93;&#91;sq&#93;&#91;m&#93; = &#40;sq+slarechts&#91;c&#93;);
          m++;
        &#125;
        if&#40; lijn != 0 ) &#123;
          ipawndir&#91;c&#93;&#91;sq&#93;&#91;m&#93; = &#40;sq+slalinks&#91;c&#93;);
          m++;
        &#125;
        ipawndir&#91;c&#93;&#91;sq&#93;&#91;m&#93; = 128;

        m = 0;
        ipiecepos&#91;c&#93;&#91;sq&#93;&#91;m&#93; = &#40;sq+veuren&#91;c&#93;);
        m++;
        if&#40; rij == rij2&#91;c&#93; )
          ipiecepos&#91;c&#93;&#91;sq&#93;&#91;m&#93; = &#40;sq+2*veuren&#91;c&#93;);
      &#125;
    &#125;

    m = 0;
    old_sq = sq;
    for&#40; i = 0; i < 8; i++ ) &#123;/* paard */
      t = nsq+spring&#91;i&#93;;
      if&#40; nunmap&#91;t&#93; >=  0 ) &#123;
        ipiecepos&#91;knight&#93;&#91;sq&#93;&#91;m&#93; = nunmap&#91;t&#93;;
        m++;
        old_sq = nunmap&#91;t&#93;;
      &#125;
    &#125;
    ipiecepos&#91;knight&#93;&#91;sq&#93;&#91;m&#93; = 128;

    m = 0;
    old_sq = sq;
    for&#40; i = 0; i < 8; i++ ) &#123; /* koning */
      t = nsq+vlucht&#91;i&#93;;
      if&#40; nunmap&#91;t&#93; >=  0 ) &#123;
        ipiecepos&#91;king&#93;&#91;sq&#93;&#91;m&#93; = nunmap&#91;t&#93;;
        m++;
        old_sq = nunmap&#91;t&#93;;
      &#125;
    &#125;
    ipiecepos&#91;king&#93;&#91;sq&#93;&#91;m&#93; = 128;

    for&#40; np = 0 ; np < 3 ; np++ ) &#123; /* loper,toren,dame */
      piece = numberpiece&#91;np&#93;;
      m = 0;
      ms = 0;
      flag = 0;

      j = 0;
      while&#40; nunmap&#91;nsq+direc&#91;np&#93;&#91;j&#93;&#93; == -1 )
        j++;

      for&#40; i = 0; i < numberfields&#91;np&#93;; i++ ) &#123; /* voor alle richtingen */
        int sqdone=0;

        t = nsq;
        t = t+direc&#91;np&#93;&#91;i&#93;;

        j = i+1;
        while&#40; nunmap&#91;nsq+direc&#91;np&#93;&#91;j&#93;&#93; == -1 )
          j++;
        next_sq = nunmap&#91;nsq+direc&#91;np&#93;&#91;j&#93;&#93;;

        while&#40; nunmap&#91;t&#93; != -1 ) &#123;
          sqdone++;
          ipiecepos&#91;piece&#93;&#91;sq&#93;&#91;m&#93; = nunmap&#91;t&#93;;

          m++;
          t = t+direc&#91;np&#93;&#91;i&#93;;
          flag = 1;
        &#125;

        if&#40; sqdone >= 2 && np <= 1 ) &#123;
          /* alleen als er bij from-to daarna nog velden af
           * te gaan zijn dan is het interessant. Anders 0.
           * Dame hoeft niet want toren,loper al gedaan */
          int my12sq/*,yesdeze=false*/;
          /* begonnen met  nsq &#40;12x12&#41; + delta &#40;direc&#91;np&#93;&#91;i&#93;)
           * */

          my12sq = nsq+direc&#91;np&#93;&#91;i&#93;;
          do &#123;
            /* 8x8 bord opslaan */
            sqdone--;
            my12sq += direc&#91;np&#93;&#91;i&#93;;
          &#125; while&#40; sqdone >= 2 );
        &#125;

        if&#40; flag ) &#123;
          flag = 0;
          skipm&#91;ms&#93; = m;
          ms++;
        &#125;
      &#125;
      ipiecepos&#91;piece&#93;&#91;sq&#93;&#91;m&#93; = 128;

      m  = 0;
      ms = 0;
      t  = ipiecepos&#91;piece&#93;&#91;sq&#93;&#91;m&#93;;
      if&#40; np == 2 ) &#123; /* skippos alleen voor de dame vullen dat is genoeg */
        do &#123;
          iskippos&#91;sq&#93;&#91;t&#93; = &#40;skipm&#91;ms&#93;-m&#41;-1;
          m++;
          t = ipiecepos&#91;piece&#93;&#91;sq&#93;&#91;m&#93;;
          if&#40; m == skipm&#91;ms&#93; )
            ms++;
        &#125; while&#40; t != 128 );
      &#125;
    &#125;
  &#125;
&#125;
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: Diepeveen's move generator

Post by diep »

By the way i notice a difference between some of the move generators.

The generation loops for heavy pieces and light pieces you can also rewrite to next code without problems.

It really depends upon which CPU you got what is faster.

For sliders:

Code: Select all

      s = andscan&#91;0&#93;;
      v = ipiecepos&#91;piece&#93;&#91;sq&#93;;
      w = iskippos&#91;sq&#93;;
      u = *v++;
      do &#123;
        int p1=snelbord&#91;u&#93;,sh=w&#91;u&#93;;
        v += &#40;s&#91;p1&#93;&sh&#41;;
        genindex->zet = SRsq|u|t&#91;p1&#93;;
        genindex     += lm&#91;p1&#93;;
      &#125; while&#40; &#40;u=*v++) != 128 );
And for King/Knight:

Code: Select all

  int u,*v;
      v = ipiecepos&#91;piece&#93;&#91;sq&#93;;
      u = *v++;
      do &#123;
        int p1 = snelbord&#91;u&#93;;
        genindex->zet = SRsq|u|t&#91;p1&#93;;
        genindex     += lm&#91;p1&#93;;
      &#125; while&#40; &#40;u=*v++) != 128 );
As you see it's 1 short branch less - yet at some MODERN processors, especially AMD, short branches are fast sometimes. I didn't benchmark this at core2 / i7 yet. In diep i'm crisscross using both ways to generate.

No deliberate attention given to it lately...

I did do the rewrite at the time as GCC f's up with branches.

edit: ok i see there is also lm here. Forgot to cut'n paste it.
it's initialized of course before the slider pieces loop:

Code: Select all

int
  linkmask&#91;2&#93;&#91;16&#93; = &#123;
    &#123; 1,0,0,0,0,0,0,0,         /* white is 1 when move is legal to piece in question */
      0,1,1,1,1,1,1,0          /* black pieces are 8 + piece, so pawn = 1 ==> bpawn = 8+1 = 9 */
    &#125;,
    &#123; 1,1,1,1,1,1,1,0,         /* black is 1 when move is legal */
      0,0,0,0,0,0,0,0
    &#125;
  &#125;;

lm = linkmask&#91;side&#93;;
Tom Likens
Posts: 303
Joined: Sat Apr 28, 2012 6:18 pm
Location: Austin, TX

Re: Diepeveen's move generator

Post by Tom Likens »

diep wrote:Had you considered shipping me an e-mail?
Yes, I would think if someone were interested in the Diep move generator, sending you an email
would be the quickest (and safest) way to get it. That *might* even be the best way to get any
questions you might have answered correctly.

My guess is you have 100% of the code for "Diepeveen's move generator" :wink:

regards,
--tom