in csrc/liars_dice/recursive_solving.cc [76:134]
void compute_strategy_recursive_to_leaf(
const Game& game, const Tree& tree, int node_id,
const Pair<std::vector<double>>& beliefs,
const SubgameSolverBuilder& solver_builder, bool use_samplig_strategy,
TreeStrategy* strategy) {
auto& node = tree[node_id];
auto& state = node.state;
if (game.is_terminal(state)) return;
auto solver = solver_builder(game, node_id, state, beliefs);
solver->multistep();
// Tree traversal queue storing tuples:
// (full_node_id, partial_node_id, unnormalized beliefs at the node).
// We do BFS traversal. For each node:
// - copy the policy from the partial (solver) tree to strategy.
// - add children to the queue with propoer believes.
// - for non-termial leaves of the solver tree, do a recursive call.
std::deque<std::tuple<int, int, Pair<std::vector<double>>>> traversal_queue;
traversal_queue.emplace_back(node_id, 0, beliefs);
const TreeStrategy& partial_strategy = use_samplig_strategy
? solver->get_sampling_strategy()
: solver->get_strategy();
const TreeStrategy& partial_belief_strategy =
use_samplig_strategy ? solver->get_belief_propogation_strategy()
: solver->get_strategy();
const Tree& partial_tree = solver->get_tree();
while (!traversal_queue.empty()) {
auto [full_node_id, partial_node_id, node_reaches] =
std::move(traversal_queue.front());
traversal_queue.pop_front();
(*strategy)[full_node_id] = partial_strategy[partial_node_id];
const auto& full_node = tree[full_node_id];
const auto& partial_node = partial_tree[partial_node_id];
assert(partial_node.num_children() == 0 ||
partial_node.num_children() == full_node.num_children());
assert(partial_node.state == full_node.state);
for (int i = 0; i < partial_node.num_children(); ++i) {
auto child_reaches = node_reaches;
const int pid = full_node.state.player_id;
const int action = game.get_bid_range(full_node.state).first + i;
for (int hand = 0; hand < game.num_hands(); ++hand) {
child_reaches[pid][hand] *=
partial_belief_strategy[partial_node_id][hand][action];
}
traversal_queue.emplace_back(full_node.children_begin + i,
partial_node.children_begin + i,
child_reaches);
}
if (partial_node.num_children() == 0 && full_node.num_children() != 0) {
normalize_beliefs_inplace(node_reaches[0]);
normalize_beliefs_inplace(node_reaches[1]);
compute_strategy_recursive_to_leaf(game, tree, full_node_id, node_reaches,
solver_builder, use_samplig_strategy,
strategy);
}
}
}