From fc8649b12fc1280d81e8dd4d35736ed69c0d9909 Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Sat, 16 Nov 2019 14:22:39 -0800 Subject: Keep WIP --- Source/Randomizer2Core.cpp | 164 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Source/Randomizer2Core.cpp (limited to 'Source/Randomizer2Core.cpp') diff --git a/Source/Randomizer2Core.cpp b/Source/Randomizer2Core.cpp new file mode 100644 index 0000000..2659076 --- /dev/null +++ b/Source/Randomizer2Core.cpp @@ -0,0 +1,164 @@ +#include "Randomizer2Core.h" +#include "Puzzle.h" +#include "Random.h" + +#include +#include +#include + +std::vector Randomizer2Core::CutEdgesToBeUnique(const Puzzle& p) { + auto [colorGrid, numColors] = CreateColorGrid(p); + std::vector edges; + for (int x=0; x edges; + for (int x=1; x cutEdges = CutEdgesInternal(p, colorGrid, edges, numEdges); + for (Pos pos : cutEdges) { + p.grid[pos.x][pos.y].gap = Cell::Gap::FULL; + } +} + +std::vector Randomizer2Core::CutEdgesInternal(const Puzzle& p, std::vector>& colorGrid, std::vector& edges, size_t numEdges) { + std::vector cutEdges; + for (int i=0; i(edges.size() - 1)); + Pos pos = edges[edge]; + edges.erase(edges.begin() + edge); + + int color1 = 0; + int color2 = 0; + if (pos.x%2 == 0 && pos.y%2 == 1) { // Vertical + if (pos.x > 0) color1 = colorGrid[pos.x-1][pos.y]; + else color1 = 1; + + if (pos.x < p.width - 1) color2 = colorGrid[pos.x+1][pos.y]; + else color2 = 1; + } else { // Horizontal + assert(pos.x%2 == 1 && pos.y%2 == 0); + if (pos.y > 0) color1 = colorGrid[pos.x][pos.y-1]; + else color1 = 1; + + if (pos.y < p.height - 1) color2 = colorGrid[pos.x][pos.y+1]; + else color2 = 1; + } + // Enforce color1 < color2 + if (color1 > color2) std::swap(color1, color2); + + // Colors mismatch, valid cut + if (color1 != color2) { + // @Performance... have a lookup table instead? + for (int x=0; x>& colorGrid) { + for (int y=0; y>& colorGrid, int color, int x, int y) { + if (!p.SafeCell(x, y)) return; + if (colorGrid[x][y] != 0) return; // Already processed. + colorGrid[x][y] = color; + + FloodFill(p, colorGrid, color, x, y+1); + FloodFill(p, colorGrid, color, x, y-1); + FloodFill(p, colorGrid, color, x+1, y); + FloodFill(p, colorGrid, color, x-1, y); +} + +void Randomizer2Core::FloodFillOutside(const Puzzle& p, std::vector>& colorGrid, int x, int y) { + if (!p.SafeCell(x, y)) return; + if (colorGrid[x][y] != 0) return; // Already processed. + if (x%2 != y%2 && p.grid[x][y].gap != Cell::Gap::FULL) return; // Only flood-fill through full gaps + colorGrid[x][y] = 1; // Outside color + + FloodFillOutside(p, colorGrid, x, y+1); + FloodFillOutside(p, colorGrid, x, y-1); + FloodFillOutside(p, colorGrid, x+1, y); + FloodFillOutside(p, colorGrid, x-1, y); +} + +/* + undefined -> 1 (color of outside) or * (any colored cell) or -1 (edge/intersection not part of any region) + + 0 -> {} (this is a special edge case, which I don't need right now) + 1 -> 0 (uncolored / ready to color) + 2 -> +*/ +std::tuple>, int> Randomizer2Core::CreateColorGrid(const Puzzle& p) { + std::vector> colorGrid; + colorGrid.resize(p.width); + + for (int x=0; x