Changed around line 1
+ const grid = document.querySelector('.grid');
+ const miniGrid = document.querySelector('.mini-grid');
+ const scoreDisplay = document.querySelector('.score');
+ const startButton = document.querySelector('.start-button');
+ const width = 10;
+ let squares = Array.from(grid.querySelectorAll('div'));
+ let miniSquares = Array.from(miniGrid.querySelectorAll('div'));
+ let currentPosition = 4;
+ let currentRotation = 0;
+ let score = 0;
+ let timerId;
+ let nextRandom = 0;
+
+ // The Tetrominoes
+ const lTetromino = [
+ [1, width+1, width*2+1, 2],
+ [width, width+1, width+2, width*2+2],
+ [1, width+1, width*2+1, width*2],
+ [width, width*2, width*2+1, width*2+2]
+ ]
+
+ const zTetromino = [
+ [0, width, width+1, width*2+1],
+ [width+1, width+2, width*2, width*2+1],
+ [0, width, width+1, width*2+1],
+ [width+1, width+2, width*2, width*2+1]
+ ]
+
+ const tTetromino = [
+ [1, width, width+1, width+2],
+ [1, width+1, width+2, width*2+1],
+ [width, width+1, width+2, width*2+1],
+ [1, width, width+1, width*2+1]
+ ]
+
+ const oTetromino = [
+ [0, 1, width, width+1],
+ [0, 1, width, width+1],
+ [0, 1, width, width+1],
+ [0, 1, width, width+1]
+ ]
+
+ const iTetromino = [
+ [1, width+1, width*2+1, width*3+1],
+ [width, width+1, width+2, width+3],
+ [1, width+1, width*2+1, width*3+1],
+ [width, width+1, width+2, width+3]
+ ]
+
+ const theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino]
+
+ let random = Math.floor(Math.random()*theTetrominoes.length)
+ let current = theTetrominoes[random][currentRotation]
+
+ // Draw the Tetromino
+ function draw() {
+ current.forEach(index => {
+ squares[currentPosition + index].classList.add('tetromino')
+ })
+ }
+
+ // Undraw the Tetromino
+ function undraw() {
+ current.forEach(index => {
+ squares[currentPosition + index].classList.remove('tetromino')
+ })
+ }
+
+ // Move down function
+ function moveDown() {
+ undraw()
+ currentPosition += width
+ draw()
+ freeze()
+ }
+
+ // Freeze function
+ function freeze() {
+ if(current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) {
+ current.forEach(index => squares[currentPosition + index].classList.add('taken'))
+ // Start a new tetromino falling
+ random = nextRandom
+ nextRandom = Math.floor(Math.random() * theTetrominoes.length)
+ current = theTetrominoes[random][currentRotation]
+ currentPosition = 4
+ draw()
+ displayShape()
+ addScore()
+ gameOver()
+ }
+ }
+
+ // Move the tetromino left, unless it's at the edge or there's a blockage
+ function moveLeft() {
+ undraw()
+ const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0)
+
+ if(!isAtLeftEdge) currentPosition -= 1
+
+ if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
+ currentPosition += 1
+ }
+
+ draw()
+ }
+
+ // Move the tetromino right, unless it's at the edge or there's a blockage
+ function moveRight() {
+ undraw()
+ const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1)
+
+ if(!isAtRightEdge) currentPosition += 1
+
+ if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
+ currentPosition -= 1
+ }
+
+ draw()
+ }
+
+ // Rotate the tetromino
+ function rotate() {
+ undraw()
+ currentRotation++
+ if(currentRotation === current.length) { // if the current rotation gets to 4, go back to 0
+ currentRotation = 0
+ }
+ current = theTetrominoes[random][currentRotation]
+ draw()
+ }
+
+ // Show up-next tetromino in mini-grid display
+ function displayShape() {
+ // Remove any trace of a tetromino from the entire grid
+ miniSquares.forEach(square => {
+ square.classList.remove('tetromino')
+ square.style.backgroundColor = ''
+ })
+ // Display the shape
+ theTetrominoes[nextRandom].forEach(index => {
+ miniSquares[index].classList.add('tetromino')
+ miniSquares[index].style.backgroundColor = colors[nextRandom]
+ })
+ }
+
+ // Add score
+ function addScore() {
+ for(let i = 0; i < 199; i += width) {
+ const row = [i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8, i+9]
+
+ if(row.every(index => squares[index].classList.contains('taken'))) {
+ score += 10
+ scoreDisplay.innerHTML = score
+ row.forEach(index => {
+ squares[index].classList.remove('taken')
+ squares[index].classList.remove('tetromino')
+ squares[index].style.backgroundColor = ''
+ })
+ const squaresRemoved = squares.splice(i, width)
+ squares = squaresRemoved.concat(squares)
+ squares.forEach(cell => grid.appendChild(cell))
+ }
+ }
+ }
+
+ // Game over
+ function gameOver() {
+ if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
+ scoreDisplay.innerHTML = 'end'
+ clearInterval(timerId)
+ }
+ }
+
+ // Assign functions to keyCodes
+ function control(e) {
+ if(e.keyCode === 37) {
+ moveLeft()
+ } else if(e.keyCode === 38) {
+ rotate()
+ } else if(e.keyCode === 39) {
+ moveRight()
+ } else if(e.keyCode === 40) {
+ moveDown()
+ }
+ }
+ document.addEventListener('keydown', control)
+
+ // Start the game
+ startButton.addEventListener('click', () => {
+ if(timerId) {
+ clearInterval(timerId)
+ timerId = null
+ } else {
+ draw()
+ timerId = setInterval(moveDown, 1000)
+ nextRandom = Math.floor(Math.random() * theTetrominoes.length)
+ displayShape()
+ }
+ })