Hint SmartBot::bestHintForPlayerGivenConstraint()

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;
}