in csrc/JointSearchBot.cc [369:422]
void JointSearchBot::filterBeliefsConsistentWithAction_(const Move &move, int from, const Server &server) {
assert(server.numPlayers() == 2);
int who = 1 - from;
simulserver_.sync(server);
updateFrames_(from, server);
if (history_[from].size() > 0) {
// my partner played blueprint. At most one player is playing
// blueprint at a time, therefore I must know my beliefs, and I can always
// update them.
assert(history_[who].size() == 0);
auto &hand_dist = hand_dists_[who];
auto hand_dist_keys = copyKeys(hand_dist);
applyDelayedObservations(hand_dist, hand_dist_keys);
std::vector<boost::fibers::future<void>> futures;
for (int t = 0; t < NUM_THREADS; t++) {
futures.push_back(getThreadPool().enqueue([&, t]() {
for (int i = t; i < hand_dist_keys.size(); i += NUM_THREADS) {
const Hand &hand = hand_dist_keys[i];
auto bot = hand_dist.at(hand).getPartner(from);
SimulServer my_server(server);
my_server.setHand(who, hand);
assert(my_server.whoAmI() == server.whoAmI());
Move bp_move = my_server.simulatePlayerMove(from, bot.get());
my_server.setObservingPlayer(from); // so that we copy over who's hand in sync()
if (move != bp_move) {
hand_dist[hand].prob = 0;
}
}
}));
}
for (auto &f: futures) {
f.get();
}
for (auto &hand: hand_dist_keys) {
if (hand_dist[hand].prob == 0) {
hand_dist.erase(hand);
}
}
std::cerr << now() << "Filtered current beliefs consistent with player " << from << " BLUEPRINT action '" << move.toString()
<< "' reduced from " << hand_dist_keys.size() << " to " <<
hand_dist.size() << std::endl;
checkBeliefs_(server);
} else {
// in this case my partner played search. If my history is empty I can update
// my beliefs directly, but it's simpler to just push it onto the end of the
// history and do the full history update
std::cerr << now() << "Player " << from << " did search; pushing a frame for player " << who << " ; frames= " << history_[who].size() + 1 << std::endl;
history_[who].emplace_back(*this, who, move, server);
}
}