diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-06-01 00:00:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-01 08:52:08 +0200 |
commit | 2b2d992946f52357b9023ed78870f176019ce808 (patch) | |
tree | d21786c56673f97c84fd7e1647121edf089ad503 | |
parent | 38f8a6aabbfe2378bae1da53ba77344be77f8f56 (diff) | |
download | serenity-2b2d992946f52357b9023ed78870f176019ce808.zip |
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.
-rw-r--r-- | Userland/Games/Hearts/Game.cpp | 35 | ||||
-rw-r--r-- | Userland/Games/Hearts/Game.h | 1 |
2 files changed, 33 insertions, 3 deletions
diff --git a/Userland/Games/Hearts/Game.cpp b/Userland/Games/Hearts/Game.cpp index 7be8d6af17..8952ec2e3b 100644 --- a/Userland/Games/Hearts/Game.cpp +++ b/Userland/Games/Hearts/Game.cpp @@ -304,6 +304,19 @@ bool Game::other_player_has_higher_value_card(Player& player, Card& card) 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) \ do { \ auto card_index = (card); \ @@ -347,10 +360,26 @@ size_t Game::pick_card(Player& player) return player.pick_max_points_card(); } RETURN_CARD_IF_VALID(player.pick_lower_value_card(*high_card)); - if (!is_trailing_player) - RETURN_CARD_IF_VALID(player.pick_slightly_higher_value_card(*high_card)); - else + bool is_third_player = m_trick.size() == 2; + bool play_highest_value_card = false; + 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())); + else + RETURN_CARD_IF_VALID(player.pick_slightly_higher_value_card(*high_card)); if (is_first_trick) return player.pick_low_points_high_value_card().value(); else diff --git a/Userland/Games/Hearts/Game.h b/Userland/Games/Hearts/Game.h index c54fbf21bc..e9e71e1313 100644 --- a/Userland/Games/Hearts/Game.h +++ b/Userland/Games/Hearts/Game.h @@ -50,6 +50,7 @@ private: int calculate_score(Player& player); 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_queen_of_spades(Player& player); void reposition_hand(Player&); bool is_card_highlighted(Card& card); |