0

JS noob here, trying to make Tetris. I have an HTML collection "squares" of all of the grid squares that make up the playable game field defined with let squares = Array.from(document.querySelectorAll('.grid div')) where grid is a class in the corresponding HTML. This array is filled with 200 div objects for a 10x20 grid. When a tetromino passes through one of the grid squares, the class "tetromino" is added to the square as such:

current.forEach(index => {
    squares[currentPosition+index].classList.add('tetromino')
})

where current is an array with elements that specify the relative position of the tetromino squares on the grid and currentPosition tracks absolute position of a single square in the tetromino.

When I then go to remove the tetromino class:

current.forEach(index => {
    squares[currentPosition + index].classList.remove('tetromino')
})

Each div object that had the tetromino class is then removed from the squares array, or the index that it was at is undefined. I would expect the class to be removed but the object to remain in the squares array. What is going on?

  • 1
    ForEach parameters is as follows: item, index, array – Mohammad Mostafa Dastjerdi Jul 27 '21 at 14:27
  • Yes, sorry for the confusing notation. In this case, the items referenced are indexes of the grid array that specify a tetromino configuration. Hence, the label index, even though that is a seperate argument passed to forEach. – Captain Banaynays Jul 27 '21 at 14:46
  • 1
    What you're describing shouldn't happen. Please post a [minimum reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – edemaine Jul 27 '21 at 15:13
  • @edemaine do you have a suggested way to do that? Good sharing site? JSFiddle almost crashed when I tried to run it there, and although it ran fine in playcode, the console did not describe the undefined divs in as much detail as VSCode does, so the console.log looks normal when it shouldn't and ultimately playcode breaks in the same way the code on just the browser does. – Captain Banaynays Jul 27 '21 at 16:09
  • https://codesandbox.io/ seems to be the current standard. – edemaine Jul 27 '21 at 16:16
  • @edemaine alright well here's the link: https://codesandbox.io/s/tetris-troubleshoot-u3qkr I think the json isn't configured correctly because it's not even attempting to run in the sandbox but the code is there. – Captain Banaynays Jul 27 '21 at 19:12
  • @edemaine No, [use a Stack Snippet](https://meta.stackoverflow.com/q/358992/1048572) instead. – Bergi Jul 27 '21 at 21:17
  • @CaptainBanaynays "*the console did not describe the undefined divs in as much detail as VSCode does, so the console.log looks normal when it shouldn't*" - maybe you are experiencing [this issue](https://stackoverflow.com/q/4057440/1048572) then? – Bergi Jul 27 '21 at 21:18
  • @Bergi no, chrome was logging the console correctly, with the undefined entries. – Captain Banaynays Jul 27 '21 at 22:46

1 Answers1

0

The issue is the following line of code:

squares[currentPosition + index + width] = undefined

This sets one of the squares items to undefined. You'll notice that squares.length remains 200 throughout the piece drop, but that some of squares's entries become undefined, which causes .classList to fail.

You probably meant == undefined or === undefined, to detect that you went below the end of the board.

edemaine
  • 2,699
  • 11
  • 20