From 98db209c9008492baec6bb482b047d386fbdd42b Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Sat, 9 Nov 2019 14:23:42 -0800 Subject: One down, 522 to go. --- App/Main.cpp | 10 ++++- Source/Puzzle.cpp | 12 +++--- Source/Puzzle.h | 28 ++++++++++--- Source/Randomizer2.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ Source/Randomizer2.h | 12 ++++++ Source/Solver.h | 2 +- Source/Source.vcxproj | 2 + Source/Validator.h | 2 +- 8 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 Source/Randomizer2.cpp create mode 100644 Source/Randomizer2.h diff --git a/App/Main.cpp b/App/Main.cpp index 5213a79..3fb9df4 100644 --- a/App/Main.cpp +++ b/App/Main.cpp @@ -23,14 +23,17 @@ /* ------- Temp ------- */ #include "Puzzle.h" #include "Solver.h" +#include "Randomizer2.h" #include #define TMP1 0x501 #define TMP2 0x502 #define TMP3 0x503 +#define TMP4 0x504 HWND g_panelId; Puzzle g_puzzle; +std::shared_ptr g_randomizer2; /* ------- Temp ------- */ // Globals @@ -61,12 +64,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // Shut down randomizer, wait for startup if (g_randomizer) { g_randomizer = nullptr; + g_randomizer2 = nullptr; EnableWindow(g_randomizerStatus, FALSE); } break; case ProcStatus::Running: if (!g_randomizer) { g_randomizer = std::make_shared(g_witnessProc); + g_randomizer2 = std::make_shared(g_witnessProc); PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL); } break; @@ -159,6 +164,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case TMP3: Solver::Solve(g_puzzle); break; + case TMP4: + g_randomizer2->Randomize(); } } return DefWindowProc(hwnd, message, wParam, lParam); @@ -244,7 +251,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance g_panelId = CreateText(200, 100, 100, L"A3B2"); CreateButton(200, 130, 100, L"Read", TMP1); CreateButton(200, 160, 100, L"Write", TMP2); - CreateButton(200, 190, 100, L"Validate", TMP3); + CreateButton(200, 190, 100, L"Solve", TMP3); + CreateButton(200, 220, 100, L"Randomize2", TMP4); g_witnessProc->StartHeartbeat(g_hwnd); diff --git a/Source/Puzzle.cpp b/Source/Puzzle.cpp index ee4c2e8..cc552d3 100644 --- a/Source/Puzzle.cpp +++ b/Source/Puzzle.cpp @@ -7,16 +7,14 @@ PuzzleSerializer::PuzzleSerializer(const std::shared_ptr& memory) : _memory(memory) {} Puzzle PuzzleSerializer::ReadPuzzle(int id) { - Puzzle p; - p.width = 2 * _memory->ReadPanelData(id, GRID_SIZE_X, 1)[0] - 1; - p.height = 2 * _memory->ReadPanelData(id, GRID_SIZE_Y, 1)[0] - 1; - if (p.width < 0 || p.height < 0) return p; // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. - p.grid.resize(p.width); - for (auto& row : p.grid) row.resize(p.height); + int width = 2 * _memory->ReadPanelData(id, GRID_SIZE_X, 1)[0] - 1; + int height = 2 * _memory->ReadPanelData(id, GRID_SIZE_Y, 1)[0] - 1; + if (width < 0 || height < 0) return Puzzle(); // @Error: Grid size should be always positive? Looks like the starting panels break this rule, though. + Puzzle p; + p.NewGrid(width, height); ReadIntersections(p, id); ReadDecorations(p, id); - return p; } diff --git a/Source/Puzzle.h b/Source/Puzzle.h index 7a98a78..94cb4b0 100644 --- a/Source/Puzzle.h +++ b/Source/Puzzle.h @@ -37,7 +37,6 @@ struct Decoration { int count = 0; }; - struct Cell { inline static Cell Undefined() { Cell c; @@ -63,7 +62,9 @@ struct Cell { struct Negation {}; struct Pos {int x; int y;}; -struct Puzzle { +#include // TODO: Move this + impl to cpp +class Puzzle { +public: int16_t height; int16_t width; bool hasDecorations = false; @@ -72,6 +73,10 @@ struct Puzzle { Symmetry sym = Symmetry::NONE; bool pillar = false; + bool valid; + std::vector negations; + std::vector invalidElements; + inline Cell GetCell(int x, int y) const { x = Mod(x); if (!SafeCell(x, y)) return Cell::Undefined(); @@ -80,13 +85,24 @@ struct Puzzle { inline Cell::Color GetLine(int x, int y) const { return grid[x][y].color; } + inline void NewGrid(int newWidth, int newHeight) { + if (newWidth == 0) { + assert(false); + newWidth = width; + newHeight = height; + } else { + // @Cleanup! This should be in the ctor... + width = 2*newWidth + 1; + height = 2*newHeight + 1; + } + grid.clear(); + grid.resize(width); + for (int x=0; x negations; - std::vector invalidElements; - // private: std::vector> grid; diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp new file mode 100644 index 0000000..fcfec9a --- /dev/null +++ b/Source/Randomizer2.cpp @@ -0,0 +1,104 @@ +#include "Randomizer2.h" +#include "Puzzle.h" +#include "Random.h" +#include "Solver.h" + +Randomizer2::Randomizer2(const std::shared_ptr& memory) : _memory(memory) {} + +void Randomizer2::Randomize() { + // 4x4 + // 14 gaps + // start (x=0, y=8) + // end (x=8, y=0) Up + // 1 solution + Puzzle p; + int attemptCount = 0; + while (true) { + attemptCount++; + p.NewGrid(4, 4); + + std::vector corners; + std::vector cells; + std::vector edges; + for (int x=0; x(edges.size() - 1)); + Pos pos = edges[edge]; + p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; + edges.erase(edges.begin() + edge); + } + + p.grid[0][8].start = true; + p.grid[8][0].end = Cell::Dir::UP; + + auto solutions = Solver::Solve(p); + if (solutions.size() == 1) { + auto solution = solutions[0]; + int solutionLength = 0; + for (int x=0; x corners; + std::vector cells; + std::vector edges; + for (int x=0; x(edges.size() - 1)); + Pos pos = edges[edge]; + p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; + edges.erase(edges.begin() + edge); + } + + p.grid[8][8].start = true; + p.grid[4][0].end = Cell::Dir::UP; + + auto solutions = Solver::Solve(p); + if (solutions.size() > 0) break; + if (solutions.size() > 0 && solutions.size() < 5) { + auto solution = solutions[0]; + int solutionLength = 0; + for (int x=0; x 30 && solutionLength < 40) break; + } + } + PuzzleSerializer(_memory).WritePuzzle(p, 0x295); + +} diff --git a/Source/Randomizer2.h b/Source/Randomizer2.h new file mode 100644 index 0000000..1aeae11 --- /dev/null +++ b/Source/Randomizer2.h @@ -0,0 +1,12 @@ +#pragma once +#include + +class Memory; +class Randomizer2 { +public: + Randomizer2(const std::shared_ptr& memory); + void Randomize(); + +private: + std::shared_ptr _memory; +}; diff --git a/Source/Solver.h b/Source/Solver.h index 8a021ac..09108c7 100644 --- a/Source/Solver.h +++ b/Source/Solver.h @@ -5,7 +5,7 @@ #define MAX_SOLUTIONS 10000 #endif -struct Puzzle; +class Puzzle; class Solver { public: static std::vector Solve(Puzzle& p); diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 92aa9d7..aebeaeb 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj @@ -163,6 +163,7 @@ + @@ -172,6 +173,7 @@ + diff --git a/Source/Validator.h b/Source/Validator.h index cddc293..2a102dd 100644 --- a/Source/Validator.h +++ b/Source/Validator.h @@ -15,7 +15,7 @@ #endif struct Region{}; -struct Puzzle; +class Puzzle; struct Pos; class Validator { public: -- cgit 1.4.1