in csrc/SmartBot.cc [875:928]
Hint SmartBot::bestHintForPlayerGivenConstraint(int to, F&& is_okay) const
{
std::vector<Card> partners_hand = server_->handOfPlayer(to);
bool colors[BLUE+1] = {};
bool values[5+1] = {};
for (const Card &card : partners_hand) {
colors[card.color] = true;
values[card.value] = true;
}
const auto& oldKnols = handKnowledge_[to];
Hint best;
best.to = to;
for (Color k = RED; k <= BLUE; ++k) {
if (!colors[k]) continue;
Hint hint;
hint.to = to;
hint.color = k;
auto newKnols = oldKnols;
for (int c = 0; c < partners_hand.size(); ++c) {
if (partners_hand[c].color == k) {
newKnols[c].setMustBe(Color(k));
} else {
newKnols[c].setCannotBe(Color(k));
}
}
if (is_okay(hint, oldKnols, newKnols)) {
hint.fitness = reduction_in_entropy(oldKnols, newKnols);
if (hint.fitness > best.fitness) {
best = hint;
}
}
}
for (int v = 1; v <= 5; ++v) {
if (!values[v]) continue;
Hint hint;
hint.to = to;
hint.value = v;
auto newKnols = oldKnols;
for (int c = 0; c < partners_hand.size(); ++c) {
if (partners_hand[c].value == v) {
newKnols[c].setMustBe(Value(v));
} else {
newKnols[c].setCannotBe(Value(v));
}
}
if (is_okay(hint, oldKnols, newKnols)) {
hint.fitness = reduction_in_entropy(oldKnols, newKnols);
if (hint.fitness > best.fitness) {
best = hint;
}
}
}
return best;
}