[Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
Clear Puzzle by Color
Forum Index -> Bugs & Suggestions
Author Message

Joined: 16/06/2010 21:53:53
Messages: 10

Having multiple colors is great for sketching out options in puzzles, but when a guess fails I find myself carefully clicking all cells of a single color with the eraser. Sometimes I find myself using the "Clear" button and adding back in my knowns as it is easier than erasing the other parts.

It would be nice if we had a way to clear all entered items of only a certain color.

Perhaps another row of buttons a bit further down from the color selection, ones to "Erase all Blue", "Erase all Red", "Erase all Green", etc.
(I wanted to attach a file of a "Highly professional artist rendition of one possible implementation", but the Limit of files to attach is showing as 0. Bonus bug report?)


Love this site, coming up on my 10 year anniversary since joining this April 21st. Thought it was time to put forth a suggestion I long had in mind.

Joined: 11/11/2015 18:26:16
Messages: 165

This functionality would be really, really useful!

I'm not sure there's actually anyone tending/developing the site right now, but if that changes this is a feature that I would love to see.

I'm not sure the suggested approach (an additional set of buttons) is the right implementation - it would add a lot of clutter and possibly be quite confusing - so some thought should be given to work out the right interface. However, if this could be implemented in some manner, it would be great. Shift-click the buttons, maybe?

Joined: 16/06/2010 21:53:53
Messages: 10

I realize there may not be much attention to the site, but wanted to share my love in case that helps rekindles someone's passion for this lovely picnic.

Since I couldn't attach the image, I'll post a link to a free host of it here:
"Highly Professional Artist Rendition of one possible implementation." - Isfan, 2020

My general idea is you click the colored eraser underneath the matching color, then you can click "Clear" to erase just the drawings of that color instead of the whole puzzle.

I'd be interested in your thoughts on it, HappyDog. Does this still look too cluttered from what you had in mind?
(Or just a new button "Clear Color" which acts on only the active color was my 2nd idea on it)

Joined: 11/11/2015 18:26:16
Messages: 165

It's a bit cluttered, but it could be done neatly. However, I think the chances of accidentally hitting the erase button instead of the colour select button would be pretty high.

My suggestion would be: When you press the 'erase' button it toggles to a 'selected' state and all the colour-select icons turn into coloured erasers, like in your high-definition mock-up. Clicking one of these clears all of that colour but otherwise the eraser brush acts as it does now (e.g. to delete items in the grid).

To go back to drawing mode, click the eraser again, to disable it. This will automatically return you to whatever colour you had selected previously.

Joined: 16/06/2010 21:53:53
Messages: 10

I like that idea! Though I can just as easily see myself accidentally clearing out a color when using the eraser because I forgot to toggle it off before trying to switch back to blue.

Just a quick clarification: I was not suggesting the colored erasers clear out the associated color automatically, rather that they change the functionality of the "Clear" button to only affect the selected eraser color when one is selected. Serving as a confirmation button of sorts.
Perhaps the Clear button could be adapted as well. Defaulting to "Clear All", and changing to "Clear [Color name]" once the [matching Color] Eraser is selected.

Will be interesting to see how this gets implemented if anyone ever takes up the mantle for it.

Joined: 11/11/2015 18:26:16
Messages: 165

I see what you're suggesting. Erasers that work as usual but only delete one colour would definitely be useful, but for me a 'clear all of colour X' button would be the more useful of the two.

I take your point about accidentally clearing when you meant to change colour. A confirmation box might be enough to resolve that.

Either way, some UI/UX design work should be done before implementing anything.

Joined: 16/06/2010 21:53:53
Messages: 10

HappyDog wrote:
I see what you're suggesting. Erasers that work as usual but only delete one colour would definitely be useful, but for me a 'clear all of colour X' button would be the more useful of the two.

That actually was not what I was suggesting at all, but I like the idea of it as well! It would also wrap into the layout of the high-definition mock-up seamlessly.

Again, the suggestion is:
Select the colored eraser, then click on the "Clear" button to have only drawings of that color erased (leaving the other colors untouched). Clicking on "Clear" without a colored eraser selected would clear the whole puzzle, as per usual.

Making the colored erasers work at the same time as a usual eraser, but only for the matching color, would be added functionality and convenience without changing the original premise. I'm officially adding that to my suggestion! :3

Joined: 01/12/2011 11:39:39
Messages: 109

I happened to find out that the functionality is already implemented: there is a function that erases a certain colour. If I remember correctly (sorry, it was years ago) I even sent Thierry a patch that experimentally opened extra buttons from clicking Clear. At the same time it served as a confirmation, because now Clear is very dangerous. Actually I've hidden it with my uBlock.

Anyway, at that time Thierry was getting even busier with out-of-site life, so I guess this has been buried completely.

Joined: 11/11/2015 18:26:16
Messages: 165

That's a much better suggestion, actually.

When you press 'clear' it should pop up a box to "Clear All", "Clear Red", etc. and the option to cancel.

That would kill two birds with one stone.

Shame, JHe, that your patch wasn't accepted. Is it a JavaScript only patch? If so, is it something that individual users could run locally, e.g. via Greasemonkey?

I wonder if Thierry could be persuaded to let other people work on the code, directly? I would certainly be happy to do some small-scale enhancements like this (I am a professional programmer).

Joined: 01/12/2011 11:39:39
Messages: 109

The patch was JavaScript and some minor addition to the HTML. Here they are pasted, since attachment seems to be a problem.


<!DOCTYPE html>
<title>Puzzlepicnic Interactive Puzzle</title>
<link rel="stylesheet" href="./puzzle.css">

<script src='downloaded/kinetic-v5.0.1.js'></script>
<script src='downloaded/jquery-2.1.0.js'></script>
<script src='fake-puzzle-backend.js'></script>
<script src="src/impl/bounding-box.js"></script>
<script src="src/impl/puzzle-model-helper.js"></script>
<script src="src/impl/kinetic/shape-painter.js"></script>
<script src="src/impl/kinetic/puzzle-view-part.js"></script>
<script src="src/impl/kinetic/puzcode-element-painter.js"></script>
<script src="src/impl/puzzle-state.js"></script>
<script src="src/impl/reporter.js"></script>
<script src="src/impl/storage.js"></script>
<script src='src/impl/model/shape-modifiers.js'></script>
<script src='src/impl/model/shape-factory.js'></script>
<script src='src/impl/puzzle-model-search.js'></script>
<script src='src/impl/puzzle-model.js'></script>
<script src='src/impl/puzzle-presenter.js'></script>
<script src='src/impl/puzzle-action-listener.js'></script>
<script src='src/impl/puzzle-action-engine.js'></script>
<script src='src/impl/user-activity-view-event-handler.js'></script>
<script src='src/impl/user-activity-listener.js'></script>
<script src='src/impl/kinetic/stage-factory.js'></script>
<script src='src/impl/kinetic/interactive-puzzle-view.js'></script>
<script src='src/impl/pencil-colors.js'></script>
<script src='src/impl/kinetic/shapes-view.js'></script>
<script src='src/api/interactive-puzzle.js'></script>
<script src='src/impl/interactive-puzzle-controls.js'></script>
<h2>Interactive Puzzle</h2>
<div id="pp-canvas-container"></div>
<div id="pp-reveal" class="hide"></div>
<div id="pp-clear" class="hide">
<big>Erase which colours?</big>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(0)"><img src="public/images/pp-canvas/blue.png" alt="Blue"></button>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(1)"><img src="public/images/pp-canvas/red.png" alt="Red"></button>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(2)"><img src="public/images/pp-canvas/green.png" alt="Green"></button>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(3)"><img src="public/images/pp-canvas/orange.png" alt="Orange"></button>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(4)"><img src="public/images/pp-canvas/purple.png" alt="Purple"></button>
<button type="button" class="imgbutton" onclick="puzzle.clearPencilColor(5)"><img src="public/images/pp-canvas/grey.png" alt="Grey"></button>
<button type="button" onclick="presenter.clearAll()">Clear all</button>
<button type="button" onclick="$('#pp-clear').addClass('hide'); $('#pp-canvas-controls').removeClass('hide');">Exit/Stop/Ready/Done</button>

<button id="puzzleCorrectAlert" onclick="controls.hideCorrect()" class="hide puzzlealert">Congratulations! You have correctly solved the puzzle.</button>
<button id="puzzleIncorrectAlert" onclick="controls.hideIncorrect()" class="hide puzzlealert">The solution to the puzzle is incorrect. Please try again.</button>
<div id="pp-canvas-controls">
<button type="button" onclick="puzzle.clear()">Clear</button>
<button type="button" onclick="controls.check()">Check</button>
<button type="button" onclick="puzzle.reveal()">Reveal</button>
<button type="button" id="pencil0" class="imgbutton" onmousedown="controls.changePencilColor(0)"><img src="public/images/pp-canvas/blue.png" alt="Blue"></button>
<button type="button" id="pencil1" class="imgbutton" onmousedown="controls.changePencilColor(1)"><img src="public/images/pp-canvas/red.png" alt="Red"></button>
<button type="button" id="pencil2" class="imgbutton" onmousedown="controls.changePencilColor(2)"><img src="public/images/pp-canvas/green.png" alt="Green"></button>
<button type="button" id="pencil3" class="imgbutton" onmousedown="controls.changePencilColor(3)"><img src="public/images/pp-canvas/orange.png" alt="Orange"></button>
<button type="button" id="pencil4" class="imgbutton" onmousedown="controls.changePencilColor(4)"><img src="public/images/pp-canvas/purple.png" alt="Purple"></button>
<button type="button" id="pencil5" class="imgbutton" onmousedown="controls.changePencilColor(5)"><img src="public/images/pp-canvas/grey.png" alt="Grey"></button>
<button type="button" id="eraser" class="imgbutton" onmousedown="controls.takeEraserInHand()"><img src="public/images/pp-canvas/eraser.png" alt="Eraser"></button>

<!-- Scripts for testing locally -->
<!-- All example puzzles -->
<script src='spokes-example.js'></script>
<script src='path-example.js'></script>
<script src='small-example.js'></script>
<script src='battleships-example.js'></script>
<script src="all-shapes-example.js"></script>

<script src='bootstrap-interactive-puzzle.js'></script>

And the relevant code in JS:

InteractivePuzzle = function (gencode, puzcode, width, height, targetDomElementName, puzzleId,pencilColors) {
var start = new Date().getTime();
var modelHelper = new PuzzleModelHelper();
var shapePainter = new ShapePainter();

var puzzleState = new PuzzleState();
var reporter = new Reporter(puzzleId);
var storage = new PuzzleStorage(puzzleId);
var puzzleActionListener;

var shapeFactory = new ShapeFactory(pencilColors.defaultPencilColorId);
var shapeModifiers = new ShapeModifiers();
var puzzleModelSearch = new PuzzleModelSearch(gencode, puzcode, shapeModifiers, shapeFactory);
var model = new PuzzleModel(pencilColors.defaultPencilColorId, puzzleModelSearch, modelHelper);
var userActivityListener = new UserActivityListener(model, reporter, storage);
var viewEventHandler = {
handleLeftMouseDown: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleLeftMouseDown(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleRightMouseDown: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleRightMouseDown(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleTouchStart: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleTouchStart(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleTouchMove: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleTouchMove(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleTouchEnd: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleTouchEnd(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleLeftMouseUp: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleLeftMouseUp(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleRightMouseUp: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleRightMouseUp(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleMouseEnter: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleMouseEnter(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
handleMouseLeave: function (dynamicId, leftMouseShapesGroup, rightMouseShapesGroup) {
puzzleActionListener.handleMouseLeave(dynamicId, leftMouseShapesGroup, rightMouseShapesGroup);
var userActivityHandler = new UserActivityViewEventHandler(userActivityListener);
var viewEventHandlers = [viewEventHandler, userActivityHandler];
var puzcodeElementPainter = new PuzcodeElementPainter(shapePainter);
var puzzleViewPart = new PuzzleViewPart(puzcodeElementPainter, shapePainter, modelHelper, viewEventHandlers);
var stageFactory = new StageFactory(targetDomElementName, width, height);
var shapesView = new ShapesView(modelHelper,puzcodeElementPainter,pencilColors.pencilColors);
var view = new InteractivePuzzleView(model, pencilColors.pencilColors, puzzleViewPart,stageFactory, shapesView);

var presenter = new PuzzlePresenter(view, model,userActivityListener);
var puzzleActionEngine = new PuzzleActionEngine(model, puzzleState);
puzzleActionListener = new PuzzleActionListener(view, model, puzzleActionEngine);
var backend = new PuzzleBackend(puzzleId);

if (storage.hasSavedPuzzle()) {
} else {

var end = new Date().getTime();
var time = end - start;
console.log('Rendering puzzle completed in ' + time + ' ms');

return {
check: function (solutionCorrectCallback,solutionIncorrectCallback) {
var solutionToCheck = model.generateSolutionShortCode();
var callBackWithReporting = function() {
backend.checkSolution(puzzleId, solutionToCheck,callBackWithReporting,solutionIncorrectCallback);
reveal: function () {
var puzzleCallback = function(puzzle) {
model.currentPencilColor = pencilColors.defaultPencilColorId;
backend.loadPuzzleById(puzzleId, puzzleCallback);
takeEraserInHand: function() {
changePencilColor: function (colorId) {
model.currentPencilColor = colorId;
clear: function () {
clearPencilColor: function (colorId) {

Sorry for the mess, hope you can use it. I actually installed Greasemonkey, but my concentration isn't enough nowadays to code for it.

Joined: 11/11/2015 18:26:16
Messages: 165

Thanks, JHe.

I'll have a play with it sometime and let you know if I come up with anything useful.
Forum Index -> Bugs & Suggestions
Go to:   
Powered by JForum 2.1.6 © JForum Team