Last active
July 10, 2019 01:24
-
-
Save jketcham/9d96a5762f0ed02b9789f16a2b8e7df7 to your computer and use it in GitHub Desktop.
A jigsaw puzzle implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Node >= v2 required | |
const util = require('util'); | |
const TOP = 0; | |
const RIGHT = 1; | |
const BOTTOM = 2; | |
const LEFT = 3; | |
const SIDES = [TOP, RIGHT, BOTTOM, LEFT]; | |
const TAB = 'tab'; | |
const HOLE = 'hole'; | |
const FLAT = 'flat'; | |
function randomType() { | |
return Math.floor(Math.random() * 2) > 0 ? TAB : HOLE; | |
} | |
class Piece { | |
constructor(x, y, sides) { | |
this.x = x; | |
this.y = y; | |
this.sides = sides; | |
} | |
getOppositeSide(side) { | |
const sidePair = { | |
[TOP]: BOTTOM, | |
[RIGHT]: LEFT, | |
[BOTTOM]: TOP, | |
[LEFT]: RIGHT, | |
}; | |
const oppositeSide = sidePair[side]; | |
return this.sides[oppositeSide]; | |
} | |
} | |
class Puzzle { | |
constructor(width, height) { | |
this.width = width; | |
this.height = height; | |
this.matrix = this.createMatrix(); | |
this.fillMatrix(); | |
} | |
createMatrix() { | |
const matrix = []; | |
while (matrix.length < this.height) { | |
matrix.push([]); | |
} | |
return matrix; | |
} | |
getAdjacentPieces(x, y) { | |
const rowAbove = this.matrix[y - 1]; | |
const rowBelow = this.matrix[y + 1]; | |
return [ | |
rowAbove && rowAbove[x], // top | |
this.matrix[y][x + 1], // right | |
rowBelow && rowBelow[x], // bottom | |
this.matrix[y][x - 1], // left | |
]; | |
} | |
isEdge(x, y, side) { | |
const tests = { | |
[TOP]: (x, y) => y === 0, | |
[RIGHT]: (x, y) => x === this.width - 1, | |
[BOTTOM]: (x, y) => y === this.height - 1, | |
[LEFT]: (x, y) => x === 0, | |
}; | |
return tests[side](x, y); | |
} | |
assignSide(neighbors, side, axis) { | |
const isEdge = this.isEdge(...axis, side); | |
if (isEdge) { | |
return FLAT; | |
} | |
const adjacentPiece = neighbors[side]; | |
if (!adjacentPiece) { | |
return randomType(); | |
} | |
if (adjacentPiece.getOppositeSide(side) === TAB) { | |
return HOLE; | |
} | |
return TAB; | |
} | |
fillMatrix() { | |
this.matrix.forEach((row, yIndex) => { | |
while (row.length < this.width) { | |
const xIndex = row.length; | |
const axis = [xIndex, yIndex]; | |
const adjacentPieces = this.getAdjacentPieces(...axis); | |
const sides = SIDES.map(side => this.assignSide(adjacentPieces, side, axis)); | |
row.push(new Piece(xIndex, yIndex, sides)); | |
} | |
}); | |
} | |
} | |
const puzzle = new Puzzle(4, 4); | |
console.log(util.inspect(puzzle.matrix, false, null, true)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment