summaryrefslogtreecommitdiff
path: root/Userland/Games
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-06-01 00:40:37 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-01 08:52:08 +0200
commit8b9da08d5aaf1d38956ee6ad6efc00abe364685b (patch)
treea54c7fb0053b2596440cfafb4264d5db95fae5b5 /Userland/Games
parent4a8d8da46c6e7d1dd6077eae75e8f2e056687f97 (diff)
downloadserenity-8b9da08d5aaf1d38956ee6ad6efc00abe364685b.zip
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.
Diffstat (limited to 'Userland/Games')
-rw-r--r--Userland/Games/Hearts/Game.cpp14
-rw-r--r--Userland/Games/Hearts/Player.cpp10
-rw-r--r--Userland/Games/Hearts/Player.h2
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<size_t> 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<bool(Card&)> 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<size_t> pick_low_points_high_value_card(Optional<Card::Type> type = {});
Optional<size_t> pick_lower_value_card(Card& other_card);
Optional<size_t> pick_slightly_higher_value_card(Card& other_card);
- size_t pick_max_points_card();
+ size_t pick_max_points_card(Function<bool(Card&)>);
Optional<size_t> pick_specific_card(Card::Type type, CardValue value);
size_t pick_last_card();
bool has_card_of_type(Card::Type type);