From 8b9da08d5aaf1d38956ee6ad6efc00abe364685b Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 1 Jun 2021 00:40:37 +0200 Subject: [PATCH] Hearts: Pick better non-matching cards When we don't have a matching card for the lead card rather than always preferring to play hearts we should try to get rid of our high value cards first if no other player has hearts cards higher than what we have. --- Userland/Games/Hearts/Game.cpp | 14 ++++++++++---- Userland/Games/Hearts/Player.cpp | 10 +++++++--- Userland/Games/Hearts/Player.h | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Userland/Games/Hearts/Game.cpp b/Userland/Games/Hearts/Game.cpp index fd19ade0bc..69b68e49f4 100644 --- a/Userland/Games/Hearts/Game.cpp +++ b/Userland/Games/Hearts/Game.cpp @@ -356,8 +356,12 @@ size_t Game::pick_card(Player& player) RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(m_trick[0].type())); if (is_first_trick) return player.pick_low_points_high_value_card().value(); - else - return player.pick_max_points_card(); + else { + auto ignore_card = [this, &player](Card& card) { + return !other_player_has_higher_value_card(player, card); + }; + return player.pick_max_points_card(move(ignore_card)); + } } RETURN_CARD_IF_VALID(player.pick_lower_value_card(*high_card)); bool is_third_player = m_trick.size() == 2; @@ -382,8 +386,10 @@ size_t Game::pick_card(Player& player) 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 - return player.pick_max_points_card(); + auto ignore_card = [this, &player](Card& card) { + return !other_player_has_higher_value_card(player, card); + }; + return player.pick_max_points_card(move(ignore_card)); } void Game::let_player_play_card() diff --git a/Userland/Games/Hearts/Player.cpp b/Userland/Games/Hearts/Player.cpp index a3d86f82cf..d8eecf7e4e 100644 --- a/Userland/Games/Hearts/Player.cpp +++ b/Userland/Games/Hearts/Player.cpp @@ -107,13 +107,17 @@ Optional Player::pick_slightly_higher_value_card(Card& other_card) return {}; } -size_t Player::pick_max_points_card() +size_t Player::pick_max_points_card(Function ignore_card) { auto queen_of_spades_maybe = pick_specific_card(Card::Type::Spades, CardValue::Queen); if (queen_of_spades_maybe.has_value()) return queen_of_spades_maybe.value(); - if (has_card_of_type(Card::Type::Hearts)) - return pick_last_card(); + if (has_card_of_type(Card::Type::Hearts)) { + auto highest_hearts_card_index = pick_last_card(); + auto& card = hand[highest_hearts_card_index]; + if (!ignore_card(*card)) + return highest_hearts_card_index; + } return pick_low_points_high_value_card().value(); } diff --git a/Userland/Games/Hearts/Player.h b/Userland/Games/Hearts/Player.h index 9f6181e477..8b4528f329 100644 --- a/Userland/Games/Hearts/Player.h +++ b/Userland/Games/Hearts/Player.h @@ -38,7 +38,7 @@ public: Optional pick_low_points_high_value_card(Optional type = {}); Optional pick_lower_value_card(Card& other_card); Optional pick_slightly_higher_value_card(Card& other_card); - size_t pick_max_points_card(); + size_t pick_max_points_card(Function); Optional pick_specific_card(Card::Type type, CardValue value); size_t pick_last_card(); bool has_card_of_type(Card::Type type);