C programming style question

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

C programming style question

Post by Michael Sherwin »

I've started a new project using classical bitboards in an incremental move generation scheme. I am having trouble deciding whether to keep the 8 BRQ directional bitboards in a two dimensional array, dirXX[8][64], or just create 8 separate arrays. I would like the first way if it were not for the fact that pawns need their own separate arrays anyway. It would be simply more consistent to use separate arrays. Another consideration is it might be necessary to resort to using pointers (see below) for efficiency if using separate arrays. I am planning a plain vanilla 101 TSCP philosophy chess engine with only the most basic of everything for anyone to use as a seed engine and I want to do a good job.

Code: Select all

//sample code initializes the classical directional bitboards
#define s32   signed __int32
#define u64 unsigned __int64

s32 mailBox[120] = {-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, 8, 9,10,11,12,13,14,15,-1,
                    -1,16,17,18,19,20,21,22,23,-1,
                    -1,24,25,26,27,28,29,30,31,-1,
                    -1,32,33,34,35,36,37,38,39,-1,
                    -1,40,41,42,43,44,45,46,47,-1,
                    -1,48,49,50,51,52,53,54,55,-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};

u64 dirNW[64];
u64 dirNN[64];
u64 dirNE[64];
u64 dirEE[64];
u64 dirSE[64];
u64 dirSS[64];
u64 dirSW[64];
u64 dirWW[64];

void Initiate(void);
s32 __cdecl main(void);

void Initiate() {
s32 i,j,k,m,s; 
u64 *dirXX[8] = {dirNW,dirNN,dirNE,dirEE,dirSE,dirSS,dirSW,dirWW};
s32 bb64[8] = {7,8,9,1,-7,-8,-9,-1};
s32 mB120[8] = {9,10,11,1,-9,-10,-11,-1};

for&#40;i = 21; i < 99; i++) &#123;
  if&#40;mailBox&#91;i&#93; != -1&#41; &#123; 
    s = mailBox&#91;i&#93;;
    for&#40;m = 0; m < 8; m++) &#123;
      j = i + mB120&#91;m&#93;;
      k = s + bb64&#91;m&#93;;
      *&#40;dirXX&#91;m&#93; + s&#41; = 0;
      while&#40;mailBox&#91;j&#93; != -1&#41; &#123;
        *&#40;dirXX&#91;m&#93; + s&#41; ^= &#40;u64&#41;1 << k;
        j = j + mB120&#91;m&#93;;
        k = k + bb64&#91;m&#93;;
      &#125;
    &#125;
  &#125;
&#125;


&#125;

s32 __cdecl main&#40;)&#123;
  Initiate&#40;);
  return&#40;1&#41;;
&#125;


/*#define s32   signed __int32
#define u64 unsigned __int64

s32 mailBox&#91;120&#93; = &#123;-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, 8, 9,10,11,12,13,14,15,-1,
                    -1,16,17,18,19,20,21,22,23,-1,
                    -1,24,25,26,27,28,29,30,31,-1,
                    -1,32,33,34,35,36,37,38,39,-1,
                    -1,40,41,42,43,44,45,46,47,-1,
                    -1,48,49,50,51,52,53,54,55,-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&#125;;

u64 dirXX&#91;8&#93;&#91;64&#93;;

void Initiate&#40;void&#41;;
s32 __cdecl main&#40;void&#41;;

void Initiate&#40;) &#123;
s32 i,j,k,m,s; 
s32 bb64&#91;8&#93; = &#123;7,8,9,1,-7,-8,-9,-1&#125;;
s32 mB120&#91;8&#93; = &#123;9,10,11,1,-9,-10,-11,-1&#125;;

for&#40;i = 21; i < 99; i++) &#123;
  if&#40;mailBox&#91;i&#93; != -1&#41; &#123; 
    s = mailBox&#91;i&#93;;
    for&#40;m = 0; m < 8; m++) &#123;
      j = i + mB120&#91;m&#93;;
      k = s + bb64&#91;m&#93;;
      dirXX&#91;m&#93;&#91;s&#93; = 0;
      while&#40;mailBox&#91;j&#93; != -1&#41; &#123;
        dirXX&#91;m&#93;&#91;s&#93; ^= &#40;u64&#41;1 << k;
        j = j + mB120&#91;m&#93;;
        k = k + bb64&#91;m&#93;;
      &#125;
    &#125;
  &#125;
&#125;


&#125;

s32 __cdecl main&#40;)&#123;
  Initiate&#40;);
  return&#40;1&#41;;
&#125;*/
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Dann Corbit
Posts: 12537
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: C programming style question

Post by Dann Corbit »

Use typedef for types, not #define
The __cdecl function calling attribute is non portable.
So do something like this:

#ifdef _MSC_VER
#define CDECL __cdecl
#else
#define CDECL
#endif

Some of your variable names are too short for my taste.
For instance:
s32 bb64[8] = {7,8,9,1,-7,-8,-9,-1};
bb64 sounds like an array of bitboards, but it is 32 bits.
Probably, these are shifts, but it is not clear.
If they are bitboard shift directions, then call it that.

instead of magic numbers like:
return (1);
use:
return EXIT_SUCCESS;

Initiate() is a strangely vague function name. Initiate what?
InitializeGameStructures() appears to be what you are doing.

But you can't please everyone. So do it the way you like.
I'm a fussy sort.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
ZirconiumX
Posts: 1334
Joined: Sun Jul 17, 2011 11:14 am

Re: C programming style question

Post by ZirconiumX »

In addition to Dann's comments, I would #include <inttypes.h> and use uint64_t and sint32_t for u64 and s32 respectively.

Matthew:out
Some believe in the almighty dollar.

I believe in the almighty printf statement.
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin »

Thanks Dann your reply is very helpful as I do want to write portable and correct code.

So by not answering my main question are you saying that it is not an important consideration?
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin »

ZirconiumX wrote:In addition to Dann's comments, I would #include <inttypes.h> and use uint64_t and sint32_t for u64 and s32 respectively.

Matthew:out
s32 looks clean to me and sint32_t not so much. Is it a portability issue that I should use sint32_t? Or? Thanks
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
abulmo
Posts: 151
Joined: Thu Nov 12, 2009 6:31 pm

Re: C programming style question

Post by abulmo »

Both methods are equivalent.
Note that *(a + i) is the same as a, so you can write dirXX[m][s] or *(dirxx[m] + s) anywhere in your code.
Richard
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin »

Dann Corbit wrote:Use typedef for types, not #define
The __cdecl function calling attribute is non portable.
So do something like this:

#ifdef _MSC_VER
#define CDECL __cdecl
#else
#define CDECL
#endif

Some of your variable names are too short for my taste.
For instance:
s32 bb64[8] = {7,8,9,1,-7,-8,-9,-1};
bb64 sounds like an array of bitboards, but it is 32 bits.
Probably, these are shifts, but it is not clear.
If they are bitboard shift directions, then call it that.

instead of magic numbers like:
return (1);
use:
return EXIT_SUCCESS;

Initiate() is a strangely vague function name. Initiate what?
InitializeGameStructures() appears to be what you are doing.

But you can't please everyone. So do it the way you like.
I'm a fussy sort.
Dann, does this pass muster?

Code: Select all

#ifdef _MSC_VER
#define CDECL __cdecl
#else
#define CDECL
#endif

typedef unsigned __int32 s32;
typedef   signed __int64 u64;

#define EXIT_SUCCESS 1

s32 mailBox&#91;120&#93; = &#123;-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, 8, 9,10,11,12,13,14,15,-1,
                    -1,16,17,18,19,20,21,22,23,-1,
                    -1,24,25,26,27,28,29,30,31,-1,
                    -1,32,33,34,35,36,37,38,39,-1,
                    -1,40,41,42,43,44,45,46,47,-1,
                    -1,48,49,50,51,52,53,54,55,-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&#125;;

u64 dirNW&#91;64&#93;;
u64 dirNN&#91;64&#93;;
u64 dirNE&#91;64&#93;;
u64 dirEE&#91;64&#93;;
u64 dirSE&#91;64&#93;;
u64 dirSS&#91;64&#93;;
u64 dirSW&#91;64&#93;;
u64 dirWW&#91;64&#93;;

void InitData&#40;void&#41;;
s32 CDECL main&#40;void&#41;;

void InitData&#40;) &#123;
  s32 i,j,k,m,sq; 
  u64 *dirXX&#91;8&#93; = &#123;dirNW,dirNN,dirNE,dirEE,dirSE,dirSS,dirSW,dirWW&#125;;
  s32 board64Off&#91;8&#93; = &#123;7,8,9,1,-7,-8,-9,-1&#125;;
  s32 mailBoxOff&#91;8&#93; = &#123;9,10,11,1,-9,-10,-11,-1&#125;;

  for&#40;i = 21; i < 99; i++) &#123;
    if&#40;mailBox&#91;i&#93; != -1&#41; &#123; 
      sq = mailBox&#91;i&#93;;
      for&#40;m = 0; m < 8; m++) &#123;
        j = i + mailBoxOff&#91;m&#93;;
        k = sq + board64Off&#91;m&#93;;
        dirXX&#91;m&#93;&#91;sq&#93; = 0;
        while&#40;mailBox&#91;j&#93; != -1&#41; &#123;
          dirXX&#91;m&#93;&#91;sq&#93; ^= &#40;u64&#41;1 << k;
          j = j + mailBoxOff&#91;m&#93;;
          k = k + board64Off&#91;m&#93;;
        &#125;
      &#125;
    &#125;
  &#125;
&#125;

s32 CDECL main&#40;)&#123;
  InitData&#40;);
  return&#40;EXIT_SUCCESS&#41;;
&#125;
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin »

abulmo wrote:Both methods are equivalent.
Note that *(a + i) is the same as a, so you can write dirXX[m][s] or *(dirxx[m] + s) anywhere in your code.


I made the change. However, I wonder if a novice will understand that it is a pointer operation.
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin »

I'm now thinking that if I use the 0x88 test a mailbox array is not necessary as the square variable can be incremented if the next index variable passes the test. So I will make that change.
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: C programming style question

Post by kbhearn »

the point is that uint64_t from <stdint.h> is a standard-defined way to request an exactly 64 bit unsigned int while __int64 is an implementation-defined token. It's not a huge difference though.