summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Games/Solitaire/Game.cpp28
-rw-r--r--Userland/Games/Solitaire/Game.h2
-rw-r--r--Userland/Libraries/LibCards/Card.cpp8
-rw-r--r--Userland/Libraries/LibCards/Card.h1
-rw-r--r--Userland/Libraries/LibCards/CardStack.cpp36
-rw-r--r--Userland/Libraries/LibCards/CardStack.h5
6 files changed, 50 insertions, 30 deletions
diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp
index a7a99a6323..81091f242e 100644
--- a/Userland/Games/Solitaire/Game.cpp
+++ b/Userland/Games/Solitaire/Game.cpp
@@ -21,20 +21,20 @@ Game::Game()
{
srand(time(nullptr));
- m_stacks[Stock] = CardStack({ 10, 10 }, CardStack::Type::Stock);
- m_stacks[Waste] = CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste);
- m_stacks[Play] = CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Play);
- m_stacks[Foundation4] = CardStack({ Game::width - Card::width - 10, 10 }, CardStack::Type::Foundation);
- m_stacks[Foundation3] = CardStack({ Game::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation);
- m_stacks[Foundation2] = CardStack({ Game::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation);
- m_stacks[Foundation1] = CardStack({ Game::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation);
- m_stacks[Pile1] = CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile2] = CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile3] = CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile4] = CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile5] = CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile6] = CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal);
- m_stacks[Pile7] = CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal);
+ m_stacks.append(adopt_ref(*new CardStack({ 10, 10 }, CardStack::Type::Stock)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Waste)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 }, CardStack::Type::Play, m_stacks.ptr_at(Waste))));
+ m_stacks.append(adopt_ref(*new CardStack({ Game::width - 4 * Card::width - 40, 10 }, CardStack::Type::Foundation)));
+ m_stacks.append(adopt_ref(*new CardStack({ Game::width - 3 * Card::width - 30, 10 }, CardStack::Type::Foundation)));
+ m_stacks.append(adopt_ref(*new CardStack({ Game::width - 2 * Card::width - 20, 10 }, CardStack::Type::Foundation)));
+ m_stacks.append(adopt_ref(*new CardStack({ Game::width - Card::width - 10, 10 }, CardStack::Type::Foundation)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + Card::width + 10, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + 2 * Card::width + 20, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + 3 * Card::width + 30, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + 4 * Card::width + 40, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + 5 * Card::width + 50, 10 + Card::height + 10 }, CardStack::Type::Normal)));
+ m_stacks.append(adopt_ref(*new CardStack({ 10 + 6 * Card::width + 60, 10 + Card::height + 10 }, CardStack::Type::Normal)));
}
Game::~Game()
diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h
index c782a73778..30168bd13c 100644
--- a/Userland/Games/Solitaire/Game.h
+++ b/Userland/Games/Solitaire/Game.h
@@ -188,7 +188,7 @@ private:
LastMove m_last_move;
NonnullRefPtrVector<Card> m_focused_cards;
NonnullRefPtrVector<Card> m_new_deck;
- CardStack m_stacks[StackLocation::__Count];
+ NonnullRefPtrVector<CardStack> m_stacks;
CardStack* m_focused_stack { nullptr };
Gfx::IntPoint m_mouse_down_location;
diff --git a/Userland/Libraries/LibCards/Card.cpp b/Userland/Libraries/LibCards/Card.cpp
index cc7552fe2d..2a88e45e82 100644
--- a/Userland/Libraries/LibCards/Card.cpp
+++ b/Userland/Libraries/LibCards/Card.cpp
@@ -81,9 +81,9 @@ Card::Card(Type type, uint8_t value)
float aspect_ratio = image->width() / static_cast<float>(image->height());
auto target_size = Gfx::IntSize(static_cast<int>(aspect_ratio * (height - 5)), height - 5);
- bg_painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, 5, 5, 5, 5);
+ bg_painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, card_radius);
auto inner_paint_rect = paint_rect.shrunken(2, 2);
- bg_painter.fill_rect_with_rounded_corners(inner_paint_rect, Color::White, 4, 4, 4, 4);
+ bg_painter.fill_rect_with_rounded_corners(inner_paint_rect, Color::White, card_radius - 1);
bg_painter.draw_scaled_bitmap(
{ { (width - target_size.width()) / 2, (height - target_size.height()) / 2 }, target_size },
@@ -96,9 +96,9 @@ Card::Card(Type type, uint8_t value)
auto& font = Gfx::FontDatabase::default_font().bold_variant();
auto label = labels[value];
- painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, 5, 5, 5, 5);
+ painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, card_radius);
paint_rect.shrink(2, 2);
- painter.fill_rect_with_rounded_corners(paint_rect, Color::White, 4, 4, 4, 4);
+ painter.fill_rect_with_rounded_corners(paint_rect, Color::White, card_radius - 1);
paint_rect.set_height(paint_rect.height() / 2);
paint_rect.shrink(10, 6);
diff --git a/Userland/Libraries/LibCards/Card.h b/Userland/Libraries/LibCards/Card.h
index eaafe68863..fbe0353d9e 100644
--- a/Userland/Libraries/LibCards/Card.h
+++ b/Userland/Libraries/LibCards/Card.h
@@ -23,6 +23,7 @@ public:
static constexpr int width = 80;
static constexpr int height = 100;
static constexpr int card_count = 13;
+ static constexpr int card_radius = 5;
static constexpr Array<StringView, card_count> labels = {
"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
};
diff --git a/Userland/Libraries/LibCards/CardStack.cpp b/Userland/Libraries/LibCards/CardStack.cpp
index d213990672..aa0c7869f7 100644
--- a/Userland/Libraries/LibCards/CardStack.cpp
+++ b/Userland/Libraries/LibCards/CardStack.cpp
@@ -25,6 +25,17 @@ CardStack::CardStack(const Gfx::IntPoint& position, Type type)
calculate_bounding_box();
}
+CardStack::CardStack(const Gfx::IntPoint& position, Type type, NonnullRefPtr<CardStack> associated_stack)
+ : m_associated_stack(move(associated_stack))
+ , m_position(position)
+ , m_type(type)
+ , m_rules(rules_for_type(type))
+ , m_base(m_position, { Card::width, Card::height })
+{
+ VERIFY(type != Invalid);
+ calculate_bounding_box();
+}
+
void CardStack::clear()
{
m_stack.clear();
@@ -33,17 +44,25 @@ void CardStack::clear()
void CardStack::draw(GUI::Painter& painter, const Gfx::Color& background_color)
{
+ auto draw_background_if_empty = [&]() {
+ if (m_associated_stack && !m_associated_stack->is_empty())
+ return false;
+ if (!is_empty() && !(m_stack.size() == 1 && peek().is_moving()))
+ return false;
+ painter.fill_rect_with_rounded_corners(m_base, background_color.darkened(0.5), Card::card_radius);
+ painter.fill_rect_with_rounded_corners(m_base.shrunken(2, 2), background_color, Card::card_radius - 1);
+ return true;
+ };
+
switch (m_type) {
case Stock:
- if (is_empty()) {
+ if (draw_background_if_empty()) {
painter.fill_rect(m_base.shrunken(Card::width / 4, Card::height / 4), background_color.lightened(1.5));
painter.fill_rect(m_base.shrunken(Card::width / 2, Card::height / 2), background_color);
- painter.draw_rect(m_base, background_color.darkened(0.5));
}
break;
case Foundation:
- if (is_empty() || (m_stack.size() == 1 && peek().is_moving())) {
- painter.draw_rect(m_base, background_color.darkened(0.5));
+ if (draw_background_if_empty()) {
for (int y = 0; y < (m_base.height() - 4) / 8; ++y) {
for (int x = 0; x < (m_base.width() - 4) / 5; ++x) {
painter.draw_rect({ 4 + m_base.x() + x * 5, 4 + m_base.y() + y * 8, 1, 1 }, background_color.darkened(0.5));
@@ -51,14 +70,11 @@ void CardStack::draw(GUI::Painter& painter, const Gfx::Color& background_color)
}
}
break;
- case Waste:
- break;
case Play:
- if (is_empty() || (m_stack.size() == 1 && peek().is_moving()))
- painter.draw_rect(m_base, background_color.darkened(0.5));
- break;
case Normal:
- painter.draw_rect(m_base, background_color.darkened(0.5));
+ draw_background_if_empty();
+ break;
+ case Waste:
break;
default:
VERIFY_NOT_REACHED();
diff --git a/Userland/Libraries/LibCards/CardStack.h b/Userland/Libraries/LibCards/CardStack.h
index 36acc824df..75259b57b2 100644
--- a/Userland/Libraries/LibCards/CardStack.h
+++ b/Userland/Libraries/LibCards/CardStack.h
@@ -8,11 +8,12 @@
#include "Card.h"
#include <AK/Format.h>
+#include <AK/RefCounted.h>
#include <AK/Vector.h>
namespace Cards {
-class CardStack final {
+class CardStack final : public RefCounted<CardStack> {
public:
enum Type {
Invalid,
@@ -25,6 +26,7 @@ public:
CardStack();
CardStack(const Gfx::IntPoint& position, Type type);
+ CardStack(const Gfx::IntPoint& position, Type type, NonnullRefPtr<CardStack> associated_stack);
bool is_empty() const { return m_stack.is_empty(); }
bool is_focused() const { return m_focused; }
@@ -75,6 +77,7 @@ private:
void calculate_bounding_box();
+ RefPtr<CardStack> m_associated_stack;
NonnullRefPtrVector<Card> m_stack;
Vector<Gfx::IntPoint> m_stack_positions;
Gfx::IntPoint m_position;