A small "being there, done that" suggestion... migrating my chess engine from a 0x88 board representation to bitboard was relatively simple. Obtaining a performance improvement was way harder than I expected.
The fact is that you can have a wonderful design for your board/piece class, perfect modularity, minimum dependencies among classes... but it's sure that you must have arranged your evaluation logic depending on what you can do fast or slow (and this is linked to board representation).
Changing the board representation will trigger changes in the static evaluation logic: that's complex, time consuming and risky.
Moreover, while you change the evaluation logic, you discover that some search extensions aren't needed anymore or that you need a better quiescence search.
Eventually you could have a completely different player.
So you can start with a "temporary" board representation but everything should be done bearing in mind the final representation (strong/weak points of a representation you are not using could be unexpected).
Your implementation is the typical Team/Members relationship.
The Team object (the board) will have pointers to its Members (the pieces) and the members will also have a back pointer to their Team object.
weak_ptr is used to break the dependency cycle: the "owner" use
shared_ptr and the "owned" use a
weak_ptr to its parent and convert it temporarily to
shared_ptr when it needs access to its parent.
So, from this point of view, it's a correct implementation.
getPossibleMoves() function will need the piece position to perform its task.
The function could find out the position scanning the board but this would slow down the move generation. To avoid data redundancy you shouldn't store the coordinates inside
getPossibleMoves() will need two arguments:
std::list<Move> ThePiece::getPossibleMoves(unsigned row, unsigned column)
auto moves = b[row][column]->getPossibleMoves(row, column);
Now why not remove the
myBoard injected dependency from
Piece and add one more argument to
std::list<Move> ThePiece::getPossibleMoves(const Board &b, unsigned row, unsigned column)
After this change the shared_ptr aren‘t required anymore... along this way we‘re going to completely change the design.