diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index e63750b6c4..e794e98806 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -110,6 +110,7 @@ void Game::setup(Mode mode) m_new_deck.clear(); m_new_game_animation_pile = 0; + m_passes_left_before_punishment = recycle_rules().passes_allowed_before_punishment; m_score = 0; update_score(0); @@ -182,7 +183,11 @@ void Game::mousedown_event(GUI::MouseEvent& event) stock.push(card); } - update_score(-100); + if (m_passes_left_before_punishment == 0) + update_score(recycle_rules().punishment); + else + --m_passes_left_before_punishment; + update(stock.bounding_box()); } else { auto play_bounding_box = play.bounding_box(); diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index 72d1ed78df..b9164610ba 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -97,6 +98,11 @@ private: bool m_dirty { false }; }; + struct WasteRecycleRules { + uint8_t passes_allowed_before_punishment { 0 }; + int8_t punishment { 0 }; + }; + enum StackLocation { Stock, Waste, @@ -116,6 +122,23 @@ private: }; static constexpr Array piles = { Pile1, Pile2, Pile3, Pile4, Pile5, Pile6, Pile7 }; + ALWAYS_INLINE const WasteRecycleRules& recycle_rules() + { + static constexpr Array rules { { + { 0, -100 }, + { 2, -20 }, + } }; + + switch (m_mode) { + case Mode::SingleCardDraw: + return rules[0]; + case Mode::ThreeCardDraw: + return rules[1]; + default: + VERIFY_NOT_REACHED(); + } + } + void mark_intersecting_stacks_dirty(Card& intersecting_card); void update_score(int to_add); void move_card(CardStack& from, CardStack& to); @@ -156,6 +179,7 @@ private: uint8_t m_new_game_animation_delay { 0 }; uint32_t m_score { 0 }; + uint8_t m_passes_left_before_punishment { 0 }; }; }