in csrc/SmartBot.cc [726:786]
void SmartBot::pleaseObserveValueHint(const Hanabi::Server &server, int from, int to, Value value, CardIndices card_indices)
{
server_ = &server;
assert(server.whoAmI() == me_);
/* Someone has given Bob a value hint. If the named cards
* include the one Bob would normally be discarding next,
* then this must be a warning that that card is valuable.
* Otherwise, all the named cards are playable. */
const int playerExpectingWarning = (from + 1) % handKnowledge_.size();
const int discardIndex = this->nextDiscardIndex(playerExpectingWarning);
const bool isHintStoneReclaim =
(!server.discardingIsAllowed()) &&
(from == (to+1) % server.numPlayers()) &&
card_indices.contains(0);
const bool isWarning =
!isHintStoneReclaim &&
(to == playerExpectingWarning) &&
card_indices.contains(discardIndex) &&
handKnowledge_[to][discardIndex].couldBeValuableWithValue(value);
if (isWarning) {
assert(discardIndex != -1);
handKnowledge_[to][discardIndex].setIsValuable(true);
}
const int numCards = server.sizeOfHandOfPlayer(to);
bool identifiedPlayableCard = false;
int inferredPlayableIndex = -1;
for (int i=numCards-1; i >= 0; --i) {
CardKnowledge &knol = handKnowledge_[to][i];
const bool wasMaybePlayable = (knol.playable() == MAYBE);
if (card_indices.contains(i)) {
knol.setMustBe(value);
if (wasMaybePlayable) {
if (knol.playable() == YES) {
identifiedPlayableCard = true;
} else if (knol.playable() == MAYBE) {
if (inferredPlayableIndex == -1) inferredPlayableIndex = i;
}
}
} else {
knol.setCannotBe(value);
if (wasMaybePlayable) {
if (knol.playable() == YES) {
identifiedPlayableCard = true;
}
}
}
}
if (!isWarning && !isHintStoneReclaim && !identifiedPlayableCard && inferredPlayableIndex >= 0) {
handKnowledge_[to][inferredPlayableIndex].setIsPlayable(true);
}
if (to != playerExpectingWarning) {
assert(!isWarning);
this->noValuableWarningWasGiven(from);
}
}