C++ code for board[8][8] representation

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

ydebilloez
Posts: 163
Joined: Tue Jun 27, 2017 11:01 pm
Location: Lubumbashi
Full name: Yves De Billoëz

C++ code for board[8][8] representation

Post by ydebilloez »

In my program, I use a board[8][8] representation with pieces as follows: blank = 0x20, 'K', 'Q' ...
I could use a representation where blank is 0, king =1, ... but for code simplicity, I preferred to keep the FEN symbols in here.

In order to be able to define static arrays that are not huge (see eval.cpp) and only occupy 13 elements, that can be coded easily, I want to map the piece symbols into integers in the fastest possible way, and came up with a 128 byte array in which some elements are filled in with index values. Coding this in C++11 resulted in below implementation. I really like this mapper implementation as it is just one deference away from the real value and easy to understand.

This generates some compile warning (and probably the crash at exit on Mac OS X could be related to that).

Code: Select all

// .cpp code, create mapper array
vector<int> bPieceIndex = [] {
  vector<int> bIndex(128);
  bIndex['K'] = 1;
  // and so on
  return bIndex;
}();
// warning: declaration requires an exit-time destructor
// warning: requires a global destructor

static int piecevalues[13] = { 0, 2000 };
// dereferencing is as simple as that
int somevar = piecevalues[bPieceIndex['K']];
I was thinking on registering an atexit() and convert bPieceIndex to a class with its destructor overloading the [] operator... but is there another way keeping a mapper array? Suggestions? Any solution that can do this mapping compile time would even be better.

I will probably move to bitboards but this would be avoiding the problem instead of resolving it. I want to resolve.
Yves De Billoëz @ macchess belofte chess
Once owner of a Mephisto I, II, challenger, ... chess computer.
User avatar
Bo Persson
Posts: 243
Joined: Sat Mar 11, 2006 8:31 am
Location: Malmö, Sweden
Full name: Bo Persson

Re: C++ code for board[8][8] representation

Post by Bo Persson »

ydebilloez wrote: Mon Mar 08, 2021 1:40 pm In my program, I use a board[8][8] representation with pieces as follows: blank = 0x20, 'K', 'Q' ...
I could use a representation where blank is 0, king =1, ... but for code simplicity, I preferred to keep the FEN symbols in here.

In order to be able to define static arrays that are not huge (see eval.cpp) and only occupy 13 elements, that can be coded easily, I want to map the piece symbols into integers in the fastest possible way, and came up with a 128 byte array in which some elements are filled in with index values. Coding this in C++11 resulted in below implementation. I really like this mapper implementation as it is just one deference away from the real value and easy to understand.

This generates some compile warning (and probably the crash at exit on Mac OS X could be related to that).

Code: Select all

// .cpp code, create mapper array
vector<int> bPieceIndex = [] {
  vector<int> bIndex(128);
  bIndex['K'] = 1;
  // and so on
  return bIndex;
}();
// warning: declaration requires an exit-time destructor
// warning: requires a global destructor

static int piecevalues[13] = { 0, 2000 };
// dereferencing is as simple as that
int somevar = piecevalues[bPieceIndex['K']];
I was thinking on registering an atexit() and convert bPieceIndex to a class with its destructor overloading the [] operator... but is there another way keeping a mapper array? Suggestions? Any solution that can do this mapping compile time would even be better.

I will probably move to bitboards but this would be avoiding the problem instead of resolving it. I want to resolve.
So why specifically do you prefer

Code: Select all

int somevar = piecevalues[bPieceIndex['K']];
over

Code: Select all

int somevar = piecevalues[K];
??

If you could possibly use a K insted of 'K', you can use

Code: Select all

const int K = 1;
// or
enum PieceIndex {K=1, P=2, etc};
ydebilloez
Posts: 163
Joined: Tue Jun 27, 2017 11:01 pm
Location: Lubumbashi
Full name: Yves De Billoëz

Re: C++ code for board[8][8] representation

Post by ydebilloez »

Bo Persson wrote: Mon Mar 08, 2021 4:04 pm
ydebilloez wrote: Mon Mar 08, 2021 1:40 pm In my program, I use a board[8][8] representation with pieces as follows: blank = 0x20, 'K', 'Q' ...
I could use a representation where blank is 0, king =1, ... but for code simplicity, I preferred to keep the FEN symbols in here.
...
I will probably move to bitboards but this would be avoiding the problem instead of resolving it. I want to resolve.
So why specifically do you prefer

Code: Select all

int somevar = piecevalues[bPieceIndex['K']];
over

Code: Select all

int somevar = piecevalues[K];
??
Thanks, your solution is exactly what I meant by working around the problem instead of resolving it. I know it will simplify code at some places.

One of the reasons is that I used two representations in versions 0.9.x of Belofte, one for keeping up with the GUI (UCI or xboard) and one for the internal program code and it was a hell of keeping both versions synchronous. When outputting search or debug, you need piece symbols, and while evaluating, you need bytes or integers.... it is a choice.

My question is more related to C++ than to chess programming. I do not want to change the structure of a program because I cannot find a way to express it in a language. I used this mapping technique in other languages: assembler, clipper, c, perl, ... so why abandon this in c++?

The real issue is that I define the mapping table as a vector. I could simply define it as an array of size. However, I have other problem cases that are based on strings, and I am looking to a generic solution for getting the vector being destructed in an organised way, thus avoiding a possible crash.

BTW, I also tried by using a bPiece class, getting its value by a method and forgetting all complexity on move-generation or storing other piece related stuff inside the class, but it was a hell when copying a board... 64 copy constructors.... Possibly a postbox solution with pieces in class representation or bitboards will be better, but all those alternatives mean: still no solution around the statically declared complex classes destruction sequence.
Yves De Billoëz @ macchess belofte chess
Once owner of a Mephisto I, II, challenger, ... chess computer.
Sesse
Posts: 300
Joined: Mon Apr 30, 2018 11:51 pm

Re: C++ code for board[8][8] representation

Post by Sesse »

You can't do what you want with std::vector, unless you write the entire initializer list out. But you can with std::array, if you're on C++17 or higher:

Code: Select all

#include <array>
  
constexpr std::array<int, 128> init() {
          std::array<int, 128> ret{0};
          ret['K'] = 1;
          ret['Q'] = 2;
          return ret;
}
constexpr std::array<int, 128> mapping = init();
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: C++ code for board[8][8] representation

Post by Rein Halbersma »

Code: Select all

#include <array>
  
constexpr auto mapping = [] {
    std::array<int, 128> ret{};
    ret['K'] = 1;
    ret['Q'] = 2;
    return ret;
}();
Or you can just use an immediately invoked lambda expression ;-)
ydebilloez
Posts: 163
Joined: Tue Jun 27, 2017 11:01 pm
Location: Lubumbashi
Full name: Yves De Billoëz

Re: C++ code for board[8][8] representation

Post by ydebilloez »

Thanks
Rein Halbersma wrote: Mon Mar 08, 2021 10:23 pm

Code: Select all

constexpr auto mapping = [] {
    std::array<int, 128> ret{};
}();
Sesse wrote: Mon Mar 08, 2021 7:37 pm

Code: Select all

std::array<int, 128> ret{0};
combining this gives:

Code: Select all

// .h
class bEvaluation {
protected:
  static std::array<int, 128> bPieceIndex;
// .cpp
auto bEvaluation::bPieceIndex = [] {
  std::array<int, 128> bIndex{0};
  bIndex['K'] = 1;
  // etc
warning: declaration requires a global constructor

But lets say, we went halfway around the problem in some way. A static array does not need a destructor...

I still have some related problems:

Code: Select all

appInstance& App() {
  static appInstance instance;
// declaration requires exit time constructor
  return instance;
}
void classname::functname(param) const
{
  static std::string sName = "Hello";
warning: declaration requires exit time constructor
Yves De Billoëz @ macchess belofte chess
Once owner of a Mephisto I, II, challenger, ... chess computer.
Sesse
Posts: 300
Joined: Mon Apr 30, 2018 11:51 pm

Re: C++ code for board[8][8] representation

Post by Sesse »

You need the constexpr part.
ydebilloez
Posts: 163
Joined: Tue Jun 27, 2017 11:01 pm
Location: Lubumbashi
Full name: Yves De Billoëz

Re: C++ code for board[8][8] representation

Post by ydebilloez »

Using a simple global c array ended up easier in C++11...

Still stuck on static std::string X = "" in a function that gives the same error.

I assure you, I can fix it with a simple static char[255]... But I want to keep it c++11 and at the same time getting rid of the destructor error warning.
Yves De Billoëz @ macchess belofte chess
Once owner of a Mephisto I, II, challenger, ... chess computer.