display puzzle title

This commit is contained in:
2026-02-25 16:53:13 +01:00
parent 5a2172cb00
commit 5e3d007a9d
6 changed files with 38 additions and 15 deletions

View File

@ -4,7 +4,7 @@ project(MassSprings)
set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD 26)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wno-unused-parameter -Wunreachable-code") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wno-unused-parameter -Wunreachable-code")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2 -ggdb") # -fsanitize=address already fails on InitWindow(), -fsanitize=undefined, -fsanitize=leak set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2 -ggdb") # -fsanitize=address already fails on InitWindow(), -fsanitize=undefined, -fsanitize=leak
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -march=native") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -march=native")

View File

@ -12,12 +12,12 @@
// Window // Window
constexpr int INITIAL_WIDTH = 800; constexpr int INITIAL_WIDTH = 800;
constexpr int INITIAL_HEIGHT = 800; constexpr int INITIAL_HEIGHT = 800;
constexpr int MENU_HEIGHT = 200; constexpr int MENU_HEIGHT = 250;
// Menu // Menu
constexpr int MENU_PAD = 5; constexpr int MENU_PAD = 5;
constexpr int BUTTON_PAD = 12; constexpr int BUTTON_PAD = 12;
constexpr int MENU_ROWS = 4; constexpr int MENU_ROWS = 5;
constexpr int MENU_COLS = 3; constexpr int MENU_COLS = 3;
// Camera Controls // Camera Controls

View File

@ -16,6 +16,7 @@ public:
ThreadedPhysics &physics; ThreadedPhysics &physics;
std::vector<State> presets; std::vector<State> presets;
std::vector<std::string> comments;
// Some stuff is faster to map from state to mass (e.g. in the renderer) // Some stuff is faster to map from state to mass (e.g. in the renderer)
std::unordered_map<State, std::size_t> states; std::unordered_map<State, std::size_t> states;

View File

@ -13,7 +13,8 @@
#include <tracy/Tracy.hpp> #include <tracy/Tracy.hpp>
#endif #endif
// TODO: Click states to display them in the board // TODO: Click states in the graph to display them in the board
// TODO: Add walls (unmoveable blocks)
// NOTE: Tracy uses a huge amount of memory. For longer testing disable Tracy. // NOTE: Tracy uses a huge amount of memory. For longer testing disable Tracy.

View File

@ -322,13 +322,26 @@ auto Renderer::DrawMenu(const std::vector<Vector3> &masses) -> void {
auto draw_btn = [&](int x, int y, std::string text, Color color) { auto draw_btn = [&](int x, int y, std::string text, Color color) {
int posx = MENU_PAD + x * (MENU_PAD + btn_width); int posx = MENU_PAD + x * (MENU_PAD + btn_width);
int posy = MENU_PAD + y * (MENU_PAD + btn_height); int posy = MENU_PAD + (y + 1) * (MENU_PAD + btn_height);
DrawRectangle(posx, posy, btn_width, btn_height, Fade(color, 0.7)); DrawRectangle(posx, posy, btn_width, btn_height, Fade(color, 0.7));
DrawRectangleLines(posx, posy, btn_width, btn_height, color); DrawRectangleLines(posx, posy, btn_width, btn_height, color);
DrawText(text.data(), posx + BUTTON_PAD, posy + BUTTON_PAD, DrawText(text.data(), posx + BUTTON_PAD, posy + BUTTON_PAD,
btn_height - 2.0 * BUTTON_PAD, WHITE); btn_height - 2.0 * BUTTON_PAD, WHITE);
}; };
auto draw_subtitle = [&](std::string text, Color color) {
int posx = MENU_PAD;
int posy = MENU_PAD;
DrawRectangle(posx, posy,
btn_width * MENU_COLS + MENU_PAD * (MENU_COLS - 1),
btn_height, Fade(color, 0.7));
DrawRectangleLines(posx, posy,
btn_width * MENU_COLS + MENU_PAD * (MENU_COLS - 1),
btn_height, color);
DrawText(text.data(), posx + BUTTON_PAD, posy + BUTTON_PAD,
btn_height = 2.0 * BUTTON_PAD, WHITE);
};
// Left column // Left column
draw_btn(0, 0, draw_btn(0, 0,
std::format("States: {} / Transitions: {} / Winning: {}", std::format("States: {} / Transitions: {} / Winning: {}",
@ -336,7 +349,7 @@ auto Renderer::DrawMenu(const std::vector<Vector3> &masses) -> void {
state.winning_states.size()), state.winning_states.size()),
ORANGE); ORANGE);
draw_btn(0, 1, draw_btn(0, 1,
std::format("Preset (M/N): {}, {} (F)", state.current_preset, std::format("Preset (M/N) / {} (F)",
state.current_state.restricted ? "Restricted" : "Free"), state.current_state.restricted ? "Restricted" : "Free"),
ORANGE); ORANGE);
draw_btn(0, 2, std::format("Pan (LMB) / Rotate (RMB) / Zoom (Wheel)"), draw_btn(0, 2, std::format("Pan (LMB) / Rotate (RMB) / Zoom (Wheel)"),
@ -350,27 +363,31 @@ auto Renderer::DrawMenu(const std::vector<Vector3> &masses) -> void {
draw_btn(1, 0, std::format("Select (LMB) / Move (W, A, S, D) / Target (T)"), draw_btn(1, 0, std::format("Select (LMB) / Move (W, A, S, D) / Target (T)"),
DARKBLUE); DARKBLUE);
draw_btn(1, 1, std::format("Add/Remove Col/Row (Arrow Keys)"), DARKBLUE); draw_btn(1, 1, std::format("Add/Remove Col/Row (Arrow Keys)"), DARKBLUE);
draw_btn(1, 2, std::format("Add/Remove Block (LMB/RMB), Set Goal (MMB)"), draw_btn(1, 2, std::format("Add/Remove Block (LMB/RMB) / Set Goal (MMB)"),
DARKBLUE); DARKBLUE);
draw_btn(1, 3, std::format("Print State (P) / Reset State (R)"), DARKBLUE); draw_btn(1, 3, std::format("Print State (P) / Reset State (R)"), DARKBLUE);
// Right column // Right column
draw_btn(2, 0, std::format("Populate Graph (G), Clear Graph (C)"), draw_btn(2, 0, std::format("Populate Graph (G) / Clear Graph (C)"),
DARKPURPLE); DARKPURPLE);
draw_btn(2, 1, draw_btn(2, 1,
std::format("Path (U): {} / Goals (I): {} / Connect (O): {}", std::format("Path (U): {} / Goals (I): {} / Lines (O): {}",
input.mark_path, input.mark_solutions, input.mark_path, input.mark_solutions,
input.connect_solutions), input.connect_solutions),
DARKPURPLE); DARKPURPLE);
draw_btn(2, 2, std::format("Best move (Space) / Move back (Backspace)"), draw_btn(2, 2, std::format("Best move (Space) / Move back (Backspace)"),
DARKPURPLE); DARKPURPLE);
draw_btn(2, 3, draw_btn(2, 3,
std::format("Worst (V) / Nearest target (B) / Moves remaining: {}", std::format("Worst (V) / Target (B) / Distance: {}",
state.winning_path.size() > 0 state.winning_path.size() > 0
? state.winning_path.size() - 1 ? state.winning_path.size() - 1
: 0), : 0),
DARKPURPLE); DARKPURPLE);
draw_subtitle(std::format("Puzzle {}: {}", state.current_preset + 1,
state.comments.at(state.current_preset)),
BLACK);
DrawLine(0, MENU_HEIGHT - 1, GetScreenWidth(), MENU_HEIGHT - 1, BLACK); DrawLine(0, MENU_HEIGHT - 1, GetScreenWidth(), MENU_HEIGHT - 1, BLACK);
EndTextureMode(); EndTextureMode();
} }

View File

@ -20,25 +20,29 @@ auto StateManager::ParsePresetFile(const std::string &preset_file) -> void {
} }
std::string line; std::string line;
std::vector<std::string> lines; std::vector<std::string> comment_lines;
std::vector<std::string> preset_lines;
while (std::getline(file, line)) { while (std::getline(file, line)) {
if (line.starts_with("F") || line.starts_with("R")) { if (line.starts_with("F") || line.starts_with("R")) {
lines.push_back(line); preset_lines.push_back(line);
} else if (line.starts_with("#")) {
comment_lines.push_back(line);
} }
} }
if (lines.size() == 0) { if (preset_lines.size() == 0 || comment_lines.size() != preset_lines.size()) {
std::cout << "Preset file \"" << preset_file << "\" couldn't be loaded." std::cout << "Preset file \"" << preset_file << "\" couldn't be loaded."
<< std::endl; << std::endl;
return; return;
} }
presets.clear(); presets.clear();
for (const auto &preset : lines) { for (const auto &preset : preset_lines) {
presets.emplace_back(preset); presets.emplace_back(preset);
} }
comments = comment_lines;
std::cout << "Loaded " << lines.size() << " presets." << std::endl; std::cout << "Loaded " << preset_lines.size() << " presets." << std::endl;
} }
auto StateManager::LoadPreset(int preset) -> void { auto StateManager::LoadPreset(int preset) -> void {