Serenity Operating System
at master 88 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2020, Till Mayer <till.mayer@web.de> 3 * Copyright (c) 2022, the SerenityOS developers. 4 * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> 5 * 6 * SPDX-License-Identifier: BSD-2-Clause 7 */ 8 9#include "Card.h" 10#include <AK/Random.h> 11#include <LibCards/CardPainter.h> 12 13namespace Cards { 14 15Card::Card(Suit suit, Rank rank) 16 : m_rect(Gfx::IntRect({}, { width, height })) 17 , m_suit(suit) 18 , m_rank(rank) 19{ 20 VERIFY(to_underlying(rank) < card_count); 21} 22 23void Card::paint(GUI::Painter& painter, bool highlighted) const 24{ 25 auto& card_painter = CardPainter::the(); 26 auto bitmap = [&]() { 27 if (m_inverted) 28 return m_upside_down ? card_painter.card_back_inverted() : card_painter.card_front_inverted(m_suit, m_rank); 29 if (highlighted) { 30 VERIFY(!m_upside_down); 31 return card_painter.card_front_highlighted(m_suit, m_rank); 32 } 33 return m_upside_down ? card_painter.card_back() : card_painter.card_front(m_suit, m_rank); 34 }(); 35 painter.blit(position(), bitmap, bitmap->rect()); 36} 37 38void Card::clear(GUI::Painter& painter, Color background_color) const 39{ 40 painter.fill_rect({ old_position(), { width, height } }, background_color); 41} 42 43void Card::save_old_position() 44{ 45 m_old_position = m_rect.location(); 46 m_old_position_valid = true; 47} 48 49void Card::clear_and_paint(GUI::Painter& painter, Color background_color, bool highlighted) 50{ 51 if (is_old_position_valid()) 52 clear(painter, background_color); 53 54 paint(painter, highlighted); 55 save_old_position(); 56} 57 58ErrorOr<Vector<NonnullRefPtr<Card>>> create_standard_deck(Shuffle shuffle) 59{ 60 return create_deck(1, 1, 1, 1, shuffle); 61} 62 63ErrorOr<Vector<NonnullRefPtr<Card>>> create_deck(unsigned full_club_suit_count, unsigned full_diamond_suit_count, unsigned full_heart_suit_count, unsigned full_spade_suit_count, Shuffle shuffle) 64{ 65 Vector<NonnullRefPtr<Card>> deck; 66 TRY(deck.try_ensure_capacity(Card::card_count * (full_club_suit_count + full_diamond_suit_count + full_heart_suit_count + full_spade_suit_count))); 67 68 auto add_cards_for_suit = [&deck](Cards::Suit suit, unsigned number_of_suits) -> ErrorOr<void> { 69 for (auto i = 0u; i < number_of_suits; ++i) { 70 for (auto rank = 0; rank < Card::card_count; ++rank) { 71 deck.unchecked_append(TRY(Card::try_create(suit, static_cast<Cards::Rank>(rank)))); 72 } 73 } 74 return {}; 75 }; 76 77 TRY(add_cards_for_suit(Cards::Suit::Clubs, full_club_suit_count)); 78 TRY(add_cards_for_suit(Cards::Suit::Diamonds, full_diamond_suit_count)); 79 TRY(add_cards_for_suit(Cards::Suit::Hearts, full_heart_suit_count)); 80 TRY(add_cards_for_suit(Cards::Suit::Spades, full_spade_suit_count)); 81 82 if (shuffle == Shuffle::Yes) 83 AK::shuffle(deck); 84 85 return deck; 86} 87 88}