No release in over 3 years
Low commit activity in last 3 years
Puzzle Runner for Mumuki
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

~> 2.35
 Project Readme

Stories in Ready Build Status Code Climate Test Coverage

mumuki-puzzle-runner

Install the server

bundle install

Run the server

RACK_ENV=development rackup -p 4567

Updating the docs

You will need instaling jsdoc-to-markdown first

npm install --global jsdoc-to-markdown
jsdoc2md lib/public/js/muzzle.js 2>&1

Live examples

You can see live examples here 🎊

Test format

Basic puzzle

// standard basic puzzle
Muzzle.basic(3, 2, 'https://flbulgarelli.github.io/headbreaker/static/berni.jpg');

// standard basic puzzle, but forcing submit button to show off
Muzzle.simple = false;
Muzzle.basic(3, 2, 'https://flbulgarelli.github.io/headbreaker/static/berni.jpg');

// standard basic puzzle, but forcing puzzle aspect ratio to be keep
// instead of being calculated to make it squared
Muzzle.aspectRatio = 1;
Muzzle.basic(1, 2, 'https://flbulgarelli.github.io/headbreaker/static/berni.jpg');

// standard basic puzzle, but using triangle-like inserts
Muzzle.spiky = true;
Muzzle.basic(1, 2, 'https://flbulgarelli.github.io/headbreaker/static/berni.jpg');

Match-pairs puzzle

const baseUrl = 'https://raw.githubusercontent.com/MumukiProject/mumuki-guia-gobstones-alternativa-kids/master/assets/attires/';

// with left and right pieces
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
  `${baseUrl}/chips_poco.png`
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
  `${baseUrl}/chips_mucho.png`,
]);

// like the previous one, but forcing submit button to hide
Muzzle.simple = true;
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
  `${baseUrl}/chips_poco.png`
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
  `${baseUrl}/chips_mucho.png`,
]);

// with left and right pieces, and left odd pieces
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
  `${baseUrl}/chips_poco.png`
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
  `${baseUrl}/chips_mucho.png`,
], {
  leftOddUrls: [ `${baseUrl}/choc_mitad_vacio2.png` ]
});

// with left and right pieces, and right odd pieces
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
  `${baseUrl}/chips_poco.png`
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
  `${baseUrl}/chips_mucho.png`,
], {
  rightOddUrls: [ `${baseUrl}/choc_mitad_vacio2.png` ]
});

// using a different aspect ratio for right pieces
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
  `${baseUrl}/chips_poco.png`
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
  `${baseUrl}/chips_mucho.png`,
], {
  rightAspectRatio: 2
});

// using a different shuffler
Muzzle.shuffler = Muzzle.Shuffler.line;
Muzzle.match([
  `${baseUrl}/va_vacio.png`,
  `${baseUrl}/cu_vacio.png`,
], [
  `${baseUrl}/va_fru.png`,
  `${baseUrl}/cu_vai.png`,
], {
  leftOddUrls: [ `${baseUrl}/choc_mitad_vacio2.png`, `${baseUrl}/chips_poco.png` ],
});

Choose puzzle

const baseUrl = 'https://raw.githubusercontent.com/MumukiProject/mumuki-guia-gobstones-primeros-programas-kinder-2/master/assets/';
// left pieces are 1:2 (0.5) and right pieces are 1:1 (1)
Muzzle.aspectRatio = 0.5;
Muzzle.choose(
  `${baseUrl}/match12_prog_si_1606331704226.svg`,
  `${baseUrl}/match12_tab_1606331726883.svg`,
  [ `${baseUrl}/match12_prog_no_1606331627470.svg`, ],
  1);

Solution format

The solution accepted by this runner is a JSON string with the following format:

{
  "positions": [
    [10, 20],
    [15, 20],
    [20, 20],
    [10, 25],
    [15, 25],
    [20, 25]
  ]
}:

Muzzle API 💪

Classes

MuzzleCanvas

Facade for referencing and creating a global puzzle canvas, handling solutions persistence and submitting them

Functions

another(id) ⇒ MuzzleCanvas

Creates a suplementary canvas at the element of the given id

Typedefs

Point : Array.<number>
Solution : object

MuzzleCanvas

Facade for referencing and creating a global puzzle canvas, handling solutions persistence and submitting them

Kind: global class

  • MuzzleCanvas
    • .canvasId : string
    • .expectedRefsAreOnlyDescriptive : boolean
    • .canvasWidth : number
    • .canvasHeight : number
    • .fixedDimensions : boolean
    • .borderFill : number
    • .strokeWidth : number
    • .pieceSize : number
    • .aspectRatio : number
    • .fitImagesVertically : boolean
    • .manualScale
    • .shuffler
    • .previousSolutionContent : string
    • .simple : boolean
    • .referenceInsertAxis : Axis
    • .baseConfig
    • .outlineConfig
    • .adjustedPieceSize ⇒ Vector
    • .imageAdjustmentAxis : Axis
    • .effectiveAspectRatio : number
    • .canvas ⇒ Canvas
    • .solution ⇒ Solution
    • .solutionContent
    • .clientResultStatus ⇒ "passed" | "failed"
    • .onReady()
    • .onSubmit(submission)
    • .onValid()
    • .draw()
    • .expect(refs)
    • .basic(x, y, imagePath) ⇒ Promise.<Canvas>
    • .choose(leftUrl, rightUrl, leftOddUrls, [rightAspectRatio]) ⇒ Promise.<Canvas>
    • .match(leftUrls, rightUrls, [options]) ⇒ Promise.<Canvas>
    • .custom(canvas) ⇒ Promise.<Canvas>
    • .scale(width, height)
    • .focus()
    • .ready()
    • .loadSolution(solution)
    • .loadPreviousSolution()
    • .resetCoordinates()
    • .submit()
    • ._config(key, value)
    • .register(event)
    • .run()

muzzleCanvas.canvasId : string

The id of the HTML element that will contain the canvas Override it you are going to place in a non-standard way

Kind: instance property of MuzzleCanvas

muzzleCanvas.expectedRefsAreOnlyDescriptive : boolean

Wether expected refs shall be ignored by Muzzle.

They will still be evaluated server-side.

Kind: instance property of MuzzleCanvas

muzzleCanvas.canvasWidth : number

Width of canvas

Kind: instance property of MuzzleCanvas

muzzleCanvas.canvasHeight : number

Height of canvas

Kind: instance property of MuzzleCanvas

muzzleCanvas.fixedDimensions : boolean

Wether canvas shoud not be resized. Default is false

Kind: instance property of MuzzleCanvas

muzzleCanvas.borderFill : number

Size of fill. Set null for perfect-match

Kind: instance property of MuzzleCanvas

muzzleCanvas.strokeWidth : number

Canvas line width

Kind: instance property of MuzzleCanvas

muzzleCanvas.pieceSize : number

Piece size

Kind: instance property of MuzzleCanvas

muzzleCanvas.aspectRatio : number

The x:y aspect ratio of the piece. Set null for automatic aspectRatio

Kind: instance property of MuzzleCanvas

muzzleCanvas.fitImagesVertically : boolean

If the images should be adjusted vertically instead of horizontally to puzzle dimensions.

Set null for automatic fit.

Kind: instance property of MuzzleCanvas

muzzleCanvas.manualScale

Wether the scaling should ignore the scaler rise events

Kind: instance property of MuzzleCanvas

muzzleCanvas.shuffler

The canvas shuffler.

Set it null to automatic shuffling algorithm selection.

Kind: instance property of MuzzleCanvas

muzzleCanvas.previousSolutionContent : string

The previous solution to the current puzzle in a past session, if any

Kind: instance property of MuzzleCanvas

muzzleCanvas.simple : boolean

Whether the current puzzle can be solved in very few tries.

Set null for automatic configuration of this property. Basic puzzles will be considered basic and match puzzles will be considered non-simple.

Kind: instance property of MuzzleCanvas

muzzleCanvas.referenceInsertAxis : Axis

The reference insert axis, used at rounded outline to compute insert internal and external diameters

Set null for default computation of axis - no axis reference for basic boards and vertical axis for match

Kind: instance property of MuzzleCanvas

muzzleCanvas.baseConfig

Kind: instance property of MuzzleCanvas

muzzleCanvas.outlineConfig

Kind: instance property of MuzzleCanvas

muzzleCanvas.adjustedPieceSize ⇒ Vector

The piece size, adjusted to the aspect ratio

Kind: instance property of MuzzleCanvas

muzzleCanvas.imageAdjustmentAxis : Axis

Kind: instance property of MuzzleCanvas

muzzleCanvas.effectiveAspectRatio : number

The configured aspect ratio, or 1

Kind: instance property of MuzzleCanvas

muzzleCanvas.canvas ⇒ Canvas

The currently active canvas, or null if it has not yet initialized

Kind: instance property of MuzzleCanvas

muzzleCanvas.solution ⇒ Solution

The state of the current puzzle expressed as a Solution object

Kind: instance property of MuzzleCanvas

muzzleCanvas.solutionContent

The current solution, expressed as a JSON string

Kind: instance property of MuzzleCanvas

muzzleCanvas.clientResultStatus ⇒ "passed" | "failed"

The solution validation status

Kind: instance property of MuzzleCanvas

muzzleCanvas.onReady()

Callback that will be executed when muzzle has fully loaded and rendered its first canvas.

It does nothing by default but you can override this property with any code you need the be called here

Kind: instance method of MuzzleCanvas

muzzleCanvas.onSubmit(submission)

Callback to be executed when submitting puzzle.

Does nothing by default but you can override it to perform additional actions

Kind: instance method of MuzzleCanvas

Param Type
submission Object

muzzleCanvas.onValid()

Callback that will be executed when muzzle's puzzle becomes valid

It does nothing by default but you can override this property with any code you need the be called here

Kind: instance method of MuzzleCanvas

muzzleCanvas.draw()

Draws the - previusly built - current canvas.

Prefer this.currentCanvas.redraw() when performing small updates to the pieces.

Kind: instance method of MuzzleCanvas

muzzleCanvas.expect(refs)

Kind: instance method of MuzzleCanvas

Param Type
refs Array.<Point>

muzzleCanvas.basic(x, y, imagePath) ⇒ Promise.<Canvas>

Creates a basic puzzle canvas with a rectangular shape and a background image, that is automatically submitted when solved

Kind: instance method of MuzzleCanvas Returns: Promise.<Canvas> - the promise of the built canvas

Param Type Description
x number the number of horizontal pieces
y number the number of vertical pieces
imagePath string

muzzleCanvas.choose(leftUrl, rightUrl, leftOddUrls, [rightAspectRatio]) ⇒ Promise.<Canvas>

Creates a choose puzzle, where a single right piece must match the single left piece, choosing the latter from a bunch of other left odd pieces. By default, Muzzle.Shuffler.line shuffling is used.

This is a particular case of a match puzzle with line

Kind: instance method of MuzzleCanvas Returns: Promise.<Canvas> - the promise of the built canvas

Param Type Default Description
leftUrl string the url of the left piece
rightUrl string the url of the right piece
leftOddUrls Array.<string> the urls of the off left urls
[rightAspectRatio] number the x:y ratio of the right pieces, that override the general aspectRatio of the puzzle. Use null to have the same aspect ratio as left pieces

muzzleCanvas.match(leftUrls, rightUrls, [options]) ⇒ Promise.<Canvas>

Creates a match puzzle, where left pieces are matched against right pieces, with optional odd left and right pieces that don't match. By default, Muzzle.Shuffler.columns shuffling is used.

Kind: instance method of MuzzleCanvas Returns: Promise.<Canvas> - the promise of the built canvas

Param Type Description
leftUrls Array.<string>
rightUrls Array.<string> must be of the same size of lefts
[options] object
[options.leftOddUrls] Array.<string>
[options.rightOddUrls] Array.<string>
[options.rightAspectRatio] number the aspect ratio of the right pieces. Use null to have the same aspect ratio as left pieces

muzzleCanvas.custom(canvas) ⇒ Promise.<Canvas>

Kind: instance method of MuzzleCanvas Returns: Promise.<Canvas> - the promise of the built canvas

Param Type
canvas Canvas

muzzleCanvas.scale(width, height)

Scales the canvas to the given width and height

Kind: instance method of MuzzleCanvas

Param Type
width number
height number

muzzleCanvas.focus()

Focuses the stage around the canvas center

Kind: instance method of MuzzleCanvas

muzzleCanvas.ready()

Mark Muzzle as ready, loading previous solution and drawing the canvas

Kind: instance method of MuzzleCanvas

muzzleCanvas.loadSolution(solution)

Loads - but does not draw - a solution into the canvas.

Kind: instance method of MuzzleCanvas

Param Type
solution Solution

muzzleCanvas.loadPreviousSolution()

Loads - but does not draw - the current canvas with the previous solution, if available.

Kind: instance method of MuzzleCanvas

muzzleCanvas.resetCoordinates()

Translates the pieces so that they start at canvas' coordinates origin

Kind: instance method of MuzzleCanvas

muzzleCanvas.submit()

Submits the puzzle to the bridge, validating it if necessary

Kind: instance method of MuzzleCanvas

muzzleCanvas._config(key, value)

Kind: instance method of MuzzleCanvas

Param Type
key string
value any

muzzleCanvas.register(event)

Registers an event handler

Kind: instance method of MuzzleCanvas

Param Type
event string

muzzleCanvas.run()

Runs the given action if muzzle is ready, queueing it otherwise

Kind: instance method of MuzzleCanvas

another(id) ⇒ MuzzleCanvas

Creates a suplementary canvas at the element of the given id

Kind: global function

Param Type
id string

Point : Array.<number>

Kind: global typedef

Solution : object

Kind: global typedef Properties

Name Type Description
positions Array.<Point> list of points