in csrc/SimpleBot.cc [189:269]
bool SimpleBot::maybeGiveHelpfulHint(Server &server)
{
if (server.hintStonesRemaining() == 0) return false;
const int numPlayers = handKnowledge_.size();
int best_so_far = 0;
int player_to_hint = -1;
int color_to_hint = -1;
int value_to_hint = -1;
for (int i = 1; i < numPlayers; ++i) {
const int partner = (me_ + i) % numPlayers;
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);
}
/* Can we construct a color hint that gives our partner information
* about unknown-playable cards, without also including any
* unplayable cards? */
for (Color color = RED; color <= BLUE; ++color) {
int information_content = 0;
bool misinformative = false;
for (int c=0; c < partners_hand.size(); ++c) {
if (partners_hand[c].color != color) continue;
if (is_really_playable[c] &&
!handKnowledge_[partner][c].isPlayable)
{
information_content += 1;
} else if (!is_really_playable[c]) {
misinformative = true;
break;
}
}
if (misinformative) continue;
if (information_content > best_so_far) {
best_so_far = information_content;
color_to_hint = color;
value_to_hint = -1;
player_to_hint = partner;
}
}
for (int value = 1; value <= 5; ++value) {
int information_content = 0;
bool misinformative = false;
for (int c=0; c < partners_hand.size(); ++c) {
if (partners_hand[c].value != value) continue;
if (is_really_playable[c] &&
!handKnowledge_[partner][c].isPlayable)
{
information_content += 1;
} else if (!is_really_playable[c]) {
misinformative = true;
break;
}
}
if (misinformative) continue;
if (information_content > best_so_far) {
best_so_far = information_content;
color_to_hint = -1;
value_to_hint = value;
player_to_hint = partner;
}
}
}
if (best_so_far == 0) return false;
/* Give the hint. */
if (color_to_hint != -1) {
server.pleaseGiveColorHint(player_to_hint, Color(color_to_hint));
} else if (value_to_hint != -1) {
server.pleaseGiveValueHint(player_to_hint, Value(value_to_hint));
} else {
assert(false);
}
return true;
}