C programming style question

Discussion of chess software programming and technical issues.

Moderators: hgm, Harvey Williamson, bob

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Michael Sherwin
Posts: 2975
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 4:54 am

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;*/
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

Dann Corbit
Posts: 9433
Joined: Wed Mar 08, 2006 7:57 pm
Location: Redmond, WA USA
Contact:

Re: C programming style question

Post by Dann Corbit » Tue Jan 19, 2016 5:19 am

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: 1327
Joined: Sun Jul 17, 2011 9:14 am

Re: C programming style question

Post by ZirconiumX » Tue Jan 19, 2016 7:19 am

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: 2975
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 7:22 am

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?
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

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

Re: C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 7:27 am

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
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

abulmo
Posts: 151
Joined: Thu Nov 12, 2009 5:31 pm
Contact:

Re: C programming style question

Post by abulmo » Tue Jan 19, 2016 7:48 am

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: 2975
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 8:36 am

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;
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

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

Re: C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 8:41 am

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.
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

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

Re: C programming style question

Post by Michael Sherwin » Tue Jan 19, 2016 9:32 am

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.
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 3:48 am

Re: C programming style question

Post by kbhearn » Tue Jan 19, 2016 12:43 pm

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.

Post Reply