From bec6f657f405cb27939ec42ae35c0cc9d524bbb9 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 1 Nov 2023 18:07:04 -0400 Subject: invisible symmetry! --- app/assets/javascripts/wittle/puzzle.js | 5 ++++- app/assets/javascripts/wittle/serializer.js | 3 +++ app/assets/javascripts/wittle/trace2.js | 23 ++++++++++++++++++----- app/assets/javascripts/wittle/utilities.js.erb | 4 ++++ ext/wittle_generator/Generate.cpp | 4 ++++ ext/wittle_generator/Panel.cpp | 10 +++++++--- ext/wittle_generator/Panel.h | 3 +++ ext/wittle_generator/Serializer.h | 3 ++- 8 files changed, 45 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/wittle/puzzle.js b/app/assets/javascripts/wittle/puzzle.js index a7ad10a..4d6b0fb 100644 --- a/app/assets/javascripts/wittle/puzzle.js +++ b/app/assets/javascripts/wittle/puzzle.js @@ -35,9 +35,12 @@ window.Puzzle = class { // If true, custom mechanics are displayed (and validated) in this puzzle. CUSTOM_MECHANICS: false, - + // If true, polyominos may be placed partially off of the grid as an intermediate solution step. // OUT_OF_BOUNDS_POLY: false, + + // If true, the symmetry line will be invisible. + INVISIBLE_SYMMETRY: false, } } diff --git a/app/assets/javascripts/wittle/serializer.js b/app/assets/javascripts/wittle/serializer.js index e440569..1598d9b 100644 --- a/app/assets/javascripts/wittle/serializer.js +++ b/app/assets/javascripts/wittle/serializer.js @@ -43,6 +43,7 @@ window.serializePuzzle = function(puzzle) { if (puzzle.settings.FLASH_FOR_ERRORS) settingsFlags |= SETTINGS_FLAG_FFE if (puzzle.settings.FAT_STARTPOINTS) settingsFlags |= SETTINGS_FLAG_FS if (puzzle.settings.CUSTOM_MECHANICS) settingsFlags |= SETTINGS_FLAG_CM + if (puzzle.settings.INVISIBLE_SYMMETRY) settingsFlags |= SETTINGS_FLAG_IS s.writeByte(settingsFlags) return s.str() @@ -93,6 +94,7 @@ window.deserializePuzzle = function(data) { FLASH_FOR_ERRORS: (settingsFlags & SETTINGS_FLAG_FFE) != 0, FAT_STARTPOINTS: (settingsFlags & SETTINGS_FLAG_FS) != 0, CUSTOM_MECHANICS: (settingsFlags & SETTINGS_FLAG_CM) != 0, + INVISIBLE_SYMMETRY: (settingsFlags & SETTINGS_FLAG_IS) != 0, } s.destroy() @@ -342,5 +344,6 @@ var SETTINGS_FLAG_PP = 4 var SETTINGS_FLAG_FFE = 8 var SETTINGS_FLAG_FS = 16 var SETTINGS_FLAG_CM = 32 +var SETTINGS_FLAG_IS = 64 }) diff --git a/app/assets/javascripts/wittle/trace2.js b/app/assets/javascripts/wittle/trace2.js index 01e4ccd..7a77564 100644 --- a/app/assets/javascripts/wittle/trace2.js +++ b/app/assets/javascripts/wittle/trace2.js @@ -138,10 +138,18 @@ class PathSegment { data.svg.insertBefore(this.symCirc, data.cursor) data.svg.insertBefore(this.symPoly2, data.cursor) data.svg.insertBefore(this.symPillarCirc, data.cursor) - this.symPoly1.setAttribute('class', 'line-3 ' + data.svg.id) - this.symCirc.setAttribute('class', 'line-3 ' + data.svg.id) - this.symPoly2.setAttribute('class', 'line-3 ' + data.svg.id) - this.symPillarCirc.setAttribute('class', 'line-3 ' + data.svg.id) + + if (data.puzzle.settings.INVISIBLE_SYMMETRY) { + this.symPoly1.setAttribute('class', 'line-4 ' + data.svg.id) + this.symCirc.setAttribute('class', 'line-4 ' + data.svg.id) + this.symPoly2.setAttribute('class', 'line-4 ' + data.svg.id) + this.symPillarCirc.setAttribute('class', 'line-4 ' + data.svg.id) + } else { + this.symPoly1.setAttribute('class', 'line-3 ' + data.svg.id) + this.symCirc.setAttribute('class', 'line-3 ' + data.svg.id) + this.symPoly2.setAttribute('class', 'line-3 ' + data.svg.id) + this.symPillarCirc.setAttribute('class', 'line-3 ' + data.svg.id) + } this.symCirc.setAttribute('cx', data.symbbox.middle.x) this.symCirc.setAttribute('cy', data.symbbox.middle.y) @@ -345,6 +353,7 @@ function clearGrid(svg, puzzle) { window.deleteElementsByClassName(svg, 'line-1') window.deleteElementsByClassName(svg, 'line-2') window.deleteElementsByClassName(svg, 'line-3') + window.deleteElementsByClassName(svg, 'line-4') puzzle.clearLines() } @@ -506,7 +515,11 @@ window.onTraceStart = function(puzzle, pos, svg, start, symStart=null) { data.symcursor = createElement('circle') svg.insertBefore(data.symcursor, data.cursor) - data.symcursor.setAttribute('class', 'line-3 ' + data.svg.id) + if (data.puzzle.settings.INVISIBLE_SYMMETRY) { + data.symcursor.setAttribute('class', 'line-4 ' + data.svg.id) + } else { + data.symcursor.setAttribute('class', 'line-3 ' + data.svg.id) + } data.symcursor.setAttribute('cx', symStart.getAttribute('cx')) data.symcursor.setAttribute('cy', symStart.getAttribute('cy')) data.symcursor.setAttribute('r', 12) diff --git a/app/assets/javascripts/wittle/utilities.js.erb b/app/assets/javascripts/wittle/utilities.js.erb index 487af6e..6bf3a17 100644 --- a/app/assets/javascripts/wittle/utilities.js.erb +++ b/app/assets/javascripts/wittle/utilities.js.erb @@ -153,6 +153,10 @@ l('.line-3 {') l(' fill: ' + window.LINE_SECONDARY + ';') l(' pointer-events: none;') l('}') +l('.line-4 {') +l(' display: none;') +l(' pointer-events: none;') +l('}') l('@keyframes line-success {to {fill: ' + window.LINE_SUCCESS + ';}}') l('@keyframes line-fail {to {fill: ' + window.LINE_FAIL + ';}}') l('@keyframes error {to {fill: red;}}') diff --git a/ext/wittle_generator/Generate.cpp b/ext/wittle_generator/Generate.cpp index ed5f2f5..a5c0af9 100644 --- a/ext/wittle_generator/Generate.cpp +++ b/ext/wittle_generator/Generate.cpp @@ -136,6 +136,10 @@ void Generate::initPanel() { if (pathWidth != 1) _panel->pathWidth = pathWidth; // Init path scale. "1" is considered the // default, and therefore means no change. + + if (hasFlag(Config::WriteInvisible)) { + _panel->SetInvisibleSymmetry(true); + } } // Place a specific symbol into the puzzle at the specified location. The diff --git a/ext/wittle_generator/Panel.cpp b/ext/wittle_generator/Panel.cpp index 892d4cc..879d205 100644 --- a/ext/wittle_generator/Panel.cpp +++ b/ext/wittle_generator/Panel.cpp @@ -225,9 +225,13 @@ std::string Panel::Write() { } serializer.writeInt(0); - serializer.writeByte(Serializer::NegationsCancelNegations | - Serializer::PrecisePolyominos | - Serializer::FlashForErrors); + + char settings = Serializer::NegationsCancelNegations | + Serializer::PrecisePolyominos | Serializer::FlashForErrors; + if (_invisible_symmetry) { + settings |= Serializer::InvisibleSymmetry; + } + serializer.writeByte(settings); return serializer.str(); } diff --git a/ext/wittle_generator/Panel.h b/ext/wittle_generator/Panel.h index b8dec2f..95832b5 100644 --- a/ext/wittle_generator/Panel.h +++ b/ext/wittle_generator/Panel.h @@ -169,6 +169,8 @@ class Panel { int get(int x, int y) { return _grid[x][y]; } void set(int x, int y, int val) { _grid[x][y] = val; } + void SetInvisibleSymmetry(bool val) { _invisible_symmetry = val; } + std::string Write(); enum Style { @@ -447,6 +449,7 @@ class Panel { float minx, miny, maxx, maxy, unitWidth, unitHeight; int _style; bool _resized; + bool _invisible_symmetry = false; }; #endif /* end of include guard: PANEL_H_FC471D68 */ diff --git a/ext/wittle_generator/Serializer.h b/ext/wittle_generator/Serializer.h index 86b262d..6eeb887 100644 --- a/ext/wittle_generator/Serializer.h +++ b/ext/wittle_generator/Serializer.h @@ -56,7 +56,8 @@ class Serializer { PrecisePolyominos = 4, FlashForErrors = 8, FatStartpoints = 16, - CustomMechanics = 32 + CustomMechanics = 32, + InvisibleSymmetry = 64, }; enum GapType : char { GapNone = 0, GapBreak = 1, GapFull = 2 }; -- cgit 1.4.1