State
class represents a game state. My goal is to traverse through all possible game states, and build up a game tree, a vector of Node classes (not present in this example).
I want to keep the memory usage as low as possible during the building of the tree, so only the growing number of the Nodes should take up memory, not the traversing of the possible states. So any guidance is more than welcome.
#include <iostream>
#include <vector>
class State {
public:
State step(int action) {
State new_state(*this);
return new_state;
};
std::vector<int> legal_actions() {
std::vector<int> v = {7, 5, 1};
return v;
}
};
void build_tree(State &state, int depth = 0) {
if (depth == 2) {
return;
}
std::vector<int> actions = state.legal_actions();
for (auto action : actions) {
std::cout << "action: " << action << " depth: " << depth << std::endl;
State new_state = state.step(action);
build_tree(state, ++depth);
}
}
int main() {
State state;
build_tree(state);
return 0;
}
One of the problem with this code, that the traversal wont stop at depth 1.
action: 7 depth: 0
action: 7 depth: 1
action: 5 depth: 2
action: 7 depth: 3
action: 7 depth: 4
action: 7 depth: 5
action: 7 depth: 6
action: 7 depth: 7
action: 7 depth: 8
action: 7 depth: 9
... and so on
I would expect a game tree like this
And an output like this:
action: 7 depth: 0
action: 7 depth: 1
action: 5 depth: 1
action: 1 depth: 1
action: 5 depth: 0
action: 7 depth: 1
action: 5 depth: 1
action: 1 depth: 1
action: 1 depth: 0
action: 7 depth: 1
action: 5 depth: 1
action: 1 depth: 1
If you remove all the unnecessary stuff and only look at the bare-bones structure, you get this:
void build_tree(int depth = 0) {
if (depth == 2) {
return;
}
for (int i = 0; i < 3; i++) {
build_tree(++depth);
}
}
int main() {
build_tree(0);
}
Now, since you increment depth
, build_tree(0)
will call in turn build_tree(1)
, build_tree(2)
, and build_tree(3)
.
The build_tree(1)
will call in turn build_tree(2)
, build_tree(3)
, and build_tree(4)
.
And now you should be able to see that the reason that it never ends is that you only stop when depth
is exactly 2; if it's 3 or more you just keep going.
The main problem is that you wrote ++depth
where you should have written depth+1
, building all three children at the same depth.
(Side effects are tricky, mmkay?)
The other problem is that your condition for terminating the recursion is too specific, although changing the condition would only make sure it terminates but wouldn't give the correct result.