From 2b2d992946f52357b9023ed78870f176019ce808 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 1 Jun 2021 00:00:57 +0200 Subject: 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. --- Userland/Games/Hearts/Game.cpp | 35 ++++++++++++++++++++++++++++++++--- 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 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); -- cgit v1.2.3