mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:27:45 +00:00
Spider: Make the last move undoable
The lets the user undo the last card move. Card moves which cause cards to be moved to the waste stack cannot be undone.
This commit is contained in:
parent
6d18164ab0
commit
c97421eabe
3 changed files with 73 additions and 0 deletions
|
@ -37,6 +37,9 @@ void Game::setup(Mode mode)
|
|||
|
||||
m_mode = mode;
|
||||
|
||||
if (on_undo_availability_change)
|
||||
on_undo_availability_change(false);
|
||||
|
||||
if (on_game_end)
|
||||
on_game_end(GameOverReason::NewGame, m_score);
|
||||
|
||||
|
@ -74,6 +77,28 @@ void Game::setup(Mode mode)
|
|||
update();
|
||||
}
|
||||
|
||||
void Game::perform_undo()
|
||||
{
|
||||
if (m_last_move.type == LastMove::Type::Invalid)
|
||||
return;
|
||||
|
||||
if (!m_last_move.was_visible)
|
||||
m_last_move.from->peek().set_upside_down(true);
|
||||
|
||||
NonnullRefPtrVector<Card> cards;
|
||||
for (size_t i = 0; i < m_last_move.card_count; i++)
|
||||
cards.append(m_last_move.to->pop());
|
||||
for (ssize_t i = m_last_move.card_count - 1; i >= 0; i--)
|
||||
m_last_move.from->push(cards[i]);
|
||||
|
||||
update_score(-1);
|
||||
|
||||
m_last_move = {};
|
||||
if (on_undo_availability_change)
|
||||
on_undo_availability_change(false);
|
||||
invalidate_layout();
|
||||
}
|
||||
|
||||
void Game::start_timer_if_necessary()
|
||||
{
|
||||
if (on_game_start && m_waiting_for_new_game) {
|
||||
|
@ -141,6 +166,9 @@ void Game::detect_full_stacks()
|
|||
update(current_pile.peek().rect());
|
||||
|
||||
update_score(101);
|
||||
|
||||
if (on_undo_availability_change)
|
||||
on_undo_availability_change(false);
|
||||
}
|
||||
|
||||
last_value = to_underlying(card.rank());
|
||||
|
@ -159,6 +187,9 @@ void Game::detect_victory()
|
|||
return;
|
||||
}
|
||||
|
||||
if (on_undo_availability_change)
|
||||
on_undo_availability_change(false);
|
||||
|
||||
if (on_game_end)
|
||||
on_game_end(GameOverReason::Victory, m_score);
|
||||
}
|
||||
|
@ -198,6 +229,17 @@ void Game::paint_event(GUI::PaintEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void Game::remember_move_for_undo(CardStack& from, CardStack& to, size_t card_count, bool was_visible)
|
||||
{
|
||||
m_last_move.type = LastMove::Type::MoveCards;
|
||||
m_last_move.from = &from;
|
||||
m_last_move.card_count = card_count;
|
||||
m_last_move.to = &to;
|
||||
m_last_move.was_visible = was_visible;
|
||||
if (on_undo_availability_change)
|
||||
on_undo_availability_change(true);
|
||||
}
|
||||
|
||||
void Game::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
GUI::Frame::mousedown_event(event);
|
||||
|
@ -239,7 +281,10 @@ void Game::mousedown_event(GUI::MouseEvent& event)
|
|||
|
||||
void Game::move_focused_cards(CardStack& stack)
|
||||
{
|
||||
auto card_count = moving_cards().size();
|
||||
drop_cards_on_stack(stack, Cards::CardStack::MovementRule::Any);
|
||||
bool was_visible = moving_cards_source_stack()->is_empty() || !moving_cards_source_stack()->peek().is_upside_down();
|
||||
remember_move_for_undo(*moving_cards_source_stack(), stack, card_count, was_visible);
|
||||
update_score(-1);
|
||||
moving_cards_source_stack()->make_top_card_visible();
|
||||
detect_full_stacks();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue