in csrc/SmartBot.cc [930:984]
Hint SmartBot::bestHintForPlayer(int partner) const
{
assert(partner != me_);
const std::vector<Card> partners_hand = server_->handOfPlayer(partner);
bool is_really_playable[5];
for (int c=0; c < partners_hand.size(); ++c) {
is_really_playable[c] =
server_->pileOf(partners_hand[c].color).nextValueIs(partners_hand[c].value);
}
/* Avoid giving hints that could be misinterpreted as warnings. */
int valueToAvoid = -1;
if (partner == (me_ + 1) % handKnowledge_.size()) {
const int discardIndex = nextDiscardIndex(partner);
if (discardIndex != -1) {
const CardKnowledge &knol = handKnowledge_[partner][discardIndex];
valueToAvoid = partners_hand[discardIndex].value;
if (!knol.couldBeValuableWithValue(valueToAvoid)) valueToAvoid = -1;
}
}
return bestHintForPlayerGivenConstraint(partner, [&](Hint hint, const std::vector<CardKnowledge>& oldKnols, const std::vector<CardKnowledge>& newKnols) {
if (hint.value != -1 && hint.value == valueToAvoid) {
// This hint would be misinterpreted as a valuable warning.
return false;
}
// If this hint identified a new playable card, then it is a good hint.
// If this hint did not unambiguously identify a new playable card,
// but the newest card it touched *is* playable in reality, then it is
// a good hint.
// If this hint did not unambiguously identify a new playable card
// and the newest card it touched is *not* playable in reality, then
// it is misleading and MUST not be given.
bool reveals_a_playable_card = false;
trivalue is_misleading = MAYBE;
for (int c = partners_hand.size()-1; c >= 0; --c) {
if (oldKnols[c].playable() != MAYBE) continue;
if (newKnols[c].playable() == YES) {
reveals_a_playable_card = true;
} else if (newKnols[c].playable() == MAYBE && hint.includes(partners_hand[c])) {
if (is_misleading == MAYBE) {
is_misleading = (is_really_playable[c] ? NO : YES);
}
}
}
if (reveals_a_playable_card || (is_misleading == NO)) {
// This is a good hint that will reveal a playable card.
return true;
} else {
// This is a misleading or worthless hint.
return false;
}
});
}