From 1b833a86102981ce178119fc3526f354b7622170 Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Thu, 14 Nov 2019 09:08:35 -0800 Subject: small changes --- App/Main.cpp | 3 +- Source/Memory.cpp | 3 +- Source/Memory.h | 8 ++- Source/Randomizer2.cpp | 187 +++++++++++++++++++++++++++++++++++++++---------- Source/Randomizer2.h | 3 + Source/Solver.cpp | 2 + Source/Solver.h | 5 +- 7 files changed, 166 insertions(+), 45 deletions(-) diff --git a/App/Main.cpp b/App/Main.cpp index 3fb9df4..a96c34d 100644 --- a/App/Main.cpp +++ b/App/Main.cpp @@ -165,7 +165,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) Solver::Solve(g_puzzle); break; case TMP4: - g_randomizer2->Randomize(); + SetRandomSeed(); + g_randomizer2->RandomizeKeep(); } } return DefWindowProc(hwnd, message, wParam, lParam); diff --git a/Source/Memory.cpp b/Source/Memory.cpp index c3b89d0..98b06f9 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp @@ -152,7 +152,8 @@ int Memory::ExecuteSigScans() void Memory::ThrowError() { std::wstring message(256, '\0'); - int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), 1024, &message[0], static_cast(message.size()), nullptr); + DWORD error = GetLastError(); + int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 1024, &message[0], static_cast(message.size()), nullptr); message.resize(length); #ifndef NDEBUG MessageBox(NULL, message.c_str(), L"Please tell darkid about this", MB_OK); diff --git a/Source/Memory.h b/Source/Memory.h index 95de884..6b8403f 100644 --- a/Source/Memory.h +++ b/Source/Memory.h @@ -5,8 +5,8 @@ #include #include -// #define GLOBALS 0x5B28C0 -#define GLOBALS 0x62D0A0 +#define GLOBALS 0x5B28C0 +// #define GLOBALS 0x62D0A0 #define HEARTBEAT 0x401 enum class ProcStatus { @@ -102,6 +102,8 @@ private: }; #if GLOBALS == 0x5B28C0 +#define POSITION 0x24 +#define ORIENTATION 0x34 #define PATH_COLOR 0xC8 #define REFLECTION_PATH_COLOR 0xD8 #define DOT_COLOR 0xF8 @@ -169,6 +171,8 @@ private: #define METADATA 0xF2 // sizeof(short) #define HOTEL_EP_NAME 0x4BC640 #elif GLOBALS == 0x62D0A0 +#define POSITION #error +#define ORIENTATION #error #define PATH_COLOR 0xC0 #define REFLECTION_PATH_COLOR 0xD0 #define DOT_COLOR 0xF0 diff --git a/Source/Randomizer2.cpp b/Source/Randomizer2.cpp index fcfec9a..537c30b 100644 --- a/Source/Randomizer2.cpp +++ b/Source/Randomizer2.cpp @@ -2,6 +2,38 @@ #include "Puzzle.h" #include "Random.h" #include "Solver.h" +#include "Memory.h" + +void FloodFillInternal(const Puzzle& p, std::vector>& reached, int x, int y) { + if (x%2 == 1 && y%2 == 1) return; + auto cell = p.GetCell(x, y); + if (cell.undefined) return; + if (cell.gap != Cell::Gap::NONE) return; + if (reached[x][y]) return; + + reached[x][y] = true; + FloodFillInternal(p, reached, x-1, y); + FloodFillInternal(p, reached, x+1, y); + FloodFillInternal(p, reached, x, y-1); + FloodFillInternal(p, reached, x, y+1); +} + +// Returns true: All nodes reachable / false: Some node disconnected +bool FloodFill(const Puzzle& p) { + std::vector> reached; + reached.resize(p.width); + for (int x=0; x& memory) : _memory(memory) {} @@ -12,9 +44,7 @@ void Randomizer2::Randomize() { // end (x=8, y=0) Up // 1 solution Puzzle p; - int attemptCount = 0; while (true) { - attemptCount++; p.NewGrid(4, 4); std::vector corners; @@ -29,40 +59,34 @@ void Randomizer2::Randomize() { } for (int i=0; i<14; i++) { - int edge = Random::RandInt(0, static_cast(edges.size() - 1)); - Pos pos = edges[edge]; - p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; - edges.erase(edges.begin() + edge); + for (int j=0; j(edges.size() - 1)); + Pos pos = edges[edge]; + p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; + edges.erase(edges.begin() + edge); + + if (FloodFill(p)) { + break; + } else { + p.grid[pos.x][pos.y].gap = Cell::Gap::NONE; + } + } } 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 0) break; } PuzzleSerializer(_memory).WritePuzzle(p, 0x293); - - - // 7x7 // 35 gaps // start (x=8, y=8) // end (x=4, y=0) Up // 2 solutions, 37 & 39 - attemptCount = 0; while (true) { - attemptCount++; p.NewGrid(7, 7); std::vector corners; @@ -77,28 +101,117 @@ void Randomizer2::Randomize() { } for (int i=0; i<35; i++) { - int edge = Random::RandInt(0, static_cast(edges.size() - 1)); - Pos pos = edges[edge]; - p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; - edges.erase(edges.begin() + edge); + for (int j=0; j(edges.size() - 1)); + Pos pos = edges[edge]; + p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; + edges.erase(edges.begin() + edge); + + if (FloodFill(p)) { + break; + } else { + p.grid[pos.x][pos.y].gap = Cell::Gap::NONE; + } + } } - p.grid[8][8].start = true; - p.grid[4][0].end = Cell::Dir::UP; + switch (Random::RandInt(1, 4)) { + case 1: + p.grid[Random::RandInt(0, p.width-1)][0].end = Cell::Dir::UP; + break; + case 2: + p.grid[Random::RandInt(0, p.width-1)][p.height-1].end = Cell::Dir::DOWN; + break; + case 3: + p.grid[0][Random::RandInt(0, p.height-1)].end = Cell::Dir::LEFT; + break; + case 4: + p.grid[p.width-1][Random::RandInt(0, p.height-1)].end = Cell::Dir::RIGHT; + break; + } + switch (Random::RandInt(1, 3)) { + case 1: // Horiz (6) [5/7][4/6/8] + p.grid[Random::RandInt(0, 1)*2 + 5][Random::RandInt(0, 2)*2 + 4].start = true; + break; + case 2: // Verti (6) [4/6/8][5/7] + p.grid[Random::RandInt(0, 2)*2 + 4][Random::RandInt(0, 1)*2 + 5].start = true; + break; + case 3: // Inter (9) [4/6/8][4/6/8] + p.grid[Random::RandInt(0, 2)*2 + 4][Random::RandInt(0, 2)*2 + 4].start = true; + break; + } 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); } + +void Randomizer2::RandomizeKeep() { + Puzzle p; + p.width = 9; + p.height = 10; + p.grid.clear(); + p.grid.resize(p.width); + for (int x=0; xWritePanelData(panel, POSITION, {x, y, 19.1f}); + + float z, w; + if (X%2 == 0 && Y%2 == 1) { // Horizontal + z = -0.1f; + w = 1.0f; + } else if (X%2 == 1 && Y%2 == 0) { // Vertical + z = -.77f; + w = .63f; + } else { + assert(false); + return; + } + + _memory->WritePanelData(panel, ORIENTATION, {0.0f, 0.0f, z, w}); +} \ No newline at end of file diff --git a/Source/Randomizer2.h b/Source/Randomizer2.h index 1aeae11..848fd22 100644 --- a/Source/Randomizer2.h +++ b/Source/Randomizer2.h @@ -6,7 +6,10 @@ class Randomizer2 { public: Randomizer2(const std::shared_ptr& memory); void Randomize(); + void RandomizeKeep(); private: + void SetGate(int panel, int X, int Y); + std::shared_ptr _memory; }; diff --git a/Source/Solver.cpp b/Source/Solver.cpp index 244bfb2..bce1482 100644 --- a/Source/Solver.cpp +++ b/Source/Solver.cpp @@ -2,6 +2,8 @@ #include "Puzzle.h" #include "Validator.h" +int Solver::MAX_SOLUTIONS = 10000; + std::vector Solver::Solve(Puzzle& p) { std::vector solutions; // var start = (new Date()).getTime() diff --git a/Source/Solver.h b/Source/Solver.h index 09108c7..455d1eb 100644 --- a/Source/Solver.h +++ b/Source/Solver.h @@ -1,13 +1,10 @@ #pragma once #include -#ifndef MAX_SOLUTIONS -#define MAX_SOLUTIONS 10000 -#endif - class Puzzle; class Solver { public: + static int MAX_SOLUTIONS; static std::vector Solve(Puzzle& p); private: -- cgit 1.4.1