Przeglądaj źródła

LibCards+Games: Change name of card type to card suit

Playing cards have a `suit` such as `hearts`/`diamonds`, not a
`type`. Make the internal naming consistent with the way playing cards
are typically named.
Lenny Maiorani 3 lat temu
rodzic
commit
a51fce6c0f

+ 28 - 28
Userland/Games/Hearts/Game.cpp

@@ -203,10 +203,10 @@ void Game::setup(String player_name, int hand_number)
     deck.ensure_capacity(Card::card_count * 4);
 
     for (int i = 0; i < Card::card_count; ++i) {
-        deck.append(Card::construct(Card::Type::Clubs, i));
-        deck.append(Card::construct(Card::Type::Spades, i));
-        deck.append(Card::construct(Card::Type::Hearts, i));
-        deck.append(Card::construct(Card::Type::Diamonds, i));
+        deck.append(Card::construct(Card::Suit::Clubs, i));
+        deck.append(Card::construct(Card::Suit::Spades, i));
+        deck.append(Card::construct(Card::Suit::Hearts, i));
+        deck.append(Card::construct(Card::Suit::Diamonds, i));
     }
 
     for (auto& player : m_players) {
@@ -288,7 +288,7 @@ bool Game::other_player_has_lower_value_card(Player& player, Card& card)
     for (auto& other_player : m_players) {
         if (&player != &other_player) {
             for (auto& other_card : other_player.hand) {
-                if (other_card && card.type() == other_card->type() && hearts_card_value(*other_card) < hearts_card_value(card))
+                if (other_card && card.suit() == other_card->suit() && hearts_card_value(*other_card) < hearts_card_value(card))
                     return true;
             }
         }
@@ -301,7 +301,7 @@ bool Game::other_player_has_higher_value_card(Player& player, Card& card)
     for (auto& other_player : m_players) {
         if (&player != &other_player) {
             for (auto& other_card : other_player.hand) {
-                if (other_card && card.type() == other_card->type() && hearts_card_value(*other_card) > hearts_card_value(card))
+                if (other_card && card.suit() == other_card->suit() && hearts_card_value(*other_card) > hearts_card_value(card))
                     return true;
             }
         }
@@ -314,7 +314,7 @@ 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)
+                if (other_card && other_card->suit() == Card::Suit::Spades && hearts_card_value(*other_card) == CardValue::Queen)
                     return true;
             }
         }
@@ -335,7 +335,7 @@ size_t Game::pick_card(Player& player)
     bool is_first_trick = m_trick_number == 0;
     if (is_leading_player) {
         if (is_first_trick) {
-            auto clubs_2 = player.pick_specific_card(Card::Type::Clubs, CardValue::Number_2);
+            auto clubs_2 = player.pick_specific_card(Card::Suit::Clubs, CardValue::Number_2);
             VERIFY(clubs_2.has_value());
             return clubs_2.value();
         } else {
@@ -350,15 +350,15 @@ size_t Game::pick_card(Player& player)
     }
     auto* high_card = &m_trick[0];
     for (auto& card : m_trick)
-        if (high_card->type() == card.type() && hearts_card_value(card) > hearts_card_value(*high_card))
+        if (high_card->suit() == card.suit() && hearts_card_value(card) > hearts_card_value(*high_card))
             high_card = &card;
-    if (high_card->type() == Card::Type::Spades && hearts_card_value(*high_card) > CardValue::Queen)
-        RETURN_CARD_IF_VALID(player.pick_specific_card(Card::Type::Spades, CardValue::Queen));
+    if (high_card->suit() == Card::Suit::Spades && hearts_card_value(*high_card) > CardValue::Queen)
+        RETURN_CARD_IF_VALID(player.pick_specific_card(Card::Suit::Spades, CardValue::Queen));
     auto card_has_points = [](Card& card) { return hearts_card_points(card) > 0; };
     auto trick_has_points = m_trick.first_matching(card_has_points).has_value();
     bool is_trailing_player = m_trick.size() == 3;
     if (!trick_has_points && is_trailing_player) {
-        RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(m_trick[0].type()));
+        RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(m_trick[0].suit()));
         if (is_first_trick)
             return player.pick_low_points_high_value_card().value();
         else {
@@ -376,8 +376,8 @@ size_t Game::pick_card(Player& player)
     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 (high_card->suit() == Card::Suit::Spades && other_player_has_queen_of_spades(player)) {
+            Optional<size_t> chosen_card_index = player.pick_low_points_high_value_card(high_card->suit());
             if (chosen_card_index.has_value()) {
                 auto& card = player.hand[chosen_card_index.value()];
                 if (hearts_card_value(*card) > CardValue::Queen)
@@ -386,7 +386,7 @@ size_t Game::pick_card(Player& player)
         }
     }
     if (play_highest_value_card)
-        RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(high_card->type()));
+        RETURN_CARD_IF_VALID(player.pick_low_points_high_value_card(high_card->suit()));
     else
         RETURN_CARD_IF_VALID(player.pick_slightly_higher_value_card(*high_card));
     if (is_first_trick)
@@ -518,7 +518,7 @@ void Game::advance_game()
         // Find whoever has 2 of Clubs, they get to play the first card
         for (auto& player : m_players) {
             auto clubs_2_card = player.hand.first_matching([](auto& card) {
-                return card->type() == Card::Type::Clubs && hearts_card_value(*card) == CardValue::Number_2;
+                return card->suit() == Card::Suit::Clubs && hearts_card_value(*card) == CardValue::Number_2;
             });
             if (clubs_2_card.has_value()) {
                 m_leading_player = &player;
@@ -533,11 +533,11 @@ void Game::advance_game()
         return;
     }
 
-    auto leading_card_type = m_trick[0].type();
+    auto leading_card_suit = m_trick[0].suit();
     size_t taker_index = 0;
     auto taker_value = hearts_card_value(m_trick[0]);
     for (size_t i = 1; i < 4; i++) {
-        if (m_trick[i].type() != leading_card_type)
+        if (m_trick[i].suit() != leading_card_suit)
             continue;
         if (hearts_card_value(m_trick[i]) <= taker_value)
             continue;
@@ -632,7 +632,7 @@ bool Game::is_valid_play(Player& player, Card& card, String* explanation) const
     if (m_trick_number == 0 && m_trick.is_empty()) {
         if (explanation)
             *explanation = "The first card must be Two of Clubs.";
-        return card.type() == Card::Type::Clubs && hearts_card_value(card) == CardValue::Number_2;
+        return card.suit() == Card::Suit::Clubs && hearts_card_value(card) == CardValue::Number_2;
     }
 
     // Can't play hearts or The Queen in the first trick.
@@ -646,7 +646,7 @@ bool Game::is_valid_play(Player& player, Card& card, String* explanation) const
         }
         // ... unless the player only has points cards (e.g. all Hearts or
         // 12 Hearts + Queen of Spades), in which case they're allowed to play Hearts.
-        if (all_points_cards && card.type() == Card::Type::Hearts)
+        if (all_points_cards && card.suit() == Card::Suit::Hearts)
             return true;
         if (explanation)
             *explanation = "You can't play a card worth points in the first trick.";
@@ -656,10 +656,10 @@ bool Game::is_valid_play(Player& player, Card& card, String* explanation) const
     // Leading card can't be hearts until hearts are broken
     // unless the player only has hearts cards.
     if (m_trick.is_empty()) {
-        if (are_hearts_broken() || card.type() != Card::Type::Hearts)
+        if (are_hearts_broken() || card.suit() != Card::Suit::Hearts)
             return true;
         auto non_hearts_card = player.hand.first_matching([](auto const& other_card) {
-            return !other_card.is_null() && other_card->type() != Card::Type::Hearts;
+            return !other_card.is_null() && other_card->suit() != Card::Suit::Hearts;
         });
         auto only_has_hearts = !non_hearts_card.has_value();
         if (!only_has_hearts && explanation)
@@ -668,10 +668,10 @@ bool Game::is_valid_play(Player& player, Card& card, String* explanation) const
     }
 
     // Player must follow suit unless they don't have any matching cards.
-    auto leading_card_type = m_trick[0].type();
-    if (leading_card_type == card.type())
+    auto leading_card_suit = m_trick[0].suit();
+    if (leading_card_suit == card.suit())
         return true;
-    auto has_matching_card = player.has_card_of_type(leading_card_type);
+    auto has_matching_card = player.has_card_of_suit(leading_card_suit);
     if (has_matching_card && explanation)
         *explanation = "You must follow suit.";
     return !has_matching_card;
@@ -681,7 +681,7 @@ bool Game::are_hearts_broken() const
 {
     for (auto& player : m_players)
         for (auto& card : player.cards_taken)
-            if (card->type() == Card::Type::Hearts)
+            if (card->suit() == Card::Suit::Hearts)
                 return true;
     return false;
 }
@@ -750,9 +750,9 @@ int Game::calculate_score(Player& player)
     for (auto& other_player : m_players) {
         int score = 0;
         for (auto& card : other_player.cards_taken)
-            if (card->type() == Card::Type::Spades && card->value() == 11)
+            if (card->suit() == Card::Suit::Spades && card->value() == 11)
                 score += 13;
-            else if (card->type() == Card::Type::Hearts)
+            else if (card->suit() == Card::Suit::Hearts)
                 score++;
         if (!min_score.has_value() || score < min_score.value())
             min_score = score;

+ 4 - 4
Userland/Games/Hearts/Helpers.h

@@ -39,9 +39,9 @@ inline CardValue hearts_card_value(Card const& card)
 
 inline uint8_t hearts_card_points(Card const& card)
 {
-    if (card.type() == Card::Type::Hearts)
+    if (card.suit() == Card::Suit::Hearts)
         return 1;
-    else if (card.type() == Card::Type::Spades && hearts_card_value(card) == CardValue::Queen)
+    else if (card.suit() == Card::Suit::Spades && hearts_card_value(card) == CardValue::Queen)
         return 13;
     else
         return 0;
@@ -49,8 +49,8 @@ inline uint8_t hearts_card_points(Card const& card)
 
 inline bool hearts_card_less(RefPtr<Card>& card1, RefPtr<Card>& card2)
 {
-    if (card1->type() != card2->type())
-        return card1->type() < card2->type();
+    if (card1->suit() != card2->suit())
+        return card1->suit() < card2->suit();
     else
         return hearts_card_value(*card1) < hearts_card_value(*card2);
 }

+ 11 - 11
Userland/Games/Hearts/Player.cpp

@@ -71,13 +71,13 @@ size_t Player::pick_lead_card(Function<bool(Card&)> valid_play, Function<bool(Ca
     return last_index;
 }
 
-Optional<size_t> Player::pick_low_points_high_value_card(Optional<Card::Type> type)
+Optional<size_t> Player::pick_low_points_high_value_card(Optional<Card::Suit> suit)
 {
     auto sorted_hand = hand_sorted_by_fn(compare_card_value);
     int min_points = -1;
     Optional<size_t> card_index;
     for (auto& cwi : sorted_hand) {
-        if (type.has_value() && cwi.card->type() != type.value())
+        if (suit.has_value() && cwi.card->suit() != suit.value())
             continue;
         auto points = hearts_card_points(*cwi.card);
         if (min_points == -1 || points < min_points) {
@@ -85,7 +85,7 @@ Optional<size_t> Player::pick_low_points_high_value_card(Optional<Card::Type> ty
             card_index = cwi.index;
         }
     }
-    VERIFY(card_index.has_value() || type.has_value());
+    VERIFY(card_index.has_value() || suit.has_value());
     return card_index;
 }
 
@@ -95,7 +95,7 @@ Optional<size_t> Player::pick_lower_value_card(Card& other_card)
         auto& card = hand[i];
         if (card.is_null())
             continue;
-        if (card->type() == other_card.type() && hearts_card_value(*card) < hearts_card_value(other_card))
+        if (card->suit() == other_card.suit() && hearts_card_value(*card) < hearts_card_value(other_card))
             return i;
     }
     return {};
@@ -107,7 +107,7 @@ Optional<size_t> Player::pick_slightly_higher_value_card(Card& other_card)
         auto& card = hand[i];
         if (card.is_null())
             continue;
-        if (card->type() == other_card.type() && hearts_card_value(*card) > hearts_card_value(other_card))
+        if (card->suit() == other_card.suit() && hearts_card_value(*card) > hearts_card_value(other_card))
             return i;
     }
     return {};
@@ -115,10 +115,10 @@ Optional<size_t> Player::pick_slightly_higher_value_card(Card& other_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);
+    auto queen_of_spades_maybe = pick_specific_card(Card::Suit::Spades, CardValue::Queen);
     if (queen_of_spades_maybe.has_value())
         return queen_of_spades_maybe.value();
-    if (has_card_of_type(Card::Type::Hearts)) {
+    if (has_card_of_suit(Card::Suit::Hearts)) {
         auto highest_hearts_card_index = pick_last_card();
         auto& card = hand[highest_hearts_card_index];
         if (!ignore_card(*card))
@@ -127,13 +127,13 @@ size_t Player::pick_max_points_card(Function<bool(Card&)> ignore_card)
     return pick_low_points_high_value_card().value();
 }
 
-Optional<size_t> Player::pick_specific_card(Card::Type type, CardValue value)
+Optional<size_t> Player::pick_specific_card(Card::Suit suit, CardValue value)
 {
     for (size_t i = 0; i < hand.size(); i++) {
         auto& card = hand[i];
         if (card.is_null())
             continue;
-        if (card->type() == type && hearts_card_value(*card) == value)
+        if (card->suit() == suit && hearts_card_value(*card) == value)
             return i;
     }
     return {};
@@ -150,10 +150,10 @@ size_t Player::pick_last_card()
     VERIFY_NOT_REACHED();
 }
 
-bool Player::has_card_of_type(Card::Type type)
+bool Player::has_card_of_suit(Card::Suit suit)
 {
     auto matching_card = hand.first_matching([&](auto const& other_card) {
-        return !other_card.is_null() && other_card->type() == type;
+        return !other_card.is_null() && other_card->suit() == suit;
     });
     return matching_card.has_value();
 }

+ 3 - 3
Userland/Games/Hearts/Player.h

@@ -35,13 +35,13 @@ public:
 
     NonnullRefPtrVector<Card> pick_cards_to_pass(PassingDirection);
     size_t pick_lead_card(Function<bool(Card&)>, Function<bool(Card&)>);
-    Optional<size_t> pick_low_points_high_value_card(Optional<Card::Type> type = {});
+    Optional<size_t> pick_low_points_high_value_card(Optional<Card::Suit> suit = {});
     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(Function<bool(Card&)>);
-    Optional<size_t> pick_specific_card(Card::Type type, CardValue value);
+    Optional<size_t> pick_specific_card(Card::Suit suit, CardValue value);
     size_t pick_last_card();
-    bool has_card_of_type(Card::Type type);
+    bool has_card_of_suit(Card::Suit suit);
     Vector<CardWithIndex> hand_sorted_by_fn(bool (*)(CardWithIndex&, CardWithIndex&)) const;
 
     void sort_hand() { quick_sort(hand, hearts_card_less); }

+ 5 - 5
Userland/Games/Solitaire/Game.cpp

@@ -90,7 +90,7 @@ void Game::timer_event(Core::TimerEvent&)
 
 void Game::create_new_animation_card()
 {
-    auto card = Card::construct(static_cast<Card::Type>(get_random_uniform(to_underlying(Card::Type::__Count))), get_random_uniform(Card::card_count));
+    auto card = Card::construct(static_cast<Card::Suit>(get_random_uniform(to_underlying(Card::Suit::__Count))), get_random_uniform(Card::card_count));
     card->set_position({ get_random_uniform(Game::width - Card::width), get_random_uniform(Game::height / 8) });
 
     int x_sgn = card->position().x() > (Game::width / 2) ? -1 : 1;
@@ -163,10 +163,10 @@ void Game::setup(Mode mode)
         on_undo_availability_change(false);
 
     for (int i = 0; i < Card::card_count; ++i) {
-        m_new_deck.append(Card::construct(Card::Type::Clubs, i));
-        m_new_deck.append(Card::construct(Card::Type::Spades, i));
-        m_new_deck.append(Card::construct(Card::Type::Hearts, i));
-        m_new_deck.append(Card::construct(Card::Type::Diamonds, i));
+        m_new_deck.append(Card::construct(Card::Suit::Clubs, i));
+        m_new_deck.append(Card::construct(Card::Suit::Spades, i));
+        m_new_deck.append(Card::construct(Card::Suit::Hearts, i));
+        m_new_deck.append(Card::construct(Card::Suit::Diamonds, i));
     }
 
     for (uint8_t i = 0; i < 200; ++i)

+ 3 - 3
Userland/Games/Spider/Game.cpp

@@ -55,13 +55,13 @@ void Game::setup(Mode mode)
         switch (m_mode) {
         case Mode::SingleSuit:
             for (int j = 0; j < 8; j++) {
-                deck.append(Card::construct(Card::Type::Spades, i));
+                deck.append(Card::construct(Card::Suit::Spades, i));
             }
             break;
         case Mode::TwoSuit:
             for (int j = 0; j < 4; j++) {
-                deck.append(Card::construct(Card::Type::Spades, i));
-                deck.append(Card::construct(Card::Type::Hearts, i));
+                deck.append(Card::construct(Card::Suit::Spades, i));
+                deck.append(Card::construct(Card::Suit::Hearts, i));
             }
             break;
         default:

+ 7 - 7
Userland/Libraries/LibCards/Card.cpp

@@ -67,10 +67,10 @@ static constexpr Gfx::CharacterBitmap s_club {
 static RefPtr<Gfx::Bitmap> s_background;
 static RefPtr<Gfx::Bitmap> s_background_inverted;
 
-Card::Card(Type type, uint8_t value)
+Card::Card(Suit suit, uint8_t value)
     : m_rect(Gfx::IntRect({}, { width, height }))
     , m_front(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, { width, height }).release_value_but_fixme_should_propagate_errors())
-    , m_type(type)
+    , m_suit(suit)
     , m_value(value)
 {
     VERIFY(value < card_count);
@@ -111,15 +111,15 @@ Card::Card(Type type, uint8_t value)
     painter.draw_text(text_rect, label, font, Gfx::TextAlignment::Center, color());
 
     auto const& symbol = [&]() -> Gfx::CharacterBitmap const& {
-        switch (m_type) {
-        case Type::Diamonds:
+        switch (m_suit) {
+        case Suit::Diamonds:
             return s_diamond;
-        case Type::Clubs:
+        case Suit::Clubs:
             return s_club;
             break;
-        case Type::Spades:
+        case Suit::Spades:
             return s_spade;
-        case Type::Hearts:
+        case Suit::Hearts:
             return s_heart;
         default:
             VERIFY_NOT_REACHED();

+ 16 - 16
Userland/Libraries/LibCards/Card.h

@@ -29,7 +29,7 @@ public:
         "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
     };
 
-    enum class Type {
+    enum class Suit {
         Clubs,
         Diamonds,
         Spades,
@@ -43,13 +43,13 @@ public:
     Gfx::IntPoint position() const { return m_rect.location(); }
     const Gfx::IntPoint& old_position() const { return m_old_position; }
     uint8_t value() const { return m_value; };
-    Type type() const { return m_type; }
+    Suit suit() const { return m_suit; }
 
     bool is_old_position_valid() const { return m_old_position_valid; }
     bool is_moving() const { return m_moving; }
     bool is_upside_down() const { return m_upside_down; }
     bool is_inverted() const { return m_inverted; }
-    Gfx::Color color() const { return (m_type == Type::Diamonds || m_type == Type::Hearts) ? Color::Red : Color::Black; }
+    Gfx::Color color() const { return (m_suit == Suit::Diamonds || m_suit == Suit::Hearts) ? Color::Red : Color::Black; }
 
     void set_position(const Gfx::IntPoint p) { m_rect.set_location(p); }
     void set_moving(bool moving) { m_moving = moving; }
@@ -63,7 +63,7 @@ public:
     void clear_and_draw(GUI::Painter&, const Color& background_color);
 
 private:
-    Card(Type type, uint8_t value);
+    Card(Suit suit, uint8_t value);
 
     static NonnullRefPtr<Gfx::Bitmap> invert_bitmap(Gfx::Bitmap&);
 
@@ -71,7 +71,7 @@ private:
     NonnullRefPtr<Gfx::Bitmap> m_front;
     RefPtr<Gfx::Bitmap> m_front_inverted;
     Gfx::IntPoint m_old_position;
-    Type m_type;
+    Suit m_suit;
     uint8_t m_value;
     bool m_old_position_valid { false };
     bool m_moving { false };
@@ -85,25 +85,25 @@ template<>
 struct AK::Formatter<Cards::Card> : Formatter<FormatString> {
     ErrorOr<void> format(FormatBuilder& builder, Cards::Card const& card)
     {
-        StringView type;
+        StringView suit;
 
-        switch (card.type()) {
-        case Cards::Card::Type::Clubs:
-            type = "C"sv;
+        switch (card.suit()) {
+        case Cards::Card::Suit::Clubs:
+            suit = "C"sv;
             break;
-        case Cards::Card::Type::Diamonds:
-            type = "D"sv;
+        case Cards::Card::Suit::Diamonds:
+            suit = "D"sv;
             break;
-        case Cards::Card::Type::Hearts:
-            type = "H"sv;
+        case Cards::Card::Suit::Hearts:
+            suit = "H"sv;
             break;
-        case Cards::Card::Type::Spades:
-            type = "S"sv;
+        case Cards::Card::Suit::Spades:
+            suit = "S"sv;
             break;
         default:
             VERIFY_NOT_REACHED();
         }
 
-        return Formatter<FormatString>::format(builder, "{:>2}{}", Cards::Card::labels[card.value()], type);
+        return Formatter<FormatString>::format(builder, "{:>2}{}", Cards::Card::labels[card.value()], suit);
     }
 };

+ 1 - 1
Userland/Libraries/LibCards/CardStack.cpp

@@ -212,7 +212,7 @@ bool CardStack::is_allowed_to_push(const Card& card, size_t stack_size, Movement
             // Prevent player from dragging an entire stack of cards to the foundation stack
             if (stack_size > 1)
                 return false;
-            return top_card.type() == card.type() && m_stack.size() == card.value();
+            return top_card.suit() == card.suit() && m_stack.size() == card.value();
         } else if (m_type == Type::Normal) {
             bool color_match;
             switch (movement_rule) {