mumuki-puzzle-runner 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/assets_server.rb +11 -0
- data/lib/metadata_hook.rb +35 -0
- data/lib/public/css/muzzle-editor.css +4 -0
- data/lib/public/css/muzzle.css +0 -0
- data/lib/public/js/muzzle-editor.js +65 -0
- data/lib/public/js/muzzle.js +320 -0
- data/lib/public/vendor/headbreaker.d.ts +802 -0
- data/lib/public/vendor/headbreaker.js +2 -0
- data/lib/public/vendor/headbreaker.js.map +1 -0
- data/lib/puzzle_runner.rb +10 -0
- data/lib/test_hook.rb +28 -0
- data/lib/version_hook.rb +3 -0
- metadata +138 -0
@@ -0,0 +1,802 @@
|
|
1
|
+
/**
|
2
|
+
* An Anchor is a mutable 2D point that
|
3
|
+
* is used to locate pieces and pieces inserts
|
4
|
+
*/
|
5
|
+
declare class Anchor {
|
6
|
+
constructor(x: number, y: number);
|
7
|
+
equal(other: Anchor): boolean;
|
8
|
+
isAt(x: number, y: number): boolean;
|
9
|
+
/**
|
10
|
+
* Creates a translated copy of this Anchor
|
11
|
+
* according to a vector
|
12
|
+
*/
|
13
|
+
translated(dx: number, dy: number): Anchor;
|
14
|
+
/**
|
15
|
+
* Translates this anchor given to a vector
|
16
|
+
*/
|
17
|
+
translate(dx: number, dy: number): void;
|
18
|
+
/**
|
19
|
+
* Answers whether this Anchor is near to another given a tolerance
|
20
|
+
* @param tolerance - the max distance within its radius is considered to be "close"
|
21
|
+
*/
|
22
|
+
closeTo(other: Anchor, tolerance: number): boolean;
|
23
|
+
copy(): Anchor;
|
24
|
+
/**
|
25
|
+
* Calculates the difference between this anchor and another
|
26
|
+
*/
|
27
|
+
diff(other: Anchor): Pair;
|
28
|
+
/**
|
29
|
+
* Converts this anchor into a point
|
30
|
+
*/
|
31
|
+
asPoint(): Pair;
|
32
|
+
/**
|
33
|
+
* Converts this anchor into a position
|
34
|
+
*/
|
35
|
+
asPosition(): Position;
|
36
|
+
export(): Position;
|
37
|
+
static atRandom(maxX: number, maxY: number): Anchor;
|
38
|
+
static import(position: Position): Anchor;
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Creates a new {@link Anchor}
|
43
|
+
*/
|
44
|
+
declare function anchor(x: number, y: number): Anchor;
|
45
|
+
|
46
|
+
declare type Label = any;
|
47
|
+
|
48
|
+
declare type Figure = {
|
49
|
+
shape: Shape;
|
50
|
+
group: Group;
|
51
|
+
label?: Label;
|
52
|
+
};
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @param piece - the connecting piece
|
56
|
+
* @param figure - the visual representation of the connecting piece
|
57
|
+
* @param targetPiece - the target connected piece
|
58
|
+
* @param targetFigure - the visual representation of the target connected
|
59
|
+
*/
|
60
|
+
declare type CanvasConnectionListener = (piece: Piece, figure: Figure, targetPiece: Piece, targetFigure: Figure) => void;
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @param piece - the translated piece
|
64
|
+
* @param figure - the visual representation of the translated piece
|
65
|
+
* @param dx - the horizontal displacement
|
66
|
+
* @param dy - the vertical displacement
|
67
|
+
*/
|
68
|
+
declare type CanvasTranslationListener = (piece: Piece, figure: Figure, dx: number, dy: number) => void;
|
69
|
+
|
70
|
+
declare type LabelMetadata = {
|
71
|
+
text?: string;
|
72
|
+
fontSize?: number;
|
73
|
+
x?: number;
|
74
|
+
y?: number;
|
75
|
+
};
|
76
|
+
|
77
|
+
declare type CanvasMetadata = {
|
78
|
+
id?: string;
|
79
|
+
targetPosition?: Position;
|
80
|
+
currentPosition?: Position;
|
81
|
+
color?: string;
|
82
|
+
strokeColor?: string;
|
83
|
+
image?: ImageLike;
|
84
|
+
label?: LabelMetadata;
|
85
|
+
};
|
86
|
+
|
87
|
+
declare type Template = {
|
88
|
+
structure: StructureLike;
|
89
|
+
metadata: CanvasMetadata;
|
90
|
+
};
|
91
|
+
|
92
|
+
/**
|
93
|
+
* An HTML graphical area where puzzles and pieces can be rendered. No assumption of the rendering backend is done - it may be
|
94
|
+
* and be a plain HTML SVG or canvas element, or a higher-level library - and this task is fully delegated to {@link Painter}
|
95
|
+
* @param id - the html id of the element where to place the canvas
|
96
|
+
* @param [options.borderFill] - the broder fill of the pieces, expresed in pixels. 0 means no border fill, 0.5 * pieceSize means full fill
|
97
|
+
* @param [options.lineSoftness] - how soft the line will be
|
98
|
+
* @param [options.image] - an optional background image for the puzzle that will be split across all pieces.
|
99
|
+
* @param [options.painter] - the Painter object used to actually draw figures in canvas
|
100
|
+
*/
|
101
|
+
declare class Canvas {
|
102
|
+
constructor(id: string, options: {
|
103
|
+
width: number;
|
104
|
+
height: number;
|
105
|
+
pieceSize?: number;
|
106
|
+
proximity?: number;
|
107
|
+
borderFill?: number;
|
108
|
+
strokeWidth?: number;
|
109
|
+
strokeColor?: string;
|
110
|
+
lineSoftness?: number;
|
111
|
+
image?: ImageLike;
|
112
|
+
painter?: Painter;
|
113
|
+
});
|
114
|
+
_painter: Painter;
|
115
|
+
_puzzle: Puzzle;
|
116
|
+
figures: {
|
117
|
+
[key: string]: Figure;
|
118
|
+
};
|
119
|
+
templates: {
|
120
|
+
[key: string]: Template;
|
121
|
+
};
|
122
|
+
/**
|
123
|
+
* Creates and renders a piece using a template, that is ready to be rendered by calling {@link Canvas#draw}
|
124
|
+
*/
|
125
|
+
sketchPiece(options: Template): void;
|
126
|
+
/**
|
127
|
+
* Renders a previously created piece object
|
128
|
+
*/
|
129
|
+
renderPiece(piece: Piece): void;
|
130
|
+
/**
|
131
|
+
* Renders many previously created piece objects
|
132
|
+
*/
|
133
|
+
renderPieces(pieces: Piece[]): void;
|
134
|
+
/**
|
135
|
+
* Renders a previously created puzzle object. This method
|
136
|
+
* overrides this canvas' {@link Canvas#pieceSize} and {@link Canvas#proximity}
|
137
|
+
*/
|
138
|
+
renderPuzzle(puzzle: Puzzle): void;
|
139
|
+
/**
|
140
|
+
* Automatically creates and renders pieces given some configuration paramters
|
141
|
+
* @param [options.metadata] - optional list of metadata that will be attached to each generated piece
|
142
|
+
*/
|
143
|
+
autogenerate(options: {
|
144
|
+
horizontalPiecesCount?: number;
|
145
|
+
verticalPiecesCount?: number;
|
146
|
+
insertsGenerator?: InsertsGenerator;
|
147
|
+
metadata?: CanvasMetadata[];
|
148
|
+
}): void;
|
149
|
+
autogenerateWithManufacturer(manufacturer: Manufacturer): void;
|
150
|
+
/**
|
151
|
+
* Creates a name piece template, that can be later instantiated using {@link Canvas#sketchPieceUsingTemplate}
|
152
|
+
*/
|
153
|
+
defineTemplate(name: string, template: Template): void;
|
154
|
+
/**
|
155
|
+
* Creates a new Piece with given id using a named template
|
156
|
+
* defined with {@link Canvas#defineTemplate}
|
157
|
+
*/
|
158
|
+
sketchPieceUsingTemplate(id: string, templateName: string): void;
|
159
|
+
/**
|
160
|
+
* @param farness - from 0 to 1, how far pieces will be placed from x = pieceSize, y = pieceSize
|
161
|
+
*/
|
162
|
+
shuffle(farness?: number): void;
|
163
|
+
/**
|
164
|
+
* Draws this canvas for the first time
|
165
|
+
*/
|
166
|
+
draw(): void;
|
167
|
+
/**
|
168
|
+
* Re-draws this canvas. This method is useful when the canvas {@link Figure}s have
|
169
|
+
* being modified and you need changes to become visible
|
170
|
+
*/
|
171
|
+
redraw(): void;
|
172
|
+
/**
|
173
|
+
* Clears the canvas, clearing the rendering backend and discarding all the created templates, figures, and pieces
|
174
|
+
*/
|
175
|
+
clear(): void;
|
176
|
+
/**
|
177
|
+
* Sets a validator for the canvas' puzzle. Only one validator
|
178
|
+
* can be attached, so subsequent calls of this method will override the previously
|
179
|
+
* attached validator
|
180
|
+
*/
|
181
|
+
attachValidator(validator: Validator): void;
|
182
|
+
/**
|
183
|
+
* Sets a validator that will report when puzzle has been solved,
|
184
|
+
* overriding any previously configured validator
|
185
|
+
*/
|
186
|
+
attachSolvedValidator(): void;
|
187
|
+
/**
|
188
|
+
* Sets a validator that will report when puzzle pieces are in their expected relative
|
189
|
+
* positions, overriding any previously configured validator
|
190
|
+
*/
|
191
|
+
attachRelativePositionValidator(): void;
|
192
|
+
/**
|
193
|
+
* Sets a validator that will report when puzzle pieces are in their expected absolute
|
194
|
+
* positions, overriding any previously configured validator
|
195
|
+
*/
|
196
|
+
attachAbsolutePositionValidator(): void;
|
197
|
+
/**
|
198
|
+
* Registers a listener for connect events
|
199
|
+
*/
|
200
|
+
onConnect(f: CanvasConnectionListener): void;
|
201
|
+
/**
|
202
|
+
* Registers a listener for disconnect events
|
203
|
+
*/
|
204
|
+
onDisconnect(f: CanvasConnectionListener): void;
|
205
|
+
onTranslate(f: CanvasTranslationListener): void;
|
206
|
+
onValid(f: ValidationListener): void;
|
207
|
+
/**
|
208
|
+
* Answers the visual representation for the given piece.
|
209
|
+
* This method uses piece's id.
|
210
|
+
*/
|
211
|
+
getFigure(piece: Piece): Figure;
|
212
|
+
/**
|
213
|
+
* Answers the visual representation for the given piece id.
|
214
|
+
*/
|
215
|
+
getFigureById(id: string): Figure;
|
216
|
+
_annotatePiecePosition(piece: Piece): void;
|
217
|
+
/**
|
218
|
+
* Configures updates from piece into group
|
219
|
+
*/
|
220
|
+
_bindGroupToPiece(group: Group, piece: Piece): void;
|
221
|
+
/**
|
222
|
+
* * Configures updates from group into piece
|
223
|
+
*/
|
224
|
+
_bindPieceToGroup(piece: Piece, group: Group): void;
|
225
|
+
_imageMetadataFor(model: Piece): ImageMetadata;
|
226
|
+
_newPiece(structureLike: StructureLike, metadata: CanvasMetadata): void;
|
227
|
+
/**
|
228
|
+
* The puzzle rendered by this canvas
|
229
|
+
*/
|
230
|
+
puzzle: any;
|
231
|
+
settings: any;
|
232
|
+
}
|
233
|
+
|
234
|
+
declare interface DummyPainter extends Painter {
|
235
|
+
}
|
236
|
+
|
237
|
+
/**
|
238
|
+
* A {@link Painter} for testing purpouses that does not perform rendering
|
239
|
+
*/
|
240
|
+
declare class DummyPainter implements Painter {
|
241
|
+
initialize(canvas: Canvas, id: string): void;
|
242
|
+
draw(canvas: Canvas): void;
|
243
|
+
sketch(canvas: Canvas, _piece: Piece, _figure: Figure): void;
|
244
|
+
}
|
245
|
+
|
246
|
+
declare type ImageMetadata = {
|
247
|
+
content: HTMLImageElement;
|
248
|
+
offset?: Position;
|
249
|
+
scale?: number;
|
250
|
+
};
|
251
|
+
|
252
|
+
declare type ImageLike = HTMLImageElement | ImageMetadata;
|
253
|
+
|
254
|
+
declare module "ImageMetadata" {
|
255
|
+
/**
|
256
|
+
* Converts an image-like object into a true {@link ImageMetadata} object
|
257
|
+
*/
|
258
|
+
function asImageMetadata(imageLike: ImageLike): ImageMetadata;
|
259
|
+
}
|
260
|
+
|
261
|
+
declare module "headbreaker" {
|
262
|
+
var anchor: any;
|
263
|
+
var position: any;
|
264
|
+
var Anchor: any;
|
265
|
+
var Puzzle: any;
|
266
|
+
var Piece: any;
|
267
|
+
var Canvas: any;
|
268
|
+
var Manufacturer: any;
|
269
|
+
var InsertSequence: any;
|
270
|
+
var PieceValidator: any;
|
271
|
+
var PuzzleValidator: any;
|
272
|
+
var NullValidator: any;
|
273
|
+
var Tab: any;
|
274
|
+
var Slot: any;
|
275
|
+
var None: any;
|
276
|
+
var Pair: any;
|
277
|
+
var Metadata: any;
|
278
|
+
var SpatialMetadata: any;
|
279
|
+
var Outline: any;
|
280
|
+
var Structure: any;
|
281
|
+
var Position: any;
|
282
|
+
var generators: any;
|
283
|
+
var painters: any;
|
284
|
+
}
|
285
|
+
|
286
|
+
/**
|
287
|
+
* A connection element of a piece
|
288
|
+
*/
|
289
|
+
declare type Insert = Tab | Slot | None;
|
290
|
+
|
291
|
+
declare interface KonvaPainter extends Painter {
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* A {@link Painter} that uses Konva.js as rendering backend
|
296
|
+
*/
|
297
|
+
declare class KonvaPainter implements Painter {
|
298
|
+
initialize(canvas: Canvas, id: string): void;
|
299
|
+
draw(canvas: Canvas): void;
|
300
|
+
reinitialize(canvas: Canvas): void;
|
301
|
+
sketch(canvas: Canvas, piece: Piece, figure: Figure): void;
|
302
|
+
label(_canvas: Canvas, piece: Piece, figure: Figure): void;
|
303
|
+
physicalTranslate(_canvas: Canvas, group: Group, piece: Piece): void;
|
304
|
+
logicalTranslate(_canvas: Canvas, piece: Piece, group: any): void;
|
305
|
+
onDrag(_canvas: Canvas, piece: Piece, group: Group, f: VectorAction): void;
|
306
|
+
onDragEnd(_canvas: Canvas, _piece: Piece, group: Group, f: Action): void;
|
307
|
+
}
|
308
|
+
|
309
|
+
declare type Figure = {
|
310
|
+
shape: Shape;
|
311
|
+
group: Group;
|
312
|
+
label?: Label;
|
313
|
+
};
|
314
|
+
|
315
|
+
declare type Group = Group;
|
316
|
+
|
317
|
+
declare class Manufacturer {
|
318
|
+
headAnchor: Anchor;
|
319
|
+
/**
|
320
|
+
* Attach metadata to each piece
|
321
|
+
* @param metadata - list of metadata that will be attached to each generated piece
|
322
|
+
*/
|
323
|
+
withMetadata(metadata: object[]): void;
|
324
|
+
withInsertsGenerator(generator: InsertsGenerator): void;
|
325
|
+
/**
|
326
|
+
* Sets the central anchor. If not specified, puzzle will be positioned
|
327
|
+
* at the distance of a whole piece from the origin
|
328
|
+
*/
|
329
|
+
withHeadAt(anchor: Anchor): void;
|
330
|
+
/**
|
331
|
+
* If nothing is configured, default Puzzle structured is assumed
|
332
|
+
*/
|
333
|
+
withStructure(structure: Settings): void;
|
334
|
+
withDimmensions(width: number, height: number): void;
|
335
|
+
build(): Puzzle;
|
336
|
+
_annotateAll(pieces: Piece[]): void;
|
337
|
+
_annotate(piece: Piece, index: number): void;
|
338
|
+
_buildPiece(puzzle: Puzzle, horizontalSequence: InsertSequence, verticalSequence: InsertSequence): void;
|
339
|
+
}
|
340
|
+
|
341
|
+
declare class Positioner {
|
342
|
+
constructor(puzzle: Puzzle, headAnchor: Anchor);
|
343
|
+
naturalAnchor(x: number, y: number): void;
|
344
|
+
}
|
345
|
+
|
346
|
+
/**
|
347
|
+
* This module exposes metadata-handling functions you can override to have better performance
|
348
|
+
*/
|
349
|
+
declare module "Metadata" {
|
350
|
+
/**
|
351
|
+
* Copies a metadata object. The default implementation uses {@link JSON#parse}. Override it to have better performance
|
352
|
+
*/
|
353
|
+
function copy(metadata: T): T;
|
354
|
+
}
|
355
|
+
|
356
|
+
/**
|
357
|
+
* This module contains the draw function. Override it change pieces drawing strategy
|
358
|
+
*/
|
359
|
+
declare module "Outline" {
|
360
|
+
function select(insert: Insert, t: number, s: number, n: number): void;
|
361
|
+
function draw(piece: Piece, size?: number): number[];
|
362
|
+
}
|
363
|
+
|
364
|
+
declare type VectorAction = (dx: number, dy: number) => void;
|
365
|
+
|
366
|
+
declare type Action = () => void;
|
367
|
+
|
368
|
+
/**
|
369
|
+
* An interface for a a rendering backend for a {@link Canvas}, that can be implemented in
|
370
|
+
* order to create UI representations of a puzzle.
|
371
|
+
*/
|
372
|
+
declare interface Painter {
|
373
|
+
/**
|
374
|
+
* Creates the rendering backend, initializig all its contents.
|
375
|
+
* After this call, painter is ready to receive any other messages
|
376
|
+
*/
|
377
|
+
initialize(canvas: Canvas, id: string): void;
|
378
|
+
/**
|
379
|
+
* Recreates the rendering backend, clearing all its contents
|
380
|
+
* After this call, painter is ready to receive any other messages
|
381
|
+
* as it had been just initialized.
|
382
|
+
*/
|
383
|
+
reinitialize(canvas: Canvas): void;
|
384
|
+
/**
|
385
|
+
* Draws the canvas figures in the rendering backend
|
386
|
+
*/
|
387
|
+
draw(canvas: Canvas): void;
|
388
|
+
/**
|
389
|
+
* Adds a piece to the rendering backend, so that it is ready to be drawn
|
390
|
+
* @param figure - the rendering backend information for this piece. This method may mutate it if necessary
|
391
|
+
*/
|
392
|
+
sketch(canvas: Canvas, piece: Piece, figure: Figure): void;
|
393
|
+
/**
|
394
|
+
* Adds piece's label to the given figure in the rendering backend
|
395
|
+
* @param figure - the rendering backend information for this piece. This method may mutate it if necessary
|
396
|
+
*/
|
397
|
+
label(canvas: Canvas, piece: Piece, figure: Figure): void;
|
398
|
+
/**
|
399
|
+
* Translates th given piece
|
400
|
+
*/
|
401
|
+
physicalTranslate(canvas: Canvas, group: Group, piece: Piece): void;
|
402
|
+
logicalTranslate(canvas: Canvas, piece: Piece, group: Group): void;
|
403
|
+
/**
|
404
|
+
* Registers a drag-start callback
|
405
|
+
*/
|
406
|
+
onDrag(canvas: Canvas, piece: Piece, group: Group, f: VectorAction): void;
|
407
|
+
/**
|
408
|
+
* Registers a drag-end callback
|
409
|
+
*/
|
410
|
+
onDragEnd(canvas: Canvas, piece: Piece, group: Group, f: Action): void;
|
411
|
+
}
|
412
|
+
|
413
|
+
/**
|
414
|
+
* Utilities for handling 2D vectors, expressed a two-elements list
|
415
|
+
*/
|
416
|
+
declare module "Pair" {
|
417
|
+
/**
|
418
|
+
* Tells whether this pair is (0, 0)
|
419
|
+
*/
|
420
|
+
function isNull(x: number, y: number): boolean;
|
421
|
+
function equal(x1: number, y1: number, x2: number, y2: number): boolean;
|
422
|
+
/**
|
423
|
+
* Calculates the difference of two vectors
|
424
|
+
*/
|
425
|
+
function diff(x1: number, y1: number, x2: number, y2: number): Pair;
|
426
|
+
}
|
427
|
+
|
428
|
+
declare type TranslationListener = (piece: Piece, dx: number, dy: number) => void;
|
429
|
+
|
430
|
+
declare type ConnectionListener = (piece: Piece, target: Piece) => void;
|
431
|
+
|
432
|
+
/**
|
433
|
+
* A piece primitive representation that can be easily stringified, exchanged and persisted
|
434
|
+
*/
|
435
|
+
declare type PieceDump = {
|
436
|
+
centralAnchor: Position;
|
437
|
+
structure: string;
|
438
|
+
connections?: Orthogonal<object>;
|
439
|
+
metadata: any;
|
440
|
+
};
|
441
|
+
|
442
|
+
/**
|
443
|
+
* A jigsaw piece
|
444
|
+
*/
|
445
|
+
declare class Piece {
|
446
|
+
constructor(options?: Structure);
|
447
|
+
centralAnchor: Anchor;
|
448
|
+
translateListeners: TranslationListener[];
|
449
|
+
connectListeners: ConnectionListener[];
|
450
|
+
disconnectListeners: ConnectionListener[];
|
451
|
+
/**
|
452
|
+
* Adds unestructured user-defined metadata on this piece.
|
453
|
+
*/
|
454
|
+
annotate(metadata: any): void;
|
455
|
+
/**
|
456
|
+
* Sets unestructured user-defined metadata on this piece.
|
457
|
+
*
|
458
|
+
* This object has no strong requirement, but it is recommended to have an
|
459
|
+
* id property.
|
460
|
+
*/
|
461
|
+
reannotate(metadata: any): void;
|
462
|
+
belongTo(puzzle: any): void;
|
463
|
+
presentConnections: any;
|
464
|
+
/**
|
465
|
+
* @param f - the callback
|
466
|
+
*/
|
467
|
+
onTranslate(f: TranslationListener): void;
|
468
|
+
/**
|
469
|
+
* @param f - the callback
|
470
|
+
*/
|
471
|
+
onConnect(f: ConnectionListener): void;
|
472
|
+
/**
|
473
|
+
* @param f - the callback
|
474
|
+
*/
|
475
|
+
onDisconnect(f: ConnectionListener): void;
|
476
|
+
fireTranslate(dx: number, dy: number): void;
|
477
|
+
fireConnect(other: Piece): void;
|
478
|
+
fireDisconnect(others: Piece[]): void;
|
479
|
+
connectVerticallyWith(other: Piece, back?: boolean): void;
|
480
|
+
attractVertically(other: Piece): void;
|
481
|
+
connectHorizontallyWith(other: Piece, back?: boolean): void;
|
482
|
+
attractHorizontally(other: Piece): void;
|
483
|
+
tryConnectWith(other: Piece, back?: boolean): void;
|
484
|
+
tryConnectHorizontallyWith(other: Piece, back?: boolean): void;
|
485
|
+
tryConnectVerticallyWith(other: Piece, back?: boolean): void;
|
486
|
+
upConnection: Piece;
|
487
|
+
leftConnection: Piece;
|
488
|
+
/**
|
489
|
+
* Sets the centralAnchor for this piece.
|
490
|
+
*/
|
491
|
+
centerAround(anchor: Anchor): void;
|
492
|
+
/**
|
493
|
+
* Sets the initial position of this piece. This method is similar to {@link Piece#centerAround},
|
494
|
+
* but takes a pair instead of an anchor.
|
495
|
+
*/
|
496
|
+
locateAt(x: number, y: number): void;
|
497
|
+
/**
|
498
|
+
* Tells whether this piece central anchor is at given point
|
499
|
+
*/
|
500
|
+
isAt(x: number, y: number): boolean;
|
501
|
+
/**
|
502
|
+
* Moves this piece to the given position, firing translation events.
|
503
|
+
* Piece must be already centered.
|
504
|
+
* @param anchor - the new central anchor
|
505
|
+
* @param [quiet = false] - indicates whether events should be suppressed
|
506
|
+
*/
|
507
|
+
recenterAround(anchor: Anchor, quiet?: boolean): void;
|
508
|
+
/**
|
509
|
+
* Moves this piece to the given position, firing translation events.
|
510
|
+
* Piece must be already centered. This method is similar to {@link Piece#recenterAround},
|
511
|
+
* but takes a pair instead of an anchor.
|
512
|
+
* @param x - the final x position
|
513
|
+
* @param y - the final y position
|
514
|
+
* @param [quiet = false] - indicates whether events should be suppressed
|
515
|
+
*/
|
516
|
+
relocateTo(x: number, y: number, quiet?: boolean): void;
|
517
|
+
/**
|
518
|
+
* Move this piece a given distance, firing translation events
|
519
|
+
* @param dx - the x distance
|
520
|
+
* @param dy - the y distance
|
521
|
+
* @param [quiet = false] - indicates whether events should be suppressed
|
522
|
+
*/
|
523
|
+
translate(dx: number, dy: number, quiet?: boolean): void;
|
524
|
+
push(dx: number, dy: number, quiet?: boolean, pushedPieces?: Piece[]): void;
|
525
|
+
drag(dx: number, dy: number): void;
|
526
|
+
vericallyOpenMovement(dy: number): boolean;
|
527
|
+
horizontallyOpenMovement(dx: number): boolean;
|
528
|
+
canConnectHorizontallyWith(other: Piece): boolean;
|
529
|
+
canConnectVerticallyWith(other: Piece): boolean;
|
530
|
+
verticallyCloseTo(other: Piece): boolean;
|
531
|
+
horizontallyCloseTo(other: Piece): boolean;
|
532
|
+
verticallyMatch(other: Piece): boolean;
|
533
|
+
horizontallyMatch(other: Piece): boolean;
|
534
|
+
downAnchor: any;
|
535
|
+
rightAnchor: any;
|
536
|
+
upAnchor: any;
|
537
|
+
leftAnchor: any;
|
538
|
+
size: any;
|
539
|
+
proximity: any;
|
540
|
+
/**
|
541
|
+
* This piece id. It is extracted from metadata
|
542
|
+
*/
|
543
|
+
id: any;
|
544
|
+
/**
|
545
|
+
* Converts this piece into a plain, stringify-ready object.
|
546
|
+
* Connections should have ids
|
547
|
+
*/
|
548
|
+
export(options: {
|
549
|
+
compact?: boolean;
|
550
|
+
}): PieceDump;
|
551
|
+
/**
|
552
|
+
* Converts this piece back from a dump. Connections are not restored. {@link Puzzle#autoconnect} method should be used
|
553
|
+
* after importing all them
|
554
|
+
*/
|
555
|
+
static import(dump: PieceDump): Piece;
|
556
|
+
}
|
557
|
+
|
558
|
+
declare type Position = {
|
559
|
+
x: number;
|
560
|
+
y: number;
|
561
|
+
};
|
562
|
+
|
563
|
+
declare function position(x: number, y: number): Position;
|
564
|
+
|
565
|
+
/**
|
566
|
+
* This module contains functions for dealing with objects with x and y
|
567
|
+
* coordinates that represent or include point data
|
568
|
+
*/
|
569
|
+
declare module "Position" {
|
570
|
+
/**
|
571
|
+
* Returns a new (0, 0) position
|
572
|
+
*/
|
573
|
+
function origin(): Position;
|
574
|
+
/**
|
575
|
+
* Compares two points
|
576
|
+
*/
|
577
|
+
function equal(one: Position, other: Position): boolean;
|
578
|
+
/**
|
579
|
+
* Creates a copy of the given point
|
580
|
+
*/
|
581
|
+
function copy(one: Position): Position;
|
582
|
+
function update(position: Position, x: any, y: any): void;
|
583
|
+
/**
|
584
|
+
* @returns ;
|
585
|
+
*/
|
586
|
+
function diff(one: Position, other: Position): Pair;
|
587
|
+
}
|
588
|
+
|
589
|
+
declare type Orthogonal = {
|
590
|
+
up: A;
|
591
|
+
down: A;
|
592
|
+
left: A;
|
593
|
+
right: A;
|
594
|
+
};
|
595
|
+
|
596
|
+
declare type Mapper = (value: A) => B;
|
597
|
+
|
598
|
+
/**
|
599
|
+
* Misc generic functions
|
600
|
+
*/
|
601
|
+
declare module "Prelude" {
|
602
|
+
function pivot(one: T, other: T, back?: boolean): any;
|
603
|
+
function orthogonalMap(values: A[], mapper: Mapper<A, B>, replacement: A): B[];
|
604
|
+
function orthogonalTransform(values: A[], mapper: Mapper<A, B>, replacement: A): Orthogonal<B>;
|
605
|
+
function itself(arg: A): A;
|
606
|
+
}
|
607
|
+
|
608
|
+
/**
|
609
|
+
* A puzzle primitive representation that can be easily stringified, exchanged and persisted
|
610
|
+
*/
|
611
|
+
declare type PuzzleDump = {
|
612
|
+
pieceSize: number;
|
613
|
+
proximity: number;
|
614
|
+
pieces: PieceDump[];
|
615
|
+
};
|
616
|
+
|
617
|
+
declare type Settings = {
|
618
|
+
pieceSize?: number;
|
619
|
+
proximity?: number;
|
620
|
+
};
|
621
|
+
|
622
|
+
/**
|
623
|
+
* A set of a {@link Piece}s that can be manipulated as a whole, and that can be
|
624
|
+
* used as a pieces factory
|
625
|
+
*/
|
626
|
+
declare class Puzzle {
|
627
|
+
constructor(options?: Settings);
|
628
|
+
pieces: Piece[];
|
629
|
+
validator: Validator;
|
630
|
+
/**
|
631
|
+
* Creates and adds to this puzzle a new piece
|
632
|
+
* @param [options] - the piece structure
|
633
|
+
* @returns the new piece
|
634
|
+
*/
|
635
|
+
newPiece(options?: Structure): Piece;
|
636
|
+
addPiece(piece: Piece): void;
|
637
|
+
addPieces(pieces: Piece[]): void;
|
638
|
+
/**
|
639
|
+
* Annotates all the pieces with the given list of metadata
|
640
|
+
*/
|
641
|
+
annotate(metadata: object[]): void;
|
642
|
+
/**
|
643
|
+
* Relocates all the pieces to the given list of points
|
644
|
+
*/
|
645
|
+
relocateTo(points: Pair[]): void;
|
646
|
+
/**
|
647
|
+
* Tries to connect pieces in their current positions
|
648
|
+
* This method is O(n^2)
|
649
|
+
*/
|
650
|
+
autoconnect(): void;
|
651
|
+
/**
|
652
|
+
* Disconnects all pieces
|
653
|
+
*/
|
654
|
+
disconnect(): void;
|
655
|
+
/**
|
656
|
+
* Tries to connect the given piece to the rest of the set
|
657
|
+
* This method is O(n)
|
658
|
+
*/
|
659
|
+
autoconnectWith(piece: Piece): void;
|
660
|
+
shuffle(maxX: number, maxY: number): void;
|
661
|
+
translate(dx: number, dy: number): void;
|
662
|
+
onTranslate(f: TranslationListener): void;
|
663
|
+
onConnect(f: ConnectionListener): void;
|
664
|
+
onDisconnect(f: ConnectionListener): void;
|
665
|
+
onValid(f: ValidationListener): void;
|
666
|
+
/**
|
667
|
+
* Answers the list of points where
|
668
|
+
* central anchors of pieces are located
|
669
|
+
*/
|
670
|
+
points: any;
|
671
|
+
/**
|
672
|
+
* Answers a list of points whose coordinates are scaled
|
673
|
+
* to the {@link Puzzle#pieceWidth}
|
674
|
+
*/
|
675
|
+
refs: any;
|
676
|
+
/**
|
677
|
+
* Returns the first piece
|
678
|
+
*/
|
679
|
+
head: any;
|
680
|
+
/**
|
681
|
+
* Returns the central anchor of the first piece
|
682
|
+
*/
|
683
|
+
headAnchor: any;
|
684
|
+
attachValidator(validator: Validator): void;
|
685
|
+
/**
|
686
|
+
* Wether all the pieces in this puzzle are connected
|
687
|
+
*/
|
688
|
+
connected: any;
|
689
|
+
/**
|
690
|
+
* The piece width, from edge to edge
|
691
|
+
*/
|
692
|
+
pieceWidth: any;
|
693
|
+
/**
|
694
|
+
* Converts this piece into a plain, stringify-ready object.
|
695
|
+
* Pieces should have ids
|
696
|
+
* @param options - config options for export
|
697
|
+
* @param [options.compact] - if connection information must be omitted
|
698
|
+
*/
|
699
|
+
export(options: {
|
700
|
+
compact?: boolean;
|
701
|
+
}): PuzzleDump;
|
702
|
+
static import(dump: PuzzleDump): Puzzle;
|
703
|
+
}
|
704
|
+
|
705
|
+
/**
|
706
|
+
* A function for generating {@link Insert}s sequentially
|
707
|
+
* @param index - the position of the element to be generated in the sequence
|
708
|
+
*/
|
709
|
+
declare type InsertsGenerator = (index: number) => Insert;
|
710
|
+
|
711
|
+
/**
|
712
|
+
* This module exports several {@link Insert}s sequences strategies: {@link fixed}, {@link flipflop}, {@link twoAndTwo} and {@link random}
|
713
|
+
*/
|
714
|
+
declare module "sequence" {
|
715
|
+
function fixed(): void;
|
716
|
+
/**
|
717
|
+
* Generates slots and tabs alternately
|
718
|
+
*/
|
719
|
+
function flipflop(): void;
|
720
|
+
/**
|
721
|
+
* Generates sequences of two slots and then two tabs
|
722
|
+
*/
|
723
|
+
function twoAndTwo(): void;
|
724
|
+
/**
|
725
|
+
* Generates tabs and slots in a psuedo-random way
|
726
|
+
*/
|
727
|
+
function random(): void;
|
728
|
+
/**
|
729
|
+
* An InsertSequence is a statefull object that
|
730
|
+
* allows to generate {@link Insert}s sequences using an {@link InsertsGenerator} as strategy
|
731
|
+
* @param generator - the generator used by this sequence to produce inserts
|
732
|
+
*/
|
733
|
+
class InsertSequence {
|
734
|
+
constructor(generator: InsertsGenerator);
|
735
|
+
/**
|
736
|
+
* The previously generated insert
|
737
|
+
*/
|
738
|
+
previousComplement(): Insert;
|
739
|
+
/**
|
740
|
+
* Answers the last Insert generated by {@link InsertSequence#next}
|
741
|
+
*/
|
742
|
+
current(): Insert;
|
743
|
+
next(): Insert;
|
744
|
+
}
|
745
|
+
}
|
746
|
+
|
747
|
+
declare type SpatialMetadata = {
|
748
|
+
targetPosition?: Position;
|
749
|
+
currentPosition?: Position;
|
750
|
+
};
|
751
|
+
|
752
|
+
/**
|
753
|
+
* Functions for handling spatial metadata
|
754
|
+
* and pieces and puzzles that are annotated with it
|
755
|
+
*/
|
756
|
+
declare module "SpatialMetadata" {
|
757
|
+
function solved(): void;
|
758
|
+
function relativePosition(): void;
|
759
|
+
function absolutePosition(): void;
|
760
|
+
function initialize(metadata: SpatialMetadata, target: Position, current?: Position): void;
|
761
|
+
}
|
762
|
+
|
763
|
+
declare type Structure = {
|
764
|
+
up?: Insert;
|
765
|
+
left?: Insert;
|
766
|
+
down?: Insert;
|
767
|
+
right?: Insert;
|
768
|
+
};
|
769
|
+
|
770
|
+
declare module "Structure" {
|
771
|
+
function serialize(structure: Structure): string;
|
772
|
+
function deserialize(string: string): Structure;
|
773
|
+
type StructureLike = Structure | string;
|
774
|
+
function asStructure(structureLike: StructureLike): Structure;
|
775
|
+
}
|
776
|
+
|
777
|
+
declare type Validator = PieceValidator | PuzzleValidator | NullValidator;
|
778
|
+
|
779
|
+
declare type ValidationListener = (puzzle: Puzzle) => void;
|
780
|
+
|
781
|
+
declare type PieceCondition = (puzzle: Piece) => boolean;
|
782
|
+
|
783
|
+
declare type PuzzleCondition = (puzzle: Puzzle) => boolean;
|
784
|
+
|
785
|
+
/**
|
786
|
+
* A validator that evaluates each piece independently
|
787
|
+
*/
|
788
|
+
declare class PieceValidator {
|
789
|
+
constructor(f: PieceCondition);
|
790
|
+
isValid(puzzle: Puzzle): boolean;
|
791
|
+
}
|
792
|
+
|
793
|
+
declare class PuzzleValidator {
|
794
|
+
constructor(f: PuzzleCondition);
|
795
|
+
isValid(puzzle: Puzzle): void;
|
796
|
+
static connected(): void;
|
797
|
+
/**
|
798
|
+
* @param expected - the expected relative refs
|
799
|
+
*/
|
800
|
+
static relativeRefs(expected: Pair[]): PuzzleCondition;
|
801
|
+
}
|
802
|
+
|