From e310b9cd0d3c0871566e78d675d07266d1040a14 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 14 May 2021 23:59:23 -0400 Subject: [PATCH] Solitaire: Add setting for number of cards to be drawn Klondike Solitaire has a couple more modes, but this adds modes for 1- and 3-card draws. --- Userland/Games/Solitaire/Game.cpp | 29 ++++++++++++++++++++++++++--- Userland/Games/Solitaire/Game.h | 11 ++++++++++- Userland/Games/Solitaire/main.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index 1b041ef16a..72d9b126bc 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -93,9 +93,10 @@ void Game::stop_game_over_animation() stop_timer(); } -void Game::setup() +void Game::setup(Mode mode) { stop_game_over_animation(); + m_mode = mode; if (on_game_end) on_game_end(); @@ -178,8 +179,30 @@ void Game::mousedown_event(GUI::MouseEvent& event) update_score(-100); update(stock.bounding_box()); } else { + auto play_bounding_box = play.bounding_box(); play.move_to_stack(waste); - move_card(stock, play); + + size_t cards_to_draw = 0; + switch (m_mode) { + case Mode::SingleCardDraw: + cards_to_draw = 1; + break; + case Mode::ThreeCardDraw: + cards_to_draw = 3; + break; + } + + update(stock.bounding_box()); + + for (size_t i = 0; (i < cards_to_draw) && !stock.is_empty(); ++i) { + auto card = stock.pop(); + play.push(move(card)); + } + + if (play.bounding_box().size().width() > play_bounding_box.size().width()) + update(play.bounding_box()); + else + update(play_bounding_box); } } else if (!to_check.is_empty()) { auto& top_card = to_check.peek(); @@ -290,7 +313,7 @@ void Game::doubleclick_event(GUI::MouseEvent& event) if (m_game_over_animation) { start_game_over_animation(); - setup(); + setup(mode()); return; } diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index 9fa44b1a6e..144ae9f15e 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -12,6 +12,11 @@ namespace Solitaire { +enum class Mode { + SingleCardDraw, + ThreeCardDraw, +}; + class Game final : public GUI::Frame { C_OBJECT(Game) public: @@ -19,7 +24,9 @@ public: static constexpr int height = 480; virtual ~Game() override; - void setup(); + + Mode mode() const { return m_mode; } + void setup(Mode); Function on_score_update; Function on_game_start; @@ -121,6 +128,8 @@ private: virtual void keydown_event(GUI::KeyEvent&) override; virtual void timer_event(Core::TimerEvent&) override; + Mode m_mode { Mode::SingleCardDraw }; + NonnullRefPtrVector m_focused_cards; NonnullRefPtrVector m_new_deck; CardStack m_stacks[StackLocation::__Count]; diff --git a/Userland/Games/Solitaire/main.cpp b/Userland/Games/Solitaire/main.cpp index 5a34ac1a64..df1621f73a 100644 --- a/Userland/Games/Solitaire/main.cpp +++ b/Userland/Games/Solitaire/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -86,13 +87,32 @@ int main(int argc, char** argv) timer->stop(); }; + GUI::ActionGroup draw_settng_actions; + draw_settng_actions.set_exclusive(true); + + auto single_card_draw_action = GUI::Action::create_checkable("&Single Card Draw", [&](auto&) { + game.setup(Solitaire::Mode::SingleCardDraw); + }); + single_card_draw_action->set_checked(true); + single_card_draw_action->set_status_tip("Draw one card at a time"); + draw_settng_actions.add_action(single_card_draw_action); + + auto three_card_draw_action = GUI::Action::create_checkable("&Three Card Draw", [&](auto&) { + game.setup(Solitaire::Mode::ThreeCardDraw); + }); + three_card_draw_action->set_status_tip("Draw three cards at a time"); + draw_settng_actions.add_action(three_card_draw_action); + auto menubar = GUI::Menubar::construct(); auto& game_menu = menubar->add_menu("&Game"); game_menu.add_action(GUI::Action::create("&New Game", { Mod_None, Key_F2 }, [&](auto&) { - game.setup(); + game.setup(game.mode()); })); game_menu.add_separator(); + game_menu.add_action(single_card_draw_action); + game_menu.add_action(three_card_draw_action); + game_menu.add_separator(); game_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { app->quit(); })); auto& help_menu = menubar->add_menu("&Help"); @@ -103,7 +123,7 @@ int main(int argc, char** argv) window->set_menubar(move(menubar)); window->set_icon(app_icon.bitmap_for_size(16)); window->show(); - game.setup(); + game.setup(game.mode()); return app->exec(); }