Card.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. * Copyright (c) 2023, David Ganz <david.g.ganz@gmail.com>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include "Card.h"
  10. #include <AK/Random.h>
  11. #include <LibCards/CardPainter.h>
  12. namespace Cards {
  13. Card::Card(Suit suit, Rank rank)
  14. : m_rect(Gfx::IntRect({}, { width, height }))
  15. , m_suit(suit)
  16. , m_rank(rank)
  17. {
  18. VERIFY(to_underlying(rank) < card_count);
  19. }
  20. void Card::paint(GUI::Painter& painter, bool highlighted) const
  21. {
  22. VERIFY(!(highlighted && m_disabled));
  23. auto& card_painter = CardPainter::the();
  24. auto bitmap = [&]() {
  25. if (m_inverted)
  26. return m_upside_down ? card_painter.card_back_inverted() : card_painter.card_front_inverted(m_suit, m_rank);
  27. if (highlighted) {
  28. VERIFY(!m_upside_down);
  29. return card_painter.card_front_highlighted(m_suit, m_rank);
  30. }
  31. if (m_disabled) {
  32. return m_upside_down ? card_painter.card_back_disabled() : card_painter.card_front_disabled(m_suit, m_rank);
  33. }
  34. return m_upside_down ? card_painter.card_back() : card_painter.card_front(m_suit, m_rank);
  35. }();
  36. painter.blit(position(), bitmap, bitmap->rect());
  37. }
  38. void Card::clear(GUI::Painter& painter, Color background_color) const
  39. {
  40. painter.fill_rect({ old_position(), { width, height } }, background_color);
  41. }
  42. void Card::save_old_position()
  43. {
  44. m_old_position = m_rect.location();
  45. m_old_position_valid = true;
  46. }
  47. void Card::clear_and_paint(GUI::Painter& painter, Color background_color, bool highlighted)
  48. {
  49. if (is_old_position_valid())
  50. clear(painter, background_color);
  51. paint(painter, highlighted);
  52. save_old_position();
  53. }
  54. ErrorOr<Vector<NonnullRefPtr<Card>>> create_standard_deck(Shuffle shuffle)
  55. {
  56. return create_deck(1, 1, 1, 1, shuffle);
  57. }
  58. ErrorOr<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)
  59. {
  60. Vector<NonnullRefPtr<Card>> deck;
  61. TRY(deck.try_ensure_capacity(Card::card_count * (full_club_suit_count + full_diamond_suit_count + full_heart_suit_count + full_spade_suit_count)));
  62. auto add_cards_for_suit = [&deck](Cards::Suit suit, unsigned number_of_suits) -> ErrorOr<void> {
  63. for (auto i = 0u; i < number_of_suits; ++i) {
  64. for (auto rank = 0; rank < Card::card_count; ++rank) {
  65. deck.unchecked_append(TRY(Card::try_create(suit, static_cast<Cards::Rank>(rank))));
  66. }
  67. }
  68. return {};
  69. };
  70. TRY(add_cards_for_suit(Cards::Suit::Clubs, full_club_suit_count));
  71. TRY(add_cards_for_suit(Cards::Suit::Diamonds, full_diamond_suit_count));
  72. TRY(add_cards_for_suit(Cards::Suit::Hearts, full_heart_suit_count));
  73. TRY(add_cards_for_suit(Cards::Suit::Spades, full_spade_suit_count));
  74. if (shuffle == Shuffle::Yes)
  75. AK::shuffle(deck);
  76. return deck;
  77. }
  78. }