allow changing the target block
This commit is contained in:
@ -270,6 +270,8 @@ public:
|
|||||||
|
|
||||||
auto RemoveBlock(int x, int y) -> bool;
|
auto RemoveBlock(int x, int y) -> bool;
|
||||||
|
|
||||||
|
auto ToggleTarget(int x, int y) -> bool;
|
||||||
|
|
||||||
auto MoveBlockAt(int x, int y, Direction dir) -> bool;
|
auto MoveBlockAt(int x, int y, Direction dir) -> bool;
|
||||||
|
|
||||||
auto GetNextStates() const -> std::vector<State>;
|
auto GetNextStates() const -> std::vector<State>;
|
||||||
|
|||||||
@ -136,6 +136,32 @@ auto State::RemoveBlock(int x, int y) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto State::ToggleTarget(int x, int y) -> bool {
|
||||||
|
Block block = GetBlock(x, y);
|
||||||
|
if (!block.IsValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the current target
|
||||||
|
int index;
|
||||||
|
for (const auto &block : *this) {
|
||||||
|
if (block.target) {
|
||||||
|
index = GetIndex(block.x, block.y);
|
||||||
|
state.replace(
|
||||||
|
index, 2,
|
||||||
|
Block(block.x, block.y, block.width, block.height, false).ToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new target
|
||||||
|
block.target = !block.target;
|
||||||
|
index = GetIndex(block.x, block.y);
|
||||||
|
state.replace(index, 2, block.ToString());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto State::MoveBlockAt(int x, int y, Direction dir) -> bool {
|
auto State::MoveBlockAt(int x, int y, Direction dir) -> bool {
|
||||||
Block block = GetBlock(x, y);
|
Block block = GetBlock(x, y);
|
||||||
if (!block.IsValid()) {
|
if (!block.IsValid()) {
|
||||||
|
|||||||
32
src/main.cpp
32
src/main.cpp
@ -14,6 +14,17 @@
|
|||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: Klotski state file loading
|
||||||
|
// - File should contain a single state per line, multiple lines possible
|
||||||
|
// - If a file is loaded, the presets should be replaced with the states
|
||||||
|
// from the file
|
||||||
|
// - Automatically determine the winning condition based on a configured
|
||||||
|
// board exit
|
||||||
|
// TODO: Graph interaction
|
||||||
|
// - Click states to display them in the board
|
||||||
|
// - Find shortest path to any winning state and mark it in the graph
|
||||||
|
// - Also mark the next move along the path on the board
|
||||||
|
|
||||||
auto apply_state(MassSpringSystem &mass_springs, StateGenerator generator)
|
auto apply_state(MassSpringSystem &mass_springs, StateGenerator generator)
|
||||||
-> State {
|
-> State {
|
||||||
mass_springs.springs.clear();
|
mass_springs.springs.clear();
|
||||||
@ -203,13 +214,27 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
sel_x++;
|
sel_x++;
|
||||||
}
|
}
|
||||||
} else if (IsKeyPressed(KEY_P)) {
|
} else if (IsKeyPressed(KEY_P)) {
|
||||||
std::cout << current_state.state << std::endl;
|
std::cout << "State: " << current_state.state << std::endl;
|
||||||
|
Block sel = current_state.GetBlock(sel_x, sel_y);
|
||||||
|
int idx = current_state.GetIndex(sel.x, sel.y) - 5;
|
||||||
|
if (sel.IsValid()) {
|
||||||
|
std::cout << "Sel: " << current_state.state.substr(0, 5)
|
||||||
|
<< std::string(idx, '.') << sel.ToString()
|
||||||
|
<< std::string(current_state.state.length() - idx - 7, '.')
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
} else if (IsKeyPressed(KEY_N)) {
|
} else if (IsKeyPressed(KEY_N)) {
|
||||||
|
block_add_x = -1;
|
||||||
|
block_add_y = -1;
|
||||||
|
has_block_add_xy = false;
|
||||||
current_preset =
|
current_preset =
|
||||||
(generators.size() + current_preset - 1) % generators.size();
|
(generators.size() + current_preset - 1) % generators.size();
|
||||||
current_state = apply_state(masssprings, generators[current_preset]);
|
current_state = apply_state(masssprings, generators[current_preset]);
|
||||||
previous_state = current_state.state;
|
previous_state = current_state.state;
|
||||||
} else if (IsKeyPressed(KEY_M)) {
|
} else if (IsKeyPressed(KEY_M)) {
|
||||||
|
block_add_x = -1;
|
||||||
|
block_add_y = -1;
|
||||||
|
has_block_add_xy = false;
|
||||||
current_preset = (current_preset + 1) % generators.size();
|
current_preset = (current_preset + 1) % generators.size();
|
||||||
current_state = apply_state(masssprings, generators[current_preset]);
|
current_state = apply_state(masssprings, generators[current_preset]);
|
||||||
previous_state = current_state.state;
|
previous_state = current_state.state;
|
||||||
@ -228,8 +253,11 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
renderer.mark_solutions = !renderer.mark_solutions;
|
renderer.mark_solutions = !renderer.mark_solutions;
|
||||||
} else if (IsKeyPressed(KEY_O)) {
|
} else if (IsKeyPressed(KEY_O)) {
|
||||||
renderer.connect_solutions = !renderer.connect_solutions;
|
renderer.connect_solutions = !renderer.connect_solutions;
|
||||||
} else if (IsKeyPressed(KEY_T)) {
|
} else if (IsKeyPressed(KEY_F)) {
|
||||||
current_state.restricted = !current_state.restricted;
|
current_state.restricted = !current_state.restricted;
|
||||||
|
} else if (IsKeyPressed(KEY_T)) {
|
||||||
|
current_state.ToggleTarget(sel_x, sel_y);
|
||||||
|
previous_state = clear_masssprings(masssprings, current_state);
|
||||||
} else if (IsKeyPressed(KEY_LEFT) && current_state.width > 1) {
|
} else if (IsKeyPressed(KEY_LEFT) && current_state.width > 1) {
|
||||||
current_state = current_state.RemoveColumn();
|
current_state = current_state.RemoveColumn();
|
||||||
previous_state = clear_masssprings(masssprings, current_state);
|
previous_state = clear_masssprings(masssprings, current_state);
|
||||||
|
|||||||
@ -299,7 +299,7 @@ auto Renderer::DrawMenu(const MassSpringSystem &masssprings, int current_preset,
|
|||||||
draw_btn(1, 2, std::format("Print Board State to Console (P)"), DARKBLUE);
|
draw_btn(1, 2, std::format("Print Board State to Console (P)"), DARKBLUE);
|
||||||
|
|
||||||
draw_btn(2, 0,
|
draw_btn(2, 0,
|
||||||
std::format("Preset (M/N): {}, {} (T)", current_preset,
|
std::format("Preset (M/N): {}, {} (F)", current_preset,
|
||||||
current_state.restricted ? "Restricted" : "Free"),
|
current_state.restricted ? "Restricted" : "Free"),
|
||||||
DARKPURPLE);
|
DARKPURPLE);
|
||||||
draw_btn(2, 1, std::format("Populate Graph (G), Clear Graph (C)"),
|
draw_btn(2, 1, std::format("Populate Graph (G), Clear Graph (C)"),
|
||||||
|
|||||||
Reference in New Issue
Block a user