implement immovable blocks (walls) and add two presets

This commit is contained in:
2026-02-25 17:21:54 +01:00
parent 81620d8709
commit 4a37e93b98
7 changed files with 89 additions and 24 deletions

View File

@ -167,6 +167,10 @@ auto InputHandler::HandleKeys() -> void {
state.current_state.ToggleTarget(sel_x, sel_y);
state.ClearGraph();
state.edited = true;
} else if (IsKeyPressed(KEY_Y)) {
state.current_state.ToggleWall(sel_x, sel_y);
state.ClearGraph();
state.edited = true;
} else if (IsKeyPressed(KEY_LEFT) && state.current_state.width > 1) {
state.current_state = state.current_state.RemoveColumn();
state.ClearGraph();

View File

@ -14,7 +14,6 @@
#endif
// 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.

View File

@ -14,7 +14,7 @@ auto Block::Hash() const -> int {
}
auto Block::Invalid() -> Block {
Block block = Block(0, 0, 1, 1, false);
Block block = Block(0, 0, 1, 1, false, false);
block.width = 0;
block.height = 0;
return block;
@ -27,12 +27,20 @@ auto Block::ToString() const -> std::string {
return std::format("{}{}",
static_cast<char>(width + static_cast<int>('a') - 1),
static_cast<char>(height + static_cast<int>('a') - 1));
} else if (immovable) {
return std::format("{}{}",
static_cast<char>(width + static_cast<int>('A') - 1),
static_cast<char>(height + static_cast<int>('A') - 1));
} else {
return std::format("{}{}", width, height);
}
}
auto Block::GetPrincipalDirs() const -> int {
if (immovable) {
return 0;
}
if (width > height) {
return Direction::EAS | Direction::WES;
} else if (height > width) {
@ -194,7 +202,7 @@ auto State::RemoveBlock(int x, int y) -> bool {
auto State::ToggleTarget(int x, int y) -> bool {
Block block = GetBlock(x, y);
if (!block.IsValid()) {
if (!block.IsValid() || block.immovable) {
return false;
}
@ -217,6 +225,20 @@ auto State::ToggleTarget(int x, int y) -> bool {
return true;
}
auto State::ToggleWall(int x, int y) -> bool {
Block block = GetBlock(x, y);
if (!block.IsValid() || block.target) {
return false;
}
// Add the new target
block.immovable = !block.immovable;
int index = GetIndex(block.x, block.y);
state.replace(index, 2, block.ToString());
return true;
}
auto State::ToggleRestricted() -> void {
restricted = !restricted;
state.replace(0, 1, restricted ? "R" : "F");
@ -224,7 +246,7 @@ auto State::ToggleRestricted() -> void {
auto State::MoveBlockAt(int x, int y, Direction dir) -> bool {
Block block = GetBlock(x, y);
if (!block.IsValid()) {
if (!block.IsValid() || block.immovable) {
return false;
}
@ -285,6 +307,10 @@ auto State::GetNextStates() const -> std::vector<State> {
: Direction::NOR | Direction::EAS | Direction::SOU |
Direction::WES;
if (b.immovable) {
continue;
}
if (dirs & Direction::NOR) {
State north = *this;
if (north.MoveBlockAt(b.x, b.y, Direction::NOR)) {

View File

@ -241,6 +241,12 @@ auto Renderer::DrawKlotski() -> void {
} else {
c = TARGET_BLOCK_COLOR;
}
} else if (block.immovable) {
if (block.Covers(input.sel_x, input.sel_y)) {
c = HL_WALL_COLOR;
} else {
c = WALL_COLOR;
}
}
DrawRectangle(x_offset + BOARD_PADDING + block.x * BLOCK_PADDING * 2 +
BLOCK_PADDING + block.x * block_size,
@ -360,7 +366,7 @@ auto Renderer::DrawMenu(const std::vector<Vector3> &masses) -> void {
DARKGREEN);
// Center column
draw_btn(1, 0, std::format("Select (LMB) / Move (W, A, S, D) / Target (T)"),
draw_btn(1, 0, std::format("Select (LMB) / Move (WASD) / Target/Wall (T/Y)"),
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)"),