summaryrefslogtreecommitdiff
path: root/Userland/Games
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-05-15 22:13:11 -0400
committerAndreas Kling <kling@serenityos.org>2021-05-16 16:37:51 +0200
commitddb278ab85f65a3111b4011bbc102023a863421a (patch)
tree3a402cce16e6ed865e9fe51fd341f1fc8d9ccf60 /Userland/Games
parentce030ca584b0311c97466f4b30ebd7e989a51a17 (diff)
downloadserenity-ddb278ab85f65a3111b4011bbc102023a863421a.zip
Solitaire: Add key combo to dump the state of the layout
Useful for chasing down bugs.
Diffstat (limited to 'Userland/Games')
-rw-r--r--Userland/Games/Solitaire/Card.cpp1
-rw-r--r--Userland/Games/Solitaire/Card.h32
-rw-r--r--Userland/Games/Solitaire/CardStack.h40
-rw-r--r--Userland/Games/Solitaire/Game.cpp12
-rw-r--r--Userland/Games/Solitaire/Game.h1
5 files changed, 85 insertions, 1 deletions
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 <AK/Array.h>
+#include <AK/Format.h>
#include <LibCore/Object.h>
#include <LibGUI/Painter.h>
#include <LibGfx/Bitmap.h>
@@ -21,6 +23,9 @@ public:
static constexpr int width = 80;
static constexpr int height = 100;
static constexpr int card_count = 13;
+ static constexpr Array<StringView, card_count> 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<Solitaire::Card> : Formatter<FormatString> {
+ 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<FormatString>::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 <AK/Format.h>
#include <AK/Vector.h>
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<Card>& 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<Solitaire::CardStack> : Formatter<FormatString> {
+ 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<FormatString>::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 <AK/Debug.h>
#include <LibGUI/Painter.h>
#include <LibGfx/Palette.h>
#include <time.h>
@@ -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)
{