From ddb278ab85f65a3111b4011bbc102023a863421a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 15 May 2021 22:13:11 -0400 Subject: [PATCH] Solitaire: Add key combo to dump the state of the layout Useful for chasing down bugs. --- Userland/Games/Solitaire/Card.cpp | 1 - Userland/Games/Solitaire/Card.h | 32 ++++++++++++++++++++++ Userland/Games/Solitaire/CardStack.h | 40 ++++++++++++++++++++++++++++ Userland/Games/Solitaire/Game.cpp | 12 +++++++++ Userland/Games/Solitaire/Game.h | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/Userland/Games/Solitaire/Card.cpp b/Userland/Games/Solitaire/Card.cpp index 40c4d4d072..20e79c128e 100644 --- a/Userland/Games/Solitaire/Card.cpp +++ b/Userland/Games/Solitaire/Card.cpp @@ -89,7 +89,6 @@ Card::Card(Type type, uint8_t value) Gfx::Painter painter(m_front); auto& font = Gfx::FontDatabase::default_bold_font(); - static const String labels[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; auto label = labels[value]; m_front->fill(Color::White); diff --git a/Userland/Games/Solitaire/Card.h b/Userland/Games/Solitaire/Card.h index 8a3c97cc47..a63c39749e 100644 --- a/Userland/Games/Solitaire/Card.h +++ b/Userland/Games/Solitaire/Card.h @@ -6,6 +6,8 @@ #pragma once +#include +#include #include #include #include @@ -21,6 +23,9 @@ public: static constexpr int width = 80; static constexpr int height = 100; static constexpr int card_count = 13; + static constexpr Array labels = { + "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" + }; enum Type { Clubs, @@ -67,3 +72,30 @@ private: }; } + +template<> +struct AK::Formatter : Formatter { + void format(FormatBuilder& builder, const Solitaire::Card& card) + { + StringView type; + + switch (card.type()) { + case Solitaire::Card::Type::Clubs: + type = "C"sv; + break; + case Solitaire::Card::Type::Diamonds: + type = "D"sv; + break; + case Solitaire::Card::Type::Hearts: + type = "H"sv; + break; + case Solitaire::Card::Type::Spades: + type = "S"sv; + break; + default: + VERIFY_NOT_REACHED(); + } + + Formatter::format(builder, "{:>2}{}", Solitaire::Card::labels[card.value()], type); + } +}; diff --git a/Userland/Games/Solitaire/CardStack.h b/Userland/Games/Solitaire/CardStack.h index 5acd22d473..90ffec5282 100644 --- a/Userland/Games/Solitaire/CardStack.h +++ b/Userland/Games/Solitaire/CardStack.h @@ -7,6 +7,7 @@ #pragma once #include "Card.h" +#include #include namespace Solitaire { @@ -28,6 +29,7 @@ public: bool is_empty() const { return m_stack.is_empty(); } bool is_focused() const { return m_focused; } Type type() const { return m_type; } + const NonnullRefPtrVector& stack() const { return m_stack; } size_t count() const { return m_stack.size(); } const Card& peek() const { return m_stack.last(); } Card& peek() { return m_stack.last(); } @@ -84,3 +86,41 @@ private: }; } + +template<> +struct AK::Formatter : Formatter { + void format(FormatBuilder& builder, const Solitaire::CardStack& stack) + { + StringView type; + + switch (stack.type()) { + case Solitaire::CardStack::Type::Stock: + type = "Stock"sv; + break; + case Solitaire::CardStack::Type::Normal: + type = "Normal"sv; + break; + case Solitaire::CardStack::Type::Foundation: + type = "Foundation"sv; + break; + case Solitaire::CardStack::Type::Waste: + type = "Waste"sv; + break; + case Solitaire::CardStack::Type::Play: + type = "Play"sv; + break; + default: + VERIFY_NOT_REACHED(); + } + + StringBuilder cards; + bool first_card = true; + + for (const auto& card : stack.stack()) { + cards.appendff("{}{}", (first_card ? "" : " "), card); + first_card = false; + } + + Formatter::format(builder, "{:<10} {:>16}: {}", type, stack.bounding_box(), cards.build()); + } +}; diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index 7c677b7c2e..d7e19e659f 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -5,6 +5,7 @@ */ #include "Game.h" +#include #include #include #include @@ -139,6 +140,8 @@ void Game::keydown_event(GUI::KeyEvent& event) if (event.shift() && (event.key() == KeyCode::Key_F12)) start_game_over_animation(); + else if (event.shift() && (event.key() == KeyCode::Key_F11)) + dump_layout(); } void Game::mousedown_event(GUI::MouseEvent& event) @@ -466,4 +469,13 @@ void Game::paint_event(GUI::PaintEvent& event) } } +void Game::dump_layout() const +{ + if constexpr (SOLITAIRE_DEBUG) { + dbgln("------------------------------"); + for (const auto& stack : m_stacks) + dbgln("{}", stack); + } +} + } diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index 144ae9f15e..220532c931 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -114,6 +114,7 @@ private: void stop_game_over_animation(); void create_new_animation_card(); void check_for_game_over(); + void dump_layout() const; ALWAYS_INLINE CardStack& stack(StackLocation location) {