summaryrefslogtreecommitdiff
path: root/Userland/Games/Hearts
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-05-23 14:49:58 +0200
committerAndreas Kling <kling@serenityos.org>2021-05-23 18:15:36 +0200
commit2dfced2501d5635c3da3904409190e90364982d5 (patch)
treeae62032f7f7804288d586d01ff2157d00c6dac37 /Userland/Games/Hearts
parent647d0f9f8a2b64bb6d0d273b71d1b4474e48576d (diff)
downloadserenity-2dfced2501d5635c3da3904409190e90364982d5.zip
Hearts: Let the AI prefer lead cards for which other cards are in play
When picking a lead card the AI should avoid playing cards where it knows that no other player has a lower value card of the same type.
Diffstat (limited to 'Userland/Games/Hearts')
-rw-r--r--Userland/Games/Hearts/Game.cpp5
-rw-r--r--Userland/Games/Hearts/Player.cpp17
-rw-r--r--Userland/Games/Hearts/Player.h2
3 files changed, 19 insertions, 5 deletions
diff --git a/Userland/Games/Hearts/Game.cpp b/Userland/Games/Hearts/Game.cpp
index d17fa9097b..2b661630dd 100644
--- a/Userland/Games/Hearts/Game.cpp
+++ b/Userland/Games/Hearts/Game.cpp
@@ -210,7 +210,10 @@ size_t Game::pick_card(Player& player)
auto prefer_card = [this, &player](Card& card) {
return !other_player_has_lower_value_card(player, card) && other_player_has_higher_value_card(player, card);
};
- return player.pick_lead_card(move(valid_card), move(prefer_card));
+ auto lower_value_card_in_play = [this, &player](Card& card) {
+ return other_player_has_lower_value_card(player, card);
+ };
+ return player.pick_lead_card(move(valid_card), move(prefer_card), move(lower_value_card_in_play));
}
}
auto* high_card = &m_trick[0];
diff --git a/Userland/Games/Hearts/Player.cpp b/Userland/Games/Hearts/Player.cpp
index 4e3bd7839f..c36ee8e3cf 100644
--- a/Userland/Games/Hearts/Player.cpp
+++ b/Userland/Games/Hearts/Player.cpp
@@ -11,7 +11,8 @@
namespace Hearts {
-size_t Player::pick_lead_card(Function<bool(Card&)> valid_play, Function<bool(Card&)> prefer_card)
+size_t Player::pick_lead_card(Function<bool(Card&)> valid_play, Function<bool(Card&)> prefer_card,
+ Function<bool(Card&)> lower_value_card_in_play)
{
struct CardWithIndex {
RefPtr<Card> card;
@@ -38,17 +39,27 @@ size_t Player::pick_lead_card(Function<bool(Card&)> valid_play, Function<bool(Ca
dbgln("----");
}
- size_t last_index = -1;
+ ssize_t fallback_index = -1;
+ ssize_t last_index = -1;
for (auto& cwi : sorted_hand) {
if (!valid_play(*cwi.card))
continue;
+ if (lower_value_card_in_play(*cwi.card)) {
+ // Allow falling back to this card if no other suitable card is in play.
+ fallback_index = cwi.index;
+ continue;
+ }
if (prefer_card(*cwi.card)) {
dbgln_if(HEARTS_DEBUG, "Preferring card {}", *cwi.card);
return cwi.index;
}
last_index = cwi.index;
}
- return last_index;
+ if (last_index == -1) {
+ dbgln_if(HEARTS_DEBUG, "Falling back to card {}", *hand[fallback_index]);
+ return fallback_index;
+ } else
+ return last_index;
}
Optional<size_t> Player::pick_low_points_high_value_card(Optional<Card::Type> type)
diff --git a/Userland/Games/Hearts/Player.h b/Userland/Games/Hearts/Player.h
index d7737951fe..6f143f34a9 100644
--- a/Userland/Games/Hearts/Player.h
+++ b/Userland/Games/Hearts/Player.h
@@ -21,7 +21,7 @@ public:
{
}
- size_t pick_lead_card(Function<bool(Card&)>, Function<bool(Card&)>);
+ size_t pick_lead_card(Function<bool(Card&)>, Function<bool(Card&)>, Function<bool(Card&)>);
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);