summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-06-01 00:00:57 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-01 08:52:08 +0200
commit2b2d992946f52357b9023ed78870f176019ce808 (patch)
treed21786c56673f97c84fd7e1647121edf089ad503
parent38f8a6aabbfe2378bae1da53ba77344be77f8f56 (diff)
downloadserenity-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.cpp35
-rw-r--r--Userland/Games/Hearts/Game.h1
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);