From e48ce4469cee270687e04bc1a2b91d3c2bba0789 Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Fri, 2 Nov 2018 21:22:29 -0700 Subject: arglbargl --- Source/Panel.cpp | 199 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 139 insertions(+), 60 deletions(-) (limited to 'Source/Panel.cpp') diff --git a/Source/Panel.cpp b/Source/Panel.cpp index 0f62664..5465bef 100644 --- a/Source/Panel.cpp +++ b/Source/Panel.cpp @@ -1,27 +1,20 @@ #include "Panel.h" #include "Random.h" +#include -Decoration::Decoration(int shape) { - _shape = shape; -} - -int Decoration::GetValue() { - return _shape; -} - -Intersection::Intersection(float x, float y, int flags) { - _x = x; - _y = y; - _flags = flags; -} - -int Intersection::GetValue() { - return _flags; +template +int find(const std::vector &data, T search, size_t startIndex = 0) { + for (size_t i=startIndex ; i(id, GRID_SIZE_X, 1)[0]; - _height = _memory.ReadPanelData(id, GRID_SIZE_Y, 1)[0]; + _width = 2 * _memory.ReadPanelData(id, GRID_SIZE_X, 1)[0] - 1; + _height = 2 * _memory.ReadPanelData(id, GRID_SIZE_Y, 1)[0] - 1; + _grid.resize(_width); + for (auto& row : _grid) row.resize(_height); ReadIntersections(id); ReadDecorations(id); @@ -31,67 +24,134 @@ void Panel::Write(int id) { WriteIntersections(id); WriteDecorations(id); - _memory.WritePanelData(id, GRID_SIZE_X, {_width}); - _memory.WritePanelData(id, GRID_SIZE_Y, {_height}); + _memory.WritePanelData(id, GRID_SIZE_X, {(_width + 1)/2}); + _memory.WritePanelData(id, GRID_SIZE_Y, {(_height + 1)/2}); +} + +nlohmann::json Panel::Serialize() { + nlohmann::json puzzle = { + {"pillar", false}, + {"dots", nlohmann::json::array()}, + {"gaps", nlohmann::json::array()}, + {"name", "Imported from The Witness :O"}, + {"regionCache", nlohmann::json::object()}, + }; + if (_grid.empty()) return {}; + puzzle["grid"] = nlohmann::json::array(); + + for (int x=0; x<_width; x++) { + for (int y=0; y<_height; y++) { + if (x%2 == 1 && y%2 == 1) { + puzzle["grid"][x][y] = Decoration::to_json(_grid[x][y]); + } else { + puzzle["grid"][x][y] = false; + } + } + } + + puzzle["startPoints"] = nlohmann::json::array(); + for (auto [x, y] : _startpoints) { + nlohmann::json startPoint = {{"x", x}, {"y", y}}; + puzzle["startPoints"].emplace_back(startPoint); + } + puzzle["endPoints"] = nlohmann::json::array(); + for (Endpoint endpoint : _endpoints) { + puzzle["endPoints"].emplace_back(endpoint.to_json()); + } + + std::string out = puzzle.dump(); + return puzzle; } void Panel::Random() { +/* for (auto& row : _decorations) { for (auto& cell : row) { - cell._shape &= 0xFFFFFFF0; - cell._shape |= Random::RandInt(1, 10); + cell.SetShape(cell.GetShape() & 0xFFFFFFF0); + cell.SetShape(cell.GetShape() | Random::RandInt(1, 10)); } } +*/ } void Panel::ReadDecorations(int id) { int numDecorations = _memory.ReadPanelData(id, NUM_DECORATIONS, 1)[0]; std::vector decorations = _memory.ReadArray(id, DECORATIONS, numDecorations); - _decorations.resize(_width - 1); - for (int x=0; x<_width-1; x++) { - _decorations[x].resize(_height - 1); - for (int y=0; y<_height-1; y++) { - int i = x * (_height - 1) + y; - _decorations[x][y] = Decoration(decorations[i]); + + int x = 1; + int y = _height - 2; + for (int decoration : decorations) { + _grid[x][y] = decoration; + x += 2; + if (x > _width - 1) { + x = 1; + y -= 2; } } } void Panel::WriteDecorations(int id) { - std::vector flattenedDecorations; - for (std::vector row : _decorations) { - for (Decoration decoration : row) { - flattenedDecorations.push_back(decoration.GetValue()); + std::vector decorations; + for (int y=_height - 2; y>0; y-=2) { + for (int x=1; x<_width - 1; x+=2) { + decorations.push_back(_grid[x][y]); } } - _memory.WritePanelData(id, NUM_DECORATIONS, {static_cast(flattenedDecorations.size())}); - _memory.WriteArray(id, DECORATIONS, flattenedDecorations); + _memory.WritePanelData(id, NUM_DECORATIONS, {static_cast(decorations.size())}); + _memory.WriteArray(id, DECORATIONS, decorations); } void Panel::ReadIntersections(int id) { int numIntersections = _memory.ReadPanelData(id, NUM_DOTS, 1)[0]; - std::vector intersections = _memory.ReadArray(id, DOT_POSITIONS, numIntersections*2); std::vector intersectionFlags = _memory.ReadArray(id, DOT_FLAGS, numIntersections); - _intersections.resize(_width); - int i=0; - for (int y=0; y<_height; y++) { - for (int x=0; x<_width; x++) { - _intersections[x].resize(_height); - _intersections[x][y] = Intersection(intersections[2*i], intersections[2*i+1], intersectionFlags[i]); - i++; + + int x = 0; + int y = _height - 1; + int i = 0; + for (;; i++) { + if (intersectionFlags[i] & IntersectionFlags::IS_STARTPOINT) { + _startpoints.push_back({x, y}); } + x += 2; + if (x > _width) { + x = 0; + y -= 2; + } + if (y < 0) break; } + std::pair, std::vector> connections; + int numConnections = _memory.ReadPanelData(id, NUM_CONNECTIONS, 1)[0]; + connections.first = _memory.ReadArray(id, DOT_CONNECTION_A, numConnections); + connections.second = _memory.ReadArray(id, DOT_CONNECTION_B, numConnections); + std::vector intersections = _memory.ReadArray(id, DOT_POSITIONS, numIntersections*2); + // Iterate the remaining intersections (either endpoints or gaps) for (; i < numIntersections; i++) { - if (intersectionFlags[i] & Intersection::Flags::IS_ENDPOINT) { - _endpoints.push_back(Intersection(intersections[2*i], intersections[2*i+1], intersectionFlags[i])); - } - if (intersectionFlags[i] & Intersection::Flags::IS_GAP) { - _gaps.push_back(Intersection(intersections[2*i], intersections[2*i+1], intersectionFlags[i])); + if (intersectionFlags[i] & IntersectionFlags::IS_ENDPOINT) { + for (int j=0; j intersections[2*location]) { + dir = Endpoint::Direction::RIGHT; + } else if (intersections[2*i + 1] > intersections[2*location + 1]) { // y coordinate is 0 (bottom) 1 (top), so this check is reversed. + dir = Endpoint::Direction::UP; + } else { + dir = Endpoint::Direction::DOWN; + } + int x = 2 * (location % ((_width + 1) / 2)); + int y = (_height - 1) - 2 * (location / ((_width + 1) / 2)); + _endpoints.push_back(Endpoint(x, y, dir)); + } + } } - } + } } void Panel::WriteIntersections(int id) { @@ -99,12 +159,18 @@ void Panel::WriteIntersections(int id) { std::vector intersectionFlags; std::pair, std::vector> connections; + double min = 0.1; + double max = 0.9; + double width_interval = (max - min) / (_width - 1); + double height_interval = (max - min) / (_height - 1); + for (int y=0; y<_height; y++) { for (int x=0; x<_width; x++) { - Intersection intersection = _intersections[x][y]; - intersections.push_back(intersection._x); - intersections.push_back(intersection._y); - intersectionFlags.push_back(intersection._flags); + intersections.push_back(min + x * width_interval); + intersections.push_back(min + y * height_interval); + int flags = 0; + if (find(_startpoints, {x, y}) != -1) flags |= IntersectionFlags::IS_STARTPOINT; + intersectionFlags.push_back(flags); if (y > 0) { connections.first.push_back(y * _width + x); connections.second.push_back((y - 1) * _width + x); @@ -116,19 +182,32 @@ void Panel::WriteIntersections(int id) { } } - // Endpoints go here :( + for (Endpoint endpoint : _endpoints) { + float xPos = min + endpoint.GetX() * width_interval; + float yPos = min + endpoint.GetY() * height_interval; + if (endpoint.GetDir()== Endpoint::Direction::LEFT) { + xPos -= .05f; + } else if (endpoint.GetDir() == Endpoint::Direction::RIGHT) { + xPos += .05f; + } else if (endpoint.GetDir() == Endpoint::Direction::UP) { + yPos += .05f; // Y position goes from 0 (bottom) to 1 (top), so this is reversed. + } else if (endpoint.GetDir() == Endpoint::Direction::DOWN) { + yPos -= .05f; + } + intersections.push_back(xPos); + intersections.push_back(yPos); - int a = _memory.ReadPanelData(id, NUM_DOTS, 1)[0]; - std::vector b = _memory.ReadArray(id, DOT_POSITIONS, a*2); - std::vector c = _memory.ReadArray(id, DOT_FLAGS, a); - std::pair, std::vector> d; - d.first = _memory.ReadArray(id, DOT_CONNECTION_A, a); - d.second = _memory.ReadArray(id, DOT_CONNECTION_B, a); + connections.first.push_back(endpoint.GetY() * _width + endpoint.GetX()); // Target to connect to + connections.second.push_back(intersectionFlags.size()); // This endpoint + intersectionFlags.push_back(IntersectionFlags::IS_ENDPOINT); + } - _memory.WritePanelData(id, NUM_DOTS, {_width * _height}); + _memory.WritePanelData(id, NUM_DOTS, {static_cast(intersectionFlags.size())}); _memory.WriteArray(id, DOT_POSITIONS, intersections); _memory.WriteArray(id, DOT_FLAGS, intersectionFlags); + _memory.WritePanelData(id, NUM_CONNECTIONS, {static_cast(connections.first.size())}); _memory.WriteArray(id, DOT_CONNECTION_A, connections.first); _memory.WriteArray(id, DOT_CONNECTION_B, connections.second); + _memory.WritePanelData(id, NEEDS_REDRAW, {1}); } -- cgit 1.4.1