I am creating a class for a chess engine. The class contains information about where each piece is, what moves are allowed, etc. The class also allows a move to be simulated without having to create a new object. The current implementation looks like this:
// in header file
class ChessGame{
int base_var1; // base indicates real game value
int test_var1; // test indicates simulated game value
... many other vars of various types
void makeRealMove(int move); // modifies base values
void makeTestMove(int move); // modifies test values
}
// in src file
void ChessGame::makeRealMove(int move){
base_var1 = move; // lots of code in here
}
void ChessGame::makeTestMove(int move){
test_var1 = move; // identical code here
}
This works, but the code for makeRealMove and makeTestMove is exactly the same, just swapping each test_var with appropriate base_var. What I would like to do is have one function makeMove which can dynamically select the right type of variables to change. This would remove essentially redundant code, make debugging easier, and such. If namespaces were allowed within classes and could be conditionally selected, I would do the following:
// in header file
class ChessGame{
namespace base { int var1; } // plus the other vars
namespace test { int var1; } // plus the other vars
void makeMove(int move, bool condition);
}
// in src file
void ChessGame::makeMove(int move, bool real_move){
if(real_move) { using namespace base; }
else { using namespace test; }
var1 = move; // appropriate variable selected
}
Unfortunately, namespaces cannot be nested in a class, and even if they could be, I could not select between two of them in this manner. So is there a way to get this kind of behavior, or am I stuck with my current approach?
You can use a class instead of a namespace:
class ChessGame{
struct Vars {
int var1; // plus the other vars
};
Vars realGame;
Vars testGame;
void makeMove(int move, bool condition);
void makeMoveImpl(int move, Vars &vars);
};
void ChessGame::makeMove(int move, bool real_move) {
if (real_move) makeMoveImpl(move, realGame);
else makeMoveImpl(move, testGame);
}
void ChessGame::makeMoveImpl(int move, Vars &vars) {
vars.var1 = move; // appropriate variable selected
}
Note that based on your design, it might make sense to make Vars
a global class instead of a nested one (while still storing two instances of it inside ChessGame
). makeMoveImpl
could then even become a member function of Vars
and ChessGame
would serve just as a delegator to one or the other.
class ChessGame{
std::array<int, 2> var; // var[0] == real game value, var[1]== simulated game value
//... many other vars of various types
void makeRealMove(int move){makeMove(move,false);};
void makeTestMove(int move){makeMove(move,true);};
void makeMove(int move, bool test){
var[test]= move;
// lots of code in here
};
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With