1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 22:47:44 +00:00

Hearts: Pick better cards when we're the third player

When we're the third player in a trick and we don't have a lower value
card we would previously pick a slightly higher value card. Instead
we should pick the highest value card unless there are points in the
current trick or the lead card is spades and the higher value card
we would've picked is higher than the queen and another player still
has the queen.

The rationale is that we have to take the trick anyway so we might as
well get rid of our highest value card. If the trailing player has a
lower value card of the same type we take the trick but don't gain
any points. If they don't have a card of the same type it doesn't
matter whether we play a high value or low value card.
This commit is contained in:
Gunnar Beutner 2021-06-01 00:00:57 +02:00 committed by Andreas Kling
parent 38f8a6aabb
commit 2b2d992946
2 changed files with 33 additions and 3 deletions

View file

@ -304,6 +304,19 @@ bool Game::other_player_has_higher_value_card(Player& player, Card& card)
return false; return false;
} }
bool Game::other_player_has_queen_of_spades(Player& player)
{
for (auto& other_player : m_players) {
if (&player != &other_player) {
for (auto& other_card : other_player.hand) {
if (other_card && other_card->type() == Card::Type::Spades && hearts_card_value(*other_card) == CardValue::Queen)
return true;
}
}
}
return false;
}
#define RETURN_CARD_IF_VALID(card) \ #define RETURN_CARD_IF_VALID(card) \
do { \ do { \
auto card_index = (card); \ auto card_index = (card); \
@ -347,10 +360,26 @@ size_t Game::pick_card(Player& player)
return player.pick_max_points_card(); return player.pick_max_points_card();
} }
RETURN_CARD_IF_VALID(player.pick_lower_value_card(*high_card)); RETURN_CARD_IF_VALID(player.pick_lower_value_card(*high_card));
if (!is_trailing_player) bool is_third_player = m_trick.size() == 2;
RETURN_CARD_IF_VALID(player.pick_slightly_higher_value_card(*high_card)); bool play_highest_value_card = false;
else if (is_trailing_player)
play_highest_value_card = true;
if (is_third_player && !trick_has_points) {
play_highest_value_card = true;
if (high_card->type() == Card::Type::Spades && other_player_has_queen_of_spades(player)) {
Optional<size_t> chosen_card_index = player.pick_low_points_high_value_card(high_card->type());
if (chosen_card_index.has_value()) {
auto& card = player.hand[chosen_card_index.value()];
if (hearts_card_value(*card) > CardValue::Queen)
play_highest_value_card = false;
}
}
}
if (play_highest_value_card)
RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(high_card->type())); RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(high_card->type()));
else
RETURN_CARD_IF_VALID(player.pick_slightly_higher_value_card(*high_card));
if (is_first_trick) if (is_first_trick)
return player.pick_low_points_high_value_card().value(); return player.pick_low_points_high_value_card().value();
else else

View file

@ -50,6 +50,7 @@ private:
int calculate_score(Player& player); int calculate_score(Player& player);
bool other_player_has_lower_value_card(Player& player, Card& card); bool other_player_has_lower_value_card(Player& player, Card& card);
bool other_player_has_higher_value_card(Player& player, Card& card); bool other_player_has_higher_value_card(Player& player, Card& card);
bool other_player_has_queen_of_spades(Player& player);
void reposition_hand(Player&); void reposition_hand(Player&);
bool is_card_highlighted(Card& card); bool is_card_highlighted(Card& card);