Okay, so here’s the context. I’ve been up for almost a day straight now working on the legendary 8-puzzle problem. I have my heuristics down and my A_star algorithm down. We are required by the project spec to solve it using three different heuristic values. I can solve it for any one of the three individually, but when I go to solve them in succession, I get a ridiculous loop, and it never finds the correct successor state.
I believe my problem is with my pointers. I have a class, State, as defined below that has an int** array and a pointer to a State (its parent).
EDIT: I have to use int** as defined by the project specification, otherwise I would gladly use a pointer.
State (int **bd, State* prnt);
State (const State& other);
~State ();
I am then declaring them as such:
State::State(int **bd, State* prnt) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
}
// fill in the board
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = bd[i][j];
//board[i][j] =
}
}
// set the parent
parent = prnt;
}
State::State(const State& other) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
delete board[i];
delete [] board;
delete parent;
parent = other.parent;
}
State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
delete board[i];
delete [] board;
delete parent;
}
State& State::operator=(const State &rhs) {
if (&rhs == this) {
return *this;
}
for (int i = 0; i < 3; i++) {
delete board[i];
}
delete [] board;
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
board[i] = new int[3];
}
// fill in the board
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//board[i][j] = rhs.board[i][j];
board[i][j] = rhs.getIntAtCoor(j, i);
}
}
//delete parent;
// set the parent
parent = rhs.parent;
// set g
g = rhs.g;
f = rhs.f;
hType = rhs.hType;
return *this;
}
I don’t give the exact declarations — some of it is simple like int = int. I just can’t quite figure it out. I feel like either my delete parent is wrong or my parent = other.parent is wrong (or both).
Thank you for your time and help,
Tyler
Upgrading your code-style may force the errors to evaporate. In other words
newanddeleteare error prone and should be avoided when better alternative exists.For management of the cells consider:
std::shared_ptr: can be used to void thedeletecallsstd::vectorcan be used to avoid thenewanddeletecallsNote you should use it like
std::vector<int> board( 3 * 3 )andboard.at( x + y * 3 ).int board[3][3]. No allocation at all.Also child states do not own their parent states. It’s the other way around. So child states shouldn’t delete their parents. You can still safely keep a parent pointer, but make sure you cleanup the children before you allow a parent to go out of scope (deleted or otherwise). All of this cleaning and deleting doesn’t neccessarily involve new at all. Your
Stateclass looks small enough that is doesn’t matter if they are copied by value. In which case just have the parent use astd::vector<State> m_childrenand the compiler will take care of the rest.