Skip to content

Instantly share code, notes, and snippets.

@allanesquina
Last active July 12, 2020 08:37
Show Gist options
  • Save allanesquina/1f9b0cf8bbd561458a28cfc8400e8741 to your computer and use it in GitHub Desktop.
Save allanesquina/1f9b0cf8bbd561458a28cfc8400e8741 to your computer and use it in GitHub Desktop.
// List of pieces
const PIECES_LIST = [
{
id: 1,
size: { col: 6, row: 2 },
length: 1,
},
{
id: 2,
size: { col: 2, row: 2 },
length: 1,
},
{
id: 3,
size: { col: 1, row: 2 },
length: 2,
},
{
id: 4,
size: { col: 8, row: 1 },
length: 1,
},
{
id: 5,
size: { col: 2, row: 1 },
length: 3,
},
{
id: 6,
size: { col: 1, row: 1 },
length: 6,
}
];
// Matrix configuration
const MATRIX_CONFIG = { col: 8, row: 5 };
/////////////////////////////////////////
// Create the matrix
function createMatrix(matrix) {
const row = matrix.row;
const col = matrix.col;
const buff = [];
for (let i = 0; i < row; i++) {
buff[i] = [];
for (let j = 0; j < col; j++) {
buff[i][j] = 0;
}
}
return buff;
}
// Print matrix to console
function printMatrix(matrix) {
let buff = '';
for (let i = 0; i < matrix.length; i++) {
buff += '\r\n' + matrix[i].join(',');
}
console.log(buff);
}
// Sorting pieces from < to >
function sortPieces(pieces) {
return pieces.sort((a, b) => (b.size.col * b.size.row) - (a.size.col * a.size.row));
}
// Get a random number between min and max
function getRandomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// Function responsible for finding an empty space within the matrix to place the given piece
function findPlace(piece, matrix) {
let randomRow;
let randomCol;
let error;
let coordinates = [];
do {
error = 0;
do {
// If the length of the coordinates is equal to the number of tiles in the matrix
if (coordinates.length === MATRIX_CONFIG.col * MATRIX_CONFIG.row) {
return false;
}
// Get a random coordinate
randomRow = getRandomBetween(0, matrix.length - 1);
randomCol = getRandomBetween(0, matrix[randomRow].length - 1);
} while (coordinates.includes(`${randomRow},${randomCol}`)
|| (matrix[randomRow] > 0 && matrix[randomRow][randomCol] > 0));
coordinates.push(`${randomRow},${randomCol}`);
// Check available positions for the given piece
for (let i = 0; i < piece.size.row; i++) {
if (matrix[randomRow + i] === undefined || matrix[randomRow + i] > 0) {
error++;
break;
} else {
for (let j = 0; j < piece.size.col; j++) {
if (matrix[randomRow + i][randomCol + j] === undefined
|| matrix[randomRow + i][randomCol + j] > 0) {
error++;
break;
}
}
}
}
} while (error > 0);
// Place piece to the matrix
const coordinate = { row: randomRow, col: randomCol };
placePiece(piece, coordinate, matrix);
return true;
}
// Place given piece id to the matrix
function placePiece(piece, coordinate, matrix) {
for (let i = 0; i < piece.size.row; i++) {
for (let j = 0; j < piece.size.col; j++) {
matrix[coordinate.row + i][coordinate.col + j] = piece.id;
}
}
}
// Walk through pieces
function placePieces(pieces, matrix) {
let error = 0;
for (let i = 0; i < pieces.length; i++) {
const piece = pieces[i];
let j = piece.length;
while (j--) {
if (!findPlace(piece, matrix)) {
error++
break;
}
}
if (error > 0) { break; }
}
// if there's error try again
if (error > 0) {
return false;
}
return true;
}
// Recursive process
function process(pieces) {
const matrix = createMatrix(MATRIX_CONFIG);
if (!placePieces(pieces, matrix)) {
process(pieces);
return false;
}
printMatrix(matrix);
}
// Start the process
function start() {
const pieces = sortPieces(PIECES_LIST);
process(pieces)
}
// INIT
start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment