implement editing the board win condition

This commit is contained in:
2026-02-24 22:36:22 +01:00
parent d8534cacdd
commit b9e3ab8d2d
5 changed files with 65 additions and 5 deletions

View File

@ -1,5 +1,5 @@
// 1 Block, 1 Axis, no goal // 1 Block, 1 Axis, no goal
R4599ab...................................... R459912......................................
// 2 Blocks, 2 Axes, no goal // 2 Blocks, 2 Axes, no goal
R45991212.................................... R45991212....................................

View File

@ -226,6 +226,8 @@ public:
auto IsWon() const -> bool; auto IsWon() const -> bool;
auto SetGoal(int x, int y) -> bool;
auto AddColumn() const -> State; auto AddColumn() const -> State;
auto RemoveColumn() const -> State; auto RemoveColumn() const -> State;
@ -240,6 +242,8 @@ public:
auto GetBlockAt(int x, int y) const -> std::string; auto GetBlockAt(int x, int y) const -> std::string;
auto GetTargetBlock() const -> Block;
auto GetIndex(int x, int y) const -> int; auto GetIndex(int x, int y) const -> int;
auto RemoveBlock(int x, int y) -> bool; auto RemoveBlock(int x, int y) -> bool;

View File

@ -89,6 +89,15 @@ auto InputHandler::HandleMouse() -> void {
block_add_y = -1; block_add_y = -1;
has_block_add_xy = false; has_block_add_xy = false;
} }
} else if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) {
if (hov_x >= 0 && hov_x < state.current_state.width && hov_y >= 0 &&
hov_y < state.current_state.height) {
if (state.current_state.SetGoal(hov_x, hov_y)) {
// We can't just call state.FindWinningStates() because the
// state is entirely different if it has a different win condition.
state.ClearGraph();
}
}
} }
} }

View File

@ -54,7 +54,7 @@ auto Block::Collides(const Block &other) const -> bool {
auto State::Hash() const -> int { return std::hash<std::string>{}(state); } auto State::Hash() const -> int { return std::hash<std::string>{}(state); }
auto State::HasWinCondition() const -> bool { auto State::HasWinCondition() const -> bool {
return target_x == 9 || target_y == 9; return target_x != 9 && target_y != 9;
} }
auto State::IsWon() const -> bool { auto State::IsWon() const -> bool {
@ -71,6 +71,26 @@ auto State::IsWon() const -> bool {
return false; return false;
} }
auto State::SetGoal(int x, int y) -> bool {
if (x < 0 || x >= width || y < 0 || y >= height ||
!GetTargetBlock().IsValid()) {
return false;
}
if (target_x == x && target_y == y) {
target_x = 9;
target_y = 9;
} else {
target_x = x;
target_y = y;
}
state.replace(3, 1, std::format("{}", target_x));
state.replace(4, 1, std::format("{}", target_y));
return true;
}
auto State::AddColumn() const -> State { auto State::AddColumn() const -> State {
State newstate = State(width + 1, height, restricted); State newstate = State(width + 1, height, restricted);
@ -146,6 +166,16 @@ auto State::GetBlockAt(int x, int y) const -> std::string {
return state.substr(GetIndex(x, y), 2); return state.substr(GetIndex(x, y), 2);
} }
auto State::GetTargetBlock() const -> Block {
for (Block b : *this) {
if (b.target) {
return b;
}
}
return Block::Invalid();
}
auto State::GetIndex(int x, int y) const -> int { auto State::GetIndex(int x, int y) const -> int {
return prefix + (y * width + x) * 2; return prefix + (y * width + x) * 2;
} }

View File

@ -132,13 +132,13 @@ auto Renderer::DrawMassSprings(
const Vector3 &winning_mass = masses.at(winning_index); const Vector3 &winning_mass = masses.at(winning_index);
if (input.mark_solutions) { if (input.mark_solutions) {
DrawCube(winning_mass, 2 * VERTEX_SIZE, 2 * VERTEX_SIZE, DrawCube(winning_mass, 2 * VERTEX_SIZE, 2 * VERTEX_SIZE,
2 * VERTEX_SIZE, BLUE); 2 * VERTEX_SIZE, TARGET_BLOCK_COLOR);
} }
std::size_t current_index = state.CurrentMassIndex(); std::size_t current_index = state.CurrentMassIndex();
if (input.connect_solutions && masses.size() > current_index) { if (input.connect_solutions && masses.size() > current_index) {
const Vector3 &current_mass = masses.at(current_index); const Vector3 &current_mass = masses.at(current_index);
DrawLine3D(winning_mass, current_mass, PURPLE); DrawLine3D(winning_mass, current_mass, ORANGE);
} }
} }
} }
@ -168,7 +168,7 @@ auto Renderer::DrawMassSprings(
if (masses.size() > current_index) { if (masses.size() > current_index) {
const Vector3 &current_mass = masses.at(current_index); const Vector3 &current_mass = masses.at(current_index);
DrawCube(current_mass, VERTEX_SIZE * 2, VERTEX_SIZE * 2, VERTEX_SIZE * 2, DrawCube(current_mass, VERTEX_SIZE * 2, VERTEX_SIZE * 2, VERTEX_SIZE * 2,
RED); BLUE);
} }
// DrawCubeWires(current_mass.position, REPULSION_RANGE, REPULSION_RANGE, // DrawCubeWires(current_mass.position, REPULSION_RANGE, REPULSION_RANGE,
@ -267,6 +267,23 @@ auto Renderer::DrawKlotski() -> void {
block_size / 10.0, Fade(BLACK, 0.5)); block_size / 10.0, Fade(BLACK, 0.5));
} }
// Draw board goal position
const Block target = state.current_state.GetTargetBlock();
if (target.IsValid() && state.current_state.HasWinCondition()) {
int target_x = state.current_state.target_x;
int target_y = state.current_state.target_y;
DrawRectangleLinesEx(
Rectangle(x_offset + BOARD_PADDING + target_x * BLOCK_PADDING * 2 +
BLOCK_PADDING + target_x * block_size,
y_offset + BOARD_PADDING + target_y * BLOCK_PADDING * 2 +
BLOCK_PADDING + target_y * block_size,
target.width * block_size + target.width * 2 * BLOCK_PADDING -
2 * BLOCK_PADDING,
target.height * block_size +
target.height * 2 * BLOCK_PADDING - 2 * BLOCK_PADDING),
2.0, TARGET_BLOCK_COLOR);
}
DrawLine(GetScreenWidth() / 2 - 1, 0, GetScreenWidth() / 2 - 1, DrawLine(GetScreenWidth() / 2 - 1, 0, GetScreenWidth() / 2 - 1,
GetScreenHeight() - MENU_HEIGHT, BLACK); GetScreenHeight() - MENU_HEIGHT, BLACK);
EndTextureMode(); EndTextureMode();