I want to have new tetris pieces to appear in the game the longer you play and it doesn’t work, it makes new shapes but the shapes aren’t centered, they aren’t continuous (like the shape might look like 2 shapes because they aren’t touching), and it sometimes adds a shape that’s already part of the shapes array. Each shape has a max squares of 12 and must fit in a 4×4 space
Here’s my code so far:
function randomShape(score) {
const maxSize = 12; // Max number of squares per shape
const centerOffset = 1; // Offset to center the shape
const maxComplexity = Math.min(Math.floor(score / 100), 6); // Max complexity based on score
let shape;
do {
shape = Array.from({ length: 4 }, () => Array(4).fill(0)); // Create an empty 4x4 shape
const size = Math.max(1, Math.floor(Math.random() * (maxComplexity + 1))); // Shape size varies based on complexity
let squaresToPlace = Math.min(size, maxSize); // Limit the squares placed to maxSize
// Fill the shape with random positions of 1s based on size
while (squaresToPlace > 0) {
const x = Math.floor(Math.random() * 4);
const y = Math.floor(Math.random() * 4);
// Only place a 1 if the spot is empty
if (shape[y][x] === 0) {
shape[y][x] = 1;
squaresToPlace--;
}
}
} while (!shape.flat(5).includes(1)); // Retry if the shape is empty
// Centering logic
const centeredShape = Array.from({ length: 4 }, () => Array(4).fill(0));
// Get the positions of all filled cells
const filledPositions = [];
for (let r = 0; r < 4; r++) {
for (let c = 0; c < 4; c++) {
if (shape[r][c] === 1) {
filledPositions.push({ r, c });
}
}
}
let amount = 0;
shape.flat(5).forEach((s) => {
if (s === 1) amount++;
});
if (amount === 1) {
return [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 0],
];
}
// Determine how to center the shape
const minRow = Math.min(...filledPositions.map((p) => p.r));
const maxRow = Math.max(...filledPositions.map((p) => p.r));
const minCol = Math.min(...filledPositions.map((p) => p.c));
const maxCol = Math.max(...filledPositions.map((p) => p.c));
// Calculate the offsets needed to center the shape
const height = maxRow - minRow + 1;
const width = maxCol - minCol + 1;
// Calculate vertical and horizontal offsets
const rowOffset = Math.floor((4 - height) / 2); // Center vertically
const colOffset = Math.floor((4 - width) / 2); // Center horizontally
// Place the shape in the centered position
filledPositions.forEach(({ r, c }) => {
// Ensure we're placing the piece within bounds
const newRow = r + rowOffset;
const newCol = c + colOffset;
if (newRow >= 0 && newRow < 4 && newCol >= 0 && newCol < 4) {
centeredShape[newRow][newCol] = 1;
}
});
return centeredShape;
}
I tried to add new random shapes that were supposed to look normal and be centered, but they were broken and uncentered and sometimes dupes.