diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index cb6a8433ee..af98a3779e 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -21,20 +21,20 @@ static constexpr int s_timer_interval_ms = 1000 / 60; Game::Game() { - m_stacks.append(adopt_ref(*new CardStack({ 10, 10 }, CardStack::Type::Stock))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Play, m_stacks.ptr_at(Waste)))); - m_stacks.append(adopt_ref(*new CardStack({ Game::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation))); - m_stacks.append(adopt_ref(*new CardStack({ Game::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation))); - m_stacks.append(adopt_ref(*new CardStack({ Game::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation))); - m_stacks.append(adopt_ref(*new CardStack({ Game::width - Card::width - 10, 10 }, CardStack::Type::Foundation))); - m_stacks.append(adopt_ref(*new CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal))); - m_stacks.append(adopt_ref(*new CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10, 10 }, CardStack::Type::Stock))); + add_stack(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste))); + add_stack(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Play, stack_at_location(Waste)))); + add_stack(adopt_ref(*new CardStack({ Game::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation))); + add_stack(adopt_ref(*new CardStack({ Game::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation))); + add_stack(adopt_ref(*new CardStack({ Game::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation))); + add_stack(adopt_ref(*new CardStack({ Game::width - Card::width - 10, 10 }, CardStack::Type::Foundation))); + add_stack(adopt_ref(*new CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal))); } static float rand_float() @@ -60,7 +60,7 @@ void Game::timer_event(Core::TimerEvent&) ++m_new_game_animation_delay; } else { m_new_game_animation_delay = 0; - auto& current_pile = stack(piles.at(m_new_game_animation_pile)); + auto& current_pile = stack_at_location(piles.at(m_new_game_animation_pile)); if (current_pile.count() < m_new_game_animation_pile) { auto card = m_new_deck.take_last(); @@ -74,7 +74,7 @@ void Game::timer_event(Core::TimerEvent&) update(current_pile.bounding_box()); if (m_new_game_animation_pile == piles.size()) { - auto& stock_pile = stack(Stock); + auto& stock_pile = stack_at_location(Stock); while (!m_new_deck.is_empty()) stock_pile.push(m_new_deck.take_last()); @@ -151,7 +151,7 @@ void Game::setup(Mode mode) if (on_game_end) on_game_end(GameOverReason::NewGame, m_score); - for (auto& stack : m_stacks) + for (auto& stack : stacks()) stack.clear(); m_new_deck.clear(); @@ -218,7 +218,9 @@ void Game::keydown_event(GUI::KeyEvent& event) } else if (event.key() == KeyCode::Key_Space && m_mouse_down != true) { draw_cards(); } else if (event.shift() && event.key() == KeyCode::Key_F11) { - dump_layout(); + if constexpr (SOLITAIRE_DEBUG) { + dump_layout(); + } } } @@ -230,7 +232,7 @@ void Game::mousedown_event(GUI::MouseEvent& event) return; auto click_location = event.position(); - for (auto& to_check : m_stacks) { + for (auto& to_check : stacks()) { if (to_check.type() == CardStack::Type::Waste) continue; @@ -273,7 +275,7 @@ void Game::mouseup_event(GUI::MouseEvent& event) return; bool rebound = true; - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { if (stack.is_focused()) continue; @@ -348,7 +350,7 @@ void Game::doubleclick_event(GUI::MouseEvent& event) return; auto click_location = event.position(); - for (auto& to_check : m_stacks) { + for (auto& to_check : stacks()) { if (to_check.type() != CardStack::Type::Normal && to_check.type() != CardStack::Type::Play) continue; @@ -365,7 +367,7 @@ void Game::doubleclick_event(GUI::MouseEvent& event) void Game::check_for_game_over() { for (auto foundationID : foundations) { - auto& foundation = stack(foundationID); + auto& foundation = stack_at_location(foundationID); if (foundation.count() != Card::card_count) return; @@ -376,9 +378,9 @@ void Game::check_for_game_over() void Game::draw_cards() { - auto& waste = stack(Waste); - auto& stock = stack(Stock); - auto& play = stack(Play); + auto& waste = stack_at_location(Waste); + auto& stock = stack_at_location(Stock); + auto& play = stack_at_location(Play); if (stock.is_empty()) { if (waste.is_empty() && play.is_empty()) @@ -447,8 +449,8 @@ void Game::draw_cards() void Game::pop_waste_to_play_stack() { - auto& waste = this->stack(Waste); - auto& play = this->stack(Play); + auto& waste = stack_at_location(Waste); + auto& play = stack_at_location(Play); if (play.is_empty() && !waste.is_empty()) { auto card = waste.pop(); m_focused_cards.append(card); @@ -468,7 +470,7 @@ bool Game::attempt_to_move_card_to_foundations(CardStack& from) bool card_was_moved = false; for (auto foundationID : foundations) { - auto& foundation = stack(foundationID); + auto& foundation = stack_at_location(foundationID); if (foundation.is_allowed_to_push(top_card)) { update(from.bounding_box()); @@ -506,7 +508,7 @@ void Game::auto_move_eligible_cards_to_foundations() { bool card_was_moved = false; - for (auto& to_check : m_stacks) { + for (auto& to_check : stacks()) { if (to_check.type() != CardStack::Type::Normal && to_check.type() != CardStack::Type::Play) continue; @@ -521,7 +523,7 @@ void Game::auto_move_eligible_cards_to_foundations() void Game::mark_intersecting_stacks_dirty(Card& intersecting_card) { - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { if (intersecting_card.rect().intersects(stack.bounding_box())) update(stack.bounding_box()); } @@ -549,7 +551,7 @@ void Game::paint_event(GUI::PaintEvent& event) focused_card.clear(painter, background_color); } - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { stack.draw(painter, background_color); } @@ -610,7 +612,7 @@ void Game::perform_undo() } if (m_last_move.from->type() == CardStack::Type::Play && m_mode == Mode::SingleCardDraw) { - auto& waste = stack(Waste); + auto& waste = stack_at_location(Waste); if (!m_last_move.from->is_empty()) waste.push(m_last_move.from->pop()); } @@ -622,8 +624,8 @@ void Game::perform_undo() } if (m_last_move.from->type() == CardStack::Type::Stock) { - auto& waste = this->stack(Waste); - auto& play = this->stack(Play); + auto& waste = stack_at_location(Waste); + auto& play = stack_at_location(Play); NonnullRefPtrVector cards_popped; for (size_t i = 0; i < m_last_move.cards.size(); i++) { if (!waste.is_empty()) { @@ -648,13 +650,4 @@ void Game::perform_undo() invalidate_layout(); } -void Game::dump_layout() const -{ - if constexpr (SOLITAIRE_DEBUG) { - dbgln("------------------------------"); - for (auto const& stack : m_stacks) - dbgln("{}", stack); - } -} - } diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index e619e5d317..8d17887702 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -175,12 +175,6 @@ private: void create_new_animation_card(); void set_background_fill_enabled(bool); void check_for_game_over(); - void dump_layout() const; - - ALWAYS_INLINE CardStack& stack(StackLocation location) - { - return m_stacks[location]; - } virtual void paint_event(GUI::PaintEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; @@ -195,7 +189,6 @@ private: LastMove m_last_move; NonnullRefPtrVector m_focused_cards; NonnullRefPtrVector m_new_deck; - NonnullRefPtrVector m_stacks; CardStack* m_focused_stack { nullptr }; Gfx::IntPoint m_mouse_down_location; diff --git a/Userland/Games/Spider/Game.cpp b/Userland/Games/Spider/Game.cpp index 71f15e95c0..af08e0da92 100644 --- a/Userland/Games/Spider/Game.cpp +++ b/Userland/Games/Spider/Game.cpp @@ -22,11 +22,11 @@ static constexpr int s_timer_interval_ms = 1000 / 60; Game::Game() { - m_stacks.append(adopt_ref(*new CardStack({ 10, Game::height - Card::height - 10 }, CardStack::Type::Waste))); - m_stacks.append(adopt_ref(*new CardStack({ Game::width - Card::width - 10, Game::height - Card::height - 10 }, CardStack::Type::Stock))); + add_stack(adopt_ref(*new CardStack({ 10, Game::height - Card::height - 10 }, CardStack::Type::Waste))); + add_stack(adopt_ref(*new CardStack({ Game::width - Card::width - 10, Game::height - Card::height - 10 }, CardStack::Type::Stock))); for (int i = 0; i < 10; i++) { - m_stacks.append(adopt_ref(*new CardStack({ 10 + i * (Card::width + 10), 10 }, CardStack::Type::Normal))); + add_stack(adopt_ref(*new CardStack({ 10 + i * (Card::width + 10), 10 }, CardStack::Type::Normal))); } } @@ -40,7 +40,7 @@ void Game::setup(Mode mode) if (on_game_end) on_game_end(GameOverReason::NewGame, m_score); - for (auto& stack : m_stacks) + for (auto& stack : stacks()) stack.clear(); m_new_game_animation_pile = 0; @@ -94,7 +94,7 @@ void Game::update_score(int delta) void Game::draw_cards() { // draw a single card from the stock for each pile - auto& stock_pile = stack(Stock); + auto& stock_pile = stack_at_location(Stock); if (stock_pile.is_empty()) return; @@ -107,7 +107,7 @@ void Game::draw_cards() void Game::mark_intersecting_stacks_dirty(Card& intersecting_card) { - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { if (intersecting_card.rect().intersects(stack.bounding_box())) update(stack.bounding_box()); } @@ -129,9 +129,9 @@ void Game::ensure_top_card_is_visible(NonnullRefPtr stack) void Game::detect_full_stacks() { - auto& completed_stack = stack(Completed); + auto& completed_stack = stack_at_location(Completed); for (auto pile : piles) { - auto& current_pile = stack(pile); + auto& current_pile = stack_at_location(pile); bool started = false; uint8_t last_value; @@ -175,7 +175,7 @@ void Game::detect_full_stacks() void Game::detect_victory() { for (auto pile : piles) { - auto& current_pile = stack(pile); + auto& current_pile = stack_at_location(pile); if (!current_pile.is_empty()) return; @@ -200,7 +200,7 @@ void Game::paint_event(GUI::PaintEvent& event) focused_card.clear(painter, background_color); } - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { stack.draw(painter, background_color); } @@ -233,7 +233,7 @@ void Game::mousedown_event(GUI::MouseEvent& event) return; auto click_location = event.position(); - for (auto& to_check : m_stacks) { + for (auto& to_check : stacks()) { if (to_check.type() == CardStack::Type::Waste) continue; @@ -297,7 +297,7 @@ void Game::mouseup_event(GUI::MouseEvent& event) if (event.button() == GUI::MouseButton::Secondary) { // This enables the game to move the focused cards to the first possible stack excluding empty stacks. // NOTE: This ignores empty stacks, as the game has no undo button, and a card, which has been moved to an empty stack without any other possibilities is not reversible. - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { if (stack.is_focused()) continue; @@ -309,7 +309,7 @@ void Game::mouseup_event(GUI::MouseEvent& event) } } } else { - for (auto& stack : m_stacks) { + for (auto& stack : stacks()) { if (stack.is_focused()) continue; @@ -364,7 +364,7 @@ void Game::timer_event(Core::TimerEvent&) ++m_new_game_animation_delay; } else { m_new_game_animation_delay = 0; - auto& current_pile = stack(piles.at(m_new_game_animation_pile)); + auto& current_pile = stack_at_location(piles.at(m_new_game_animation_pile)); // for first 4 piles, draw 6 cards // for last 6 piles, draw 5 cards @@ -384,7 +384,7 @@ void Game::timer_event(Core::TimerEvent&) if (m_new_game_animation_pile == piles.size()) { VERIFY(m_new_deck.size() == 50); - auto& stock_pile = stack(Stock); + auto& stock_pile = stack_at_location(Stock); while (!m_new_deck.is_empty()) stock_pile.push(m_new_deck.take_last()); @@ -399,8 +399,8 @@ void Game::timer_event(Core::TimerEvent&) if (m_draw_animation_delay < draw_animation_delay) { ++m_draw_animation_delay; } else { - auto& stock_pile = stack(Stock); - auto& current_pile = stack(piles.at(m_draw_animation_pile)); + auto& stock_pile = stack_at_location(Stock); + auto& current_pile = stack_at_location(piles.at(m_draw_animation_pile)); auto card = stock_pile.pop(); card->set_upside_down(false); current_pile.push(card); diff --git a/Userland/Games/Spider/Game.h b/Userland/Games/Spider/Game.h index 263d464088..9addb2ff90 100644 --- a/Userland/Games/Spider/Game.h +++ b/Userland/Games/Spider/Game.h @@ -76,11 +76,6 @@ private: void detect_victory(); void move_focused_cards(CardStack& stack); - ALWAYS_INLINE CardStack& stack(StackLocation location) - { - return m_stacks[location]; - } - void paint_event(GUI::PaintEvent&) override; void mousedown_event(GUI::MouseEvent&) override; void mouseup_event(GUI::MouseEvent&) override; @@ -91,7 +86,6 @@ private: NonnullRefPtrVector m_focused_cards; NonnullRefPtrVector m_new_deck; - NonnullRefPtrVector m_stacks; CardStack* m_focused_stack { nullptr }; Gfx::IntPoint m_mouse_down_location; diff --git a/Userland/Libraries/LibCards/CardGame.cpp b/Userland/Libraries/LibCards/CardGame.cpp index bb3fb5abd9..216dffbf2a 100644 --- a/Userland/Libraries/LibCards/CardGame.cpp +++ b/Userland/Libraries/LibCards/CardGame.cpp @@ -17,6 +17,18 @@ CardGame::CardGame() set_background_color(background_color.value_or(Color::from_rgb(0x008000))); } +void CardGame::add_stack(NonnullRefPtr stack) +{ + m_stacks.append(move(stack)); +} + +void CardGame::dump_layout() const +{ + dbgln("------------------------------"); + for (auto const& stack : stacks()) + dbgln("{}", stack); +} + void CardGame::config_string_did_change(String const& domain, String const& group, String const& key, String const& value) { if (domain == "Games" && group == "Cards") { diff --git a/Userland/Libraries/LibCards/CardGame.h b/Userland/Libraries/LibCards/CardGame.h index 6c9f697a5d..8d9ca0e4fd 100644 --- a/Userland/Libraries/LibCards/CardGame.h +++ b/Userland/Libraries/LibCards/CardGame.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -20,11 +21,20 @@ public: Gfx::Color background_color() const; void set_background_color(Gfx::Color const&); + NonnullRefPtrVector& stacks() { return m_stacks; } + NonnullRefPtrVector const& stacks() const { return m_stacks; } + CardStack& stack_at_location(int location) { return m_stacks[location]; } + void add_stack(NonnullRefPtr); + + void dump_layout() const; + protected: CardGame(); private: virtual void config_string_did_change(String const& domain, String const& group, String const& key, String const& value) override; + + NonnullRefPtrVector m_stacks; }; }