mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibCards: Support non-alternating colour patience games
This introduces a new MovementType concept to LibCards, starting the process to allow other patience games to be implemented using it - that differ more substantially from Klondike in logic. This is currently used for two purposes: 1. to verify that the 'grabbed' stack of cards is valid* (sequential and correct colours) and 2. to allow 'grabbed' stacks to be pushed onto same-colour, either-colour, or alternating-colour stacks * Klondike doesn't need this logic, as per how the game works any 'grabbed' selection is guaranteed to be valid.
This commit is contained in:
parent
84c0f98fb2
commit
b7e806e15e
Notes:
sideshowbarker
2024-07-18 11:35:30 +09:00
Author: https://github.com/jamierocks Commit: https://github.com/SerenityOS/serenity/commit/b7e806e15ef Pull-request: https://github.com/SerenityOS/serenity/pull/8079 Reviewed-by: https://github.com/gunnarbeutner
2 changed files with 67 additions and 7 deletions
|
@ -108,7 +108,7 @@ void CardStack::rebound_cards()
|
|||
card.set_position(m_stack_positions.at(card_index++));
|
||||
}
|
||||
|
||||
void CardStack::add_all_grabbed_cards(const Gfx::IntPoint& click_location, NonnullRefPtrVector<Card>& grabbed)
|
||||
void CardStack::add_all_grabbed_cards(const Gfx::IntPoint& click_location, NonnullRefPtrVector<Card>& grabbed, MovementRule movement_rule)
|
||||
{
|
||||
VERIFY(grabbed.is_empty());
|
||||
|
||||
|
@ -149,15 +149,56 @@ void CardStack::add_all_grabbed_cards(const Gfx::IntPoint& click_location, Nonnu
|
|||
grabbed.append(*last_intersect);
|
||||
last_intersect->set_moving(true);
|
||||
}
|
||||
|
||||
// verify valid stack
|
||||
bool valid_stack = true;
|
||||
uint8_t last_value;
|
||||
Color last_color;
|
||||
for (size_t i = 0; i < grabbed.size(); i++) {
|
||||
auto& card = grabbed.at(i);
|
||||
if (i != 0) {
|
||||
bool color_match;
|
||||
switch (movement_rule) {
|
||||
case Alternating:
|
||||
color_match = card.color() != last_color;
|
||||
break;
|
||||
case Same:
|
||||
color_match = card.color() == last_color;
|
||||
break;
|
||||
case Any:
|
||||
color_match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!color_match || card.value() != last_value - 1) {
|
||||
valid_stack = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
last_value = card.value();
|
||||
last_color = card.color();
|
||||
}
|
||||
|
||||
if (!valid_stack) {
|
||||
for (auto& card : grabbed) {
|
||||
card.set_moving(false);
|
||||
}
|
||||
grabbed.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CardStack::is_allowed_to_push(const Card& card, size_t stack_size) const
|
||||
bool CardStack::is_allowed_to_push(const Card& card, size_t stack_size, MovementRule movement_rule) const
|
||||
{
|
||||
if (m_type == Stock || m_type == Waste || m_type == Play)
|
||||
return false;
|
||||
|
||||
if (m_type == Normal && is_empty())
|
||||
return card.value() == 12;
|
||||
if (m_type == Normal && is_empty()) {
|
||||
// FIXME: proper solution for this
|
||||
if (movement_rule == Alternating) {
|
||||
return card.value() == 12;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_type == Foundation && is_empty())
|
||||
return card.value() == 0;
|
||||
|
@ -173,7 +214,20 @@ bool CardStack::is_allowed_to_push(const Card& card, size_t stack_size) const
|
|||
return false;
|
||||
return top_card.type() == card.type() && m_stack.size() == card.value();
|
||||
} else if (m_type == Normal) {
|
||||
return top_card.color() != card.color() && top_card.value() == card.value() + 1;
|
||||
bool color_match;
|
||||
switch (movement_rule) {
|
||||
case Alternating:
|
||||
color_match = card.color() != top_card.color();
|
||||
break;
|
||||
case Same:
|
||||
color_match = card.color() == top_card.color();
|
||||
break;
|
||||
case Any:
|
||||
color_match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return color_match && top_card.value() == card.value() + 1;
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
|
|
|
@ -24,6 +24,12 @@ public:
|
|||
Foundation
|
||||
};
|
||||
|
||||
enum MovementRule {
|
||||
Alternating,
|
||||
Same,
|
||||
Any,
|
||||
};
|
||||
|
||||
CardStack();
|
||||
CardStack(const Gfx::IntPoint& position, Type type);
|
||||
CardStack(const Gfx::IntPoint& position, Type type, NonnullRefPtr<CardStack> associated_stack);
|
||||
|
@ -44,8 +50,8 @@ public:
|
|||
void move_to_stack(CardStack&);
|
||||
void rebound_cards();
|
||||
|
||||
bool is_allowed_to_push(const Card&, size_t stack_size = 1) const;
|
||||
void add_all_grabbed_cards(const Gfx::IntPoint& click_location, NonnullRefPtrVector<Card>& grabbed);
|
||||
bool is_allowed_to_push(const Card&, size_t stack_size = 1, MovementRule movement_rule = Alternating) const;
|
||||
void add_all_grabbed_cards(const Gfx::IntPoint& click_location, NonnullRefPtrVector<Card>& grabbed, MovementRule movement_rule = Alternating);
|
||||
void draw(GUI::Painter&, const Gfx::Color& background_color);
|
||||
void clear();
|
||||
|
||||
|
|
Loading…
Reference in a new issue