about summary refs log tree commit diff stats
path: root/Source/PuzzlerSerializer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/PuzzlerSerializer.cpp')
-rw-r--r--Source/PuzzlerSerializer.cpp63
1 files changed, 40 insertions, 23 deletions
diff --git a/Source/PuzzlerSerializer.cpp b/Source/PuzzlerSerializer.cpp index 8ab1649..abdfafd 100644 --- a/Source/PuzzlerSerializer.cpp +++ b/Source/PuzzlerSerializer.cpp
@@ -95,7 +95,7 @@ void PuzzleSerializer::ReadExtras(Puzzle& p) {
95 p.grid[x][y].start = true; 95 p.grid[x][y].start = true;
96 } 96 }
97 p.grid[x][y].dot = FlagsToDot(flags); 97 p.grid[x][y].dot = FlagsToDot(flags);
98 if (flags & Flags::IS_FULL_GAP) { 98 if (flags & Flags::HAS_NO_CONN) {
99 p.grid[x][y].gap = Cell::Gap::FULL; 99 p.grid[x][y].gap = Cell::Gap::FULL;
100 } 100 }
101 } 101 }
@@ -175,15 +175,13 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
175 // Grided intersections 175 // Grided intersections
176 for (int y=p.height-1; y>=0; y-=2) { 176 for (int y=p.height-1; y>=0; y-=2) {
177 for (int x=0; x<p.width; x+=2) { 177 for (int x=0; x<p.width; x+=2) {
178 _intersectionLocations.push_back(MIN + (x/2) * WIDTH_INTERVAL); 178 auto [xPos, yPos] = xy_to_pos(p, x, y);
179 _intersectionLocations.push_back(MAX - (y/2) * HEIGHT_INTERVAL); 179 _intersectionLocations.push_back(xPos);
180 _intersectionLocations.push_back(yPos);
180 int flags = 0; 181 int flags = 0;
181 if (p.grid[x][y].start) { 182 if (p.grid[x][y].start) {
182 flags |= Flags::IS_STARTPOINT; 183 flags |= Flags::IS_STARTPOINT;
183 } 184 }
184 if (p.grid[x][y].gap == Cell::Gap::FULL) {
185 flags |= Flags::IS_FULL_GAP;
186 }
187 switch (p.grid[x][y].dot) { 185 switch (p.grid[x][y].dot) {
188 case Cell::Dot::BLACK: 186 case Cell::Dot::BLACK:
189 flags |= Flags::HAS_DOT; 187 flags |= Flags::HAS_DOT;
@@ -201,15 +199,15 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
201 199
202 int numConnections = 0; 200 int numConnections = 0;
203 if (p.grid[x][y].end != Cell::Dir::NONE) numConnections++; 201 if (p.grid[x][y].end != Cell::Dir::NONE) numConnections++;
204 // Create connections for this intersection for bottom/left only. 202 // Create connections for this intersection for top/left only.
205 // Bottom connection 203 // Top connection
206 if (y > 0 && p.grid[x][y-1].gap != Cell::Gap::FULL) { 204 if (y > 0 && p.grid[x][y-1].gap != Cell::Gap::FULL) {
207 _connectionsA.push_back(xy_to_loc(p, x, y-2)); 205 _connectionsA.push_back(xy_to_loc(p, x, y-2));
208 _connectionsB.push_back(xy_to_loc(p, x, y)); 206 _connectionsB.push_back(xy_to_loc(p, x, y));
209 flags |= Flags::HAS_VERTI_CONN; 207 flags |= Flags::HAS_VERTI_CONN;
210 numConnections++; 208 numConnections++;
211 } 209 }
212 // Top connection 210 // Bottom connection
213 if (y < p.height - 1 && p.grid[x][y+1].gap != Cell::Gap::FULL) { 211 if (y < p.height - 1 && p.grid[x][y+1].gap != Cell::Gap::FULL) {
214 flags |= Flags::HAS_VERTI_CONN; 212 flags |= Flags::HAS_VERTI_CONN;
215 numConnections++; 213 numConnections++;
@@ -226,7 +224,9 @@ void PuzzleSerializer::WriteIntersections(const Puzzle& p) {
226 flags |= Flags::HAS_HORIZ_CONN; 224 flags |= Flags::HAS_HORIZ_CONN;
227 numConnections++; 225 numConnections++;
228 } 226 }
227 if (numConnections == 0) flags |= HAS_NO_CONN;
229 if (numConnections == 1) flags |= HAS_ONE_CONN; 228 if (numConnections == 1) flags |= HAS_ONE_CONN;
229
230 _intersectionFlags.push_back(flags); 230 _intersectionFlags.push_back(flags);
231 } 231 }
232 } 232 }
@@ -268,21 +268,25 @@ void PuzzleSerializer::WriteDots(const Puzzle& p) {
268 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled. 268 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled.
269 if (p.grid[x][y].dot == Cell::Dot::NONE) continue; 269 if (p.grid[x][y].dot == Cell::Dot::NONE) continue;
270 270
271 // We need to introduce a new segment -- 271 // We need to introduce a new segment which contains this dot. Break the existing segment, and add one.
272 // Locate the segment we're breaking 272 int connectionLocation = -1;
273 for (int i=0; i<_connectionsA.size(); i++) { 273 for (int i=0; i<_connectionsA.size(); i++) {
274 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]); 274 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]);
275 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]); 275 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]);
276 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) || 276 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) ||
277 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) { 277 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) {
278 int other_connection = _connectionsB[i]; 278 connectionLocation = i;
279 _connectionsB[i] = static_cast<int>(_intersectionFlags.size()); 279 break;
280
281 _connectionsA.push_back(other_connection);
282 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size()));
283 break;
284 } 280 }
285 } 281 }
282 if (connectionLocation == -1) continue; // @Error
283
284 // @Assume: B > A for connections. To remove, add the horiz/verti check, see gaps.
285 int other_connection = _connectionsB[connectionLocation];
286 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
287 _connectionsA.push_back(other_connection);
288 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size()));
289
286 // Add this dot to the end 290 // Add this dot to the end
287 auto [xPos, yPos] = xy_to_pos(p, x, y); 291 auto [xPos, yPos] = xy_to_pos(p, x, y);
288 _intersectionLocations.push_back(xPos); 292 _intersectionLocations.push_back(xPos);
@@ -313,11 +317,24 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) {
313 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled. 317 if (x%2 == y%2) continue; // Cells are invalid, intersections are already handled.
314 if (p.grid[x][y].gap != Cell::Gap::BREAK) continue; 318 if (p.grid[x][y].gap != Cell::Gap::BREAK) continue;
315 319
320 // We need to introduce a new segment which contains this dot. Break the existing segment, and add one.
321 int connectionLocation = -1;
322 for (int i=0; i<_connectionsA.size(); i++) {
323 auto [x1, y1] = loc_to_xy(p, _connectionsA[i]);
324 auto [x2, y2] = loc_to_xy(p, _connectionsB[i]);
325 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) ||
326 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) {
327 connectionLocation = i;
328 break;
329 }
330 }
331 if (connectionLocation == -1) continue; // @Error
332
316 auto [xPos, yPos] = xy_to_pos(p, x, y); 333 auto [xPos, yPos] = xy_to_pos(p, x, y);
317 // Reminder: Y goes from 0.0 (bottom) to 1.0 (top) 334 // Reminder: Y goes from 0.0 (bottom) to 1.0 (top)
318 if (x%2 == 0) { // Vertical gap 335 if (x%2 == 0) { // Vertical gap
319 _connectionsA.push_back(xy_to_loc(p, x, y-1)); 336 _connectionsA[connectionLocation] = xy_to_loc(p, x, y-1);
320 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); 337 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
321 _intersectionLocations.push_back(xPos); 338 _intersectionLocations.push_back(xPos);
322 _intersectionLocations.push_back(yPos + VERTI_GAP_SIZE / 2); 339 _intersectionLocations.push_back(yPos + VERTI_GAP_SIZE / 2);
323 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); 340 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN);
@@ -328,8 +345,8 @@ void PuzzleSerializer::WriteGaps(const Puzzle& p) {
328 _intersectionLocations.push_back(yPos - VERTI_GAP_SIZE / 2); 345 _intersectionLocations.push_back(yPos - VERTI_GAP_SIZE / 2);
329 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN); 346 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_VERTI_CONN);
330 } else if (y%2 == 0) { // Horizontal gap 347 } else if (y%2 == 0) { // Horizontal gap
331 _connectionsA.push_back(xy_to_loc(p, x-1, y)); 348 _connectionsA[connectionLocation] = xy_to_loc(p, x-1, y);
332 _connectionsB.push_back(static_cast<int>(_intersectionFlags.size())); 349 _connectionsB[connectionLocation] = static_cast<int>(_intersectionFlags.size());
333 _intersectionLocations.push_back(xPos - HORIZ_GAP_SIZE / 2); 350 _intersectionLocations.push_back(xPos - HORIZ_GAP_SIZE / 2);
334 _intersectionLocations.push_back(yPos); 351 _intersectionLocations.push_back(yPos);
335 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN); 352 _intersectionFlags.push_back(Flags::HAS_ONE_CONN | Flags::HAS_HORIZ_CONN);
@@ -422,8 +439,8 @@ int PuzzleSerializer::xy_to_dloc(const Puzzle& p, int x, int y) const {
422 439
423std::tuple<float, float> PuzzleSerializer::xy_to_pos(const Puzzle& p, int x, int y) const { 440std::tuple<float, float> PuzzleSerializer::xy_to_pos(const Puzzle& p, int x, int y) const {
424 return { 441 return {
425 MIN + (x/2) * WIDTH_INTERVAL, 442 MIN + (x/2.0f) * WIDTH_INTERVAL,
426 MAX - (y/2) * HEIGHT_INTERVAL 443 MAX - (y/2.0f) * HEIGHT_INTERVAL
427 }; 444 };
428} 445}
429 446