From 2159385bb65a612672a43773fe2cca9b9791df1d Mon Sep 17 00:00:00 2001 From: Neolyum Date: Thu, 6 Jan 2022 19:04:19 +0100 Subject: [PATCH] Spider: Add functionality to automatically move cards to valid stacks This commit adds the possibility to use the secondary mouse button to let the game move the selected card(s) to the next valid stack. --- Userland/Games/Spider/Game.cpp | 71 +++++++++++++++++++++++----------- Userland/Games/Spider/Game.h | 1 + 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/Userland/Games/Spider/Game.cpp b/Userland/Games/Spider/Game.cpp index 9d99b2ac34..fdb238ec01 100644 --- a/Userland/Games/Spider/Game.cpp +++ b/Userland/Games/Spider/Game.cpp @@ -1,11 +1,13 @@ /* * Copyright (c) 2021, Jamie Mansfield + * Copyright (c) 2022, Jonas Höpner * * SPDX-License-Identifier: BSD-2-Clause */ #include "Game.h" #include +#include #include #include @@ -267,7 +269,9 @@ void Game::mousedown_event(GUI::MouseEvent& event) m_focused_stack->set_focused(false); to_check.set_focused(true); m_focused_stack = &to_check; - m_mouse_down = true; + // When the user wants to automatically move cards, do not go into the drag mode. + if (event.button() != GUI::MouseButton::Secondary) + m_mouse_down = true; start_timer_if_necessary(); } } @@ -276,6 +280,24 @@ void Game::mousedown_event(GUI::MouseEvent& event) } } +void Game::move_focused_cards(CardStack& stack) +{ + for (auto& to_intersect : m_focused_cards) { + mark_intersecting_stacks_dirty(to_intersect); + stack.push(to_intersect); + (void)m_focused_stack->pop(); + } + + update_score(-1); + + update(m_focused_stack->bounding_box()); + update(stack.bounding_box()); + + detect_full_stacks(); + + ensure_top_card_is_visible(*m_focused_stack); +} + void Game::mouseup_event(GUI::MouseEvent& event) { GUI::Frame::mouseup_event(event); @@ -284,30 +306,33 @@ void Game::mouseup_event(GUI::MouseEvent& event) return; bool rebound = true; - for (auto& stack : m_stacks) { - if (stack.is_focused()) - continue; + 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 reversable. + for (auto& stack : m_stacks) { + if (stack.is_focused()) + continue; - for (auto& focused_card : m_focused_cards) { - if (stack.bounding_box().intersects(focused_card.rect())) { - if (stack.is_allowed_to_push(m_focused_cards.at(0), m_focused_cards.size(), Cards::CardStack::Any)) { - for (auto& to_intersect : m_focused_cards) { - mark_intersecting_stacks_dirty(to_intersect); - stack.push(to_intersect); - (void)m_focused_stack->pop(); + if (stack.is_allowed_to_push(m_focused_cards.at(0), m_focused_cards.size(), Cards::CardStack::Any) && !stack.is_empty()) { + move_focused_cards(stack); + + rebound = false; + break; + } + } + } else { + for (auto& stack : m_stacks) { + if (stack.is_focused()) + continue; + + for (auto& focused_card : m_focused_cards) { + if (stack.bounding_box().intersects(focused_card.rect())) { + if (stack.is_allowed_to_push(m_focused_cards.at(0), m_focused_cards.size(), Cards::CardStack::Any)) { + move_focused_cards(stack); + + rebound = false; + break; } - - update_score(-1); - - update(m_focused_stack->bounding_box()); - update(stack.bounding_box()); - - detect_full_stacks(); - - ensure_top_card_is_visible(*m_focused_stack); - - rebound = false; - break; } } } diff --git a/Userland/Games/Spider/Game.h b/Userland/Games/Spider/Game.h index 331cf831cf..f122c7f934 100644 --- a/Userland/Games/Spider/Game.h +++ b/Userland/Games/Spider/Game.h @@ -72,6 +72,7 @@ private: void ensure_top_card_is_visible(NonnullRefPtr stack); void detect_full_stacks(); void detect_victory(); + void move_focused_cards(CardStack& stack); ALWAYS_INLINE CardStack& stack(StackLocation location) {