diff options
-rw-r--r-- | Games/Solitaire/Card.cpp | 2 | ||||
-rw-r--r-- | Games/Solitaire/Card.h | 2 | ||||
-rw-r--r-- | Games/Solitaire/CardStack.cpp | 40 | ||||
-rw-r--r-- | Games/Solitaire/CardStack.h | 28 | ||||
-rw-r--r-- | Games/Solitaire/SolitaireWidget.cpp | 37 | ||||
-rw-r--r-- | Games/Solitaire/SolitaireWidget.h | 7 |
6 files changed, 64 insertions, 52 deletions
diff --git a/Games/Solitaire/Card.cpp b/Games/Solitaire/Card.cpp index 72ae50e42b..c98de8a90b 100644 --- a/Games/Solitaire/Card.cpp +++ b/Games/Solitaire/Card.cpp @@ -166,7 +166,7 @@ void Card::save_old_position() m_old_position_valid = true; } -void Card::draw_complete(GUI::Painter& painter, const Color& background_color) +void Card::clear_and_draw(GUI::Painter& painter, const Color& background_color) { if (is_old_position_valid()) clear(painter, background_color); diff --git a/Games/Solitaire/Card.h b/Games/Solitaire/Card.h index 2f3f31084d..8a5652d481 100644 --- a/Games/Solitaire/Card.h +++ b/Games/Solitaire/Card.h @@ -69,7 +69,7 @@ public: void draw(GUI::Painter&) const; void clear(GUI::Painter&, const Color& background_color) const; - void draw_complete(GUI::Painter&, const Color& background_color); + void clear_and_draw(GUI::Painter&, const Color& background_color); private: Card(Type type, uint8_t value); diff --git a/Games/Solitaire/CardStack.cpp b/Games/Solitaire/CardStack.cpp index dfac4b9347..bb2b1bade5 100644 --- a/Games/Solitaire/CardStack.cpp +++ b/Games/Solitaire/CardStack.cpp @@ -29,22 +29,17 @@ CardStack::CardStack() : m_position({ 0, 0 }) , m_type(Invalid) - , m_shift_x(0) - , m_shift_y(0) - , m_step(1) , m_base(m_position, { Card::width, Card::height }) { } -CardStack::CardStack(const Gfx::IntPoint& position, Type type, uint8_t shift_x, uint8_t shift_y, uint8_t step) +CardStack::CardStack(const Gfx::IntPoint& position, Type type) : m_position(position) , m_type(type) - , m_shift_x(shift_x) - , m_shift_y(shift_y) - , m_step(step) + , m_rules(rules_for_type(type)) , m_base(m_position, { Card::width, Card::height }) { - ASSERT(step && type != Invalid); + ASSERT(type != Invalid); calculate_bounding_box(); } @@ -88,7 +83,7 @@ void CardStack::draw(GUI::Painter& painter, const Gfx::Color& background_color) if (is_empty()) return; - if (m_shift_x == 0 && m_shift_y == 0) { + if (m_rules.shift_x == 0 && m_rules.shift_y == 0) { auto& card = peek(); card.draw(painter); return; @@ -96,11 +91,12 @@ void CardStack::draw(GUI::Painter& painter, const Gfx::Color& background_color) for (auto& card : m_stack) { if (!card.is_moving()) - card.draw_complete(painter, background_color); + card.clear_and_draw(painter, background_color); } m_dirty = false; } + void CardStack::rebound_cards() { ASSERT(m_stack_positions.size() == m_stack.size()); @@ -183,15 +179,14 @@ bool CardStack::is_allowed_to_push(const Card& card) const void CardStack::push(NonnullRefPtr<Card> card) { - int size = m_stack.size(); - int ud_shift = (m_type == Normal) ? 3 : 1; + auto size = m_stack.size(); auto top_most_position = m_stack_positions.is_empty() ? m_position : m_stack_positions.last(); - if (size && size % m_step == 0) { + if (size && size % m_rules.step == 0) { if (peek().is_upside_down()) - top_most_position.move_by(m_shift_x, ((m_shift_y == 0) ? 0 : ud_shift)); + top_most_position.move_by(m_rules.shift_x, m_rules.shift_y_upside_down); else - top_most_position.move_by(m_shift_x, m_shift_y); + top_most_position.move_by(m_rules.shift_x, m_rules.shift_y); } if (m_type == Stock) @@ -225,16 +220,15 @@ void CardStack::calculate_bounding_box() uint16_t width = 0; uint16_t height = 0; - int card_position = 0; + size_t card_position = 0; for (auto& card : m_stack) { - if (card_position % m_step == 0 && card_position) { - if (card.is_upside_down() && m_type != Stock) { - int ud_shift = (m_type == Normal) ? 3 : 1; - width += m_shift_x; - height += (m_shift_y == 0) ? 0 : ud_shift; + if (card_position % m_rules.step == 0 && card_position) { + if (card.is_upside_down()) { + width += m_rules.shift_x; + height += m_rules.shift_y_upside_down; } else { - width += m_shift_x; - height += m_shift_y; + width += m_rules.shift_x; + height += m_rules.shift_y; } } ++card_position; diff --git a/Games/Solitaire/CardStack.h b/Games/Solitaire/CardStack.h index e4cb2be77b..18bac7a027 100644 --- a/Games/Solitaire/CardStack.h +++ b/Games/Solitaire/CardStack.h @@ -40,7 +40,7 @@ public: }; CardStack(); - CardStack(const Gfx::IntPoint& position, Type type, uint8_t shift_x, uint8_t shift_y, uint8_t step = 1); + CardStack(const Gfx::IntPoint& position, Type type); bool is_dirty() const { return m_dirty; } bool is_empty() const { return m_stack.is_empty(); } @@ -64,6 +64,28 @@ public: void clear(); private: + struct StackRules { + uint8_t shift_x { 0 }; + uint8_t shift_y { 0 }; + uint8_t step { 1 }; + uint8_t shift_y_upside_down { 0 }; + }; + + constexpr StackRules rules_for_type(Type stack_type) + { + switch (stack_type) { + case Foundation: + return { 2, 1, 4, 1 }; + case Normal: + return { 0, 15, 1, 3 }; + case Stock: + case Waste: + return { 2, 1, 8, 1 }; + default: + return {}; + } + } + void calculate_bounding_box(); NonnullRefPtrVector<Card> m_stack; @@ -71,9 +93,7 @@ private: Gfx::IntPoint m_position; Gfx::IntRect m_bounding_box; Type m_type { Invalid }; - uint8_t m_shift_x { 0 }; - uint8_t m_shift_y { 0 }; - uint8_t m_step {}; + StackRules m_rules; bool m_focused { false }; bool m_dirty { false }; Gfx::IntRect m_base; diff --git a/Games/Solitaire/SolitaireWidget.cpp b/Games/Solitaire/SolitaireWidget.cpp index 3ec581d617..6c944248ce 100644 --- a/Games/Solitaire/SolitaireWidget.cpp +++ b/Games/Solitaire/SolitaireWidget.cpp @@ -37,19 +37,19 @@ SolitaireWidget::SolitaireWidget(GUI::Window& window, Function<void(uint32_t)>&& { set_fill_with_background_color(false); - m_stacks[Stock] = CardStack({ 10, 10 }, CardStack::Type::Stock, 2, 1, 8); - m_stacks[Waste] = CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste, 2, 1, 8); - m_stacks[Foundation4] = CardStack({ SolitaireWidget::width - Card::width - 10, 10 }, CardStack::Type::Foundation, 2, 1, 4); - m_stacks[Foundation3] = CardStack({ SolitaireWidget::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation, 2, 1, 4); - m_stacks[Foundation2] = CardStack({ SolitaireWidget::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation, 2, 1, 4); - m_stacks[Foundation1] = CardStack({ SolitaireWidget::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation, 2, 1, 4); - m_stacks[Pile1] = CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile2] = CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile3] = CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile4] = CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile5] = CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile6] = CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); - m_stacks[Pile7] = CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal, 0, 15); + m_stacks[Stock] = CardStack({ 10, 10 }, CardStack::Type::Stock); + m_stacks[Waste] = CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste); + m_stacks[Foundation4] = CardStack({ SolitaireWidget::width - Card::width - 10, 10 }, CardStack::Type::Foundation); + m_stacks[Foundation3] = CardStack({ SolitaireWidget::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation); + m_stacks[Foundation2] = CardStack({ SolitaireWidget::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation); + m_stacks[Foundation1] = CardStack({ SolitaireWidget::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation); + m_stacks[Pile1] = CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile2] = CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile3] = CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile4] = CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile5] = CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile6] = CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal); + m_stacks[Pile7] = CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal); m_timer = Core::Timer::construct(1000 / 60, [&]() { tick(window); }); m_timer->stop(); @@ -66,7 +66,7 @@ static float rand_float() static void make_pile(NonnullRefPtrVector<Card>& cards, CardStack& stack, uint8_t count) { - for (int i = 1; i < count; ++i) { + for (uint8_t i = 1; i < count; ++i) { auto card = cards.take_last(); card->set_upside_down(true); stack.push(card); @@ -81,10 +81,9 @@ void SolitaireWidget::tick(GUI::Window& window) return; if (m_game_over_animation) { - if (m_animation.card()->position().x() > SolitaireWidget::width - || m_animation.card()->rect().right() < 0) { + ASSERT(!m_animation.card().is_null()); + if (m_animation.card()->position().x() > SolitaireWidget::width || m_animation.card()->rect().right() < 0) create_new_animation_card(); - } m_animation.tick(); } @@ -141,7 +140,7 @@ void SolitaireWidget::setup() } srand(time(nullptr)); - for (int i = 0; i < 200; ++i) + for (uint8_t i = 0; i < 200; ++i) cards.append(cards.take(rand() % cards.size())); make_pile(cards, stack(Pile1), 1); @@ -415,7 +414,7 @@ void SolitaireWidget::paint_event(GUI::PaintEvent& event) focused_card.save_old_position(); } } - } else if (m_animation.card() != nullptr) + } else if (!m_animation.card().is_null()) m_animation.card()->draw(painter); m_repaint_all = true; diff --git a/Games/Solitaire/SolitaireWidget.h b/Games/Solitaire/SolitaireWidget.h index ac9bbd109c..a1b18ee819 100644 --- a/Games/Solitaire/SolitaireWidget.h +++ b/Games/Solitaire/SolitaireWidget.h @@ -56,15 +56,14 @@ private: { } - Card* card() { return m_animation_card; } + RefPtr<Card> card() { return m_animation_card; } void tick() { ASSERT(!m_animation_card.is_null()); m_y_velocity += m_gravity; - if (m_animation_card->position().y() + Card::height + m_y_velocity > SolitaireWidget::height + 1 - && m_y_velocity > 0) { + if (m_animation_card->position().y() + Card::height + m_y_velocity > SolitaireWidget::height + 1 && m_y_velocity > 0) { m_y_velocity = min((m_y_velocity * -m_bouncyness), -8.f); m_animation_card->rect().set_y(SolitaireWidget::height - Card::height); m_animation_card->rect().move_by(m_x_velocity, 0); @@ -107,7 +106,7 @@ private: void check_for_game_over(); void tick(GUI::Window&); - inline CardStack& stack(StackLocation location) + ALWAYS_INLINE CardStack& stack(StackLocation location) { return m_stacks[location]; } |