Search code examples
javascriptfor-loopif-statementconditional-statementsminesweeper

I need help to debug cells in Mine Sweeper personal project


first post here. I'm a newbie, and for my personal Javscript project I'm trying to clone the old Mine Sweeper windows game. In the generating field algorithm I declared this If statement that calculates the previous number, the following and the upwards, downwards and diagonals. Assuming x= bomb number, I used the x+1, x-1 for next and previous. Then x+rowLenght, x-rowLenght for upwards and downwards. Then x+rowLenght +1, x+rowlenght +1, x-rowLenght +1, x-rowLenght-1 for diagonals.

The problems appears when a bomb is placed on the grid border, so I got green cells also in wrong places (after or before).

        let gridLenght = Math.sqrt(numbOfCells);
        const cellNumb = Number(singleCell.textContent);       

        if (bombsArray.includes(cellNumb)) {
            // 🔽🔽 💣 this adds bombs based on bombsArray generated randomly

           singleCell.classList.add('bomb')

            // 🔽🔽💚 this creates the green cells near the bomb cell

            
        } else if (bombsArray.includes(cellNumb - 1)
            || bombsArray.includes(cellNumb + 1)
            || bombsArray.includes(cellNumb - gridLenght)
            || bombsArray.includes(cellNumb + gridLenght)
            || bombsArray.includes(cellNumb - gridLenght - 1)
            || bombsArray.includes(cellNumb - gridLenght + 1)
            || bombsArray.includes(cellNumb + gridLenght - 1)
            || bombsArray.includes(cellNumb + gridLenght + 1)
        ) {

            singleCell.classList.add('green');
            singleCell.addEventListener('click', function () {
                addGreenPoints()
            })

        }

I'm trying to add a specific rule, that reads when a bomb is placed on the border and in that case override the if else statment, or maybe just delete the green cell class.

if (bombsArray.includes(cellNumb) == (gridLenght * 10)) {
            singleCell.classList.remove('green');
            console.log("bomb on the right border");
        }

But it seems to not be working, likewise the condition is never verificated. I can't figure it out if the problem is in the logic or in the code itself.

Thanks a lot for the help.

Edit: the grid numbers (cellNumb) starts with 1, not 0.

Edit: The Blue Grid: As a second feature I tried to use the same logic suggested by Trincot (thank you) but to add an outer rim of blue cells representing the farthest indicator of a bomb, they'll give 1 point instead of 3 if you click it. The basic logic works, but I found odd behaviors on borders. It seems that borders numbers generate 2 extra cells in the other border, but I cant find which rule isn't working properly.

    let gridLength = Math.sqrt(numbOfCells);
    const cellNumb = Number(singleCell.textContent);

    const atRightSide = cellNumb % gridLength === 0;
    const atLeftSide = (cellNumb - 1) % gridLength === 0;

    const twoRightSide = cellNumb % gridLength === 0 || (cellNumb + 1) 
      % gridLength === 0;
    const twoLeftSide = (cellNumb - 1) % gridLength === 0 || (cellNumb) 
     % gridLength === 2;

    if (bombsArray.includes(cellNumb)) {
        singleCell.classList.add('bomb')

        // 🔽🔽💚 this create green cells

    } else if (!atLeftSide && bombsArray.includes(cellNumb - 1)
        || !atRightSide && bombsArray.includes(cellNumb + 1)
        || bombsArray.includes(cellNumb - gridLength)
        || bombsArray.includes(cellNumb + gridLength)
        || !atLeftSide && bombsArray.includes(cellNumb - gridLength - 1)
        || !atRightSide && bombsArray.includes(cellNumb - gridLength + 1)
        || !atLeftSide && bombsArray.includes(cellNumb + gridLength - 1)
        || !atRightSide && bombsArray.includes(cellNumb + gridLength + 1)
    ) {

        singleCell.classList.add('green');
        singleCell.addEventListener('click', function () {
            addGreenPoints()
        })

         // 🔽🔽💙 this create blue cells (example 55)

    } else if (
        !twoLeftSide && bombsArray.includes(cellNumb - 2)
        // 53
        || !twoRightSide && bombsArray.includes(cellNumb + 2)
        // 57
        //left and right blue cell

        || bombsArray.includes(cellNumb - (gridLength * 2))
        || bombsArray.includes(cellNumb + (gridLength * 2))
        // these are the top/bottom blue cells

        || !twoLeftSide && bombsArray.includes(cellNumb - (gridLength * 2) - 2)
        // ↖↖ Nord-west-west blue cell (33)
        || bombsArray.includes(cellNumb - (gridLength * 2) - 1)
        //  ↖ Nord-west blue cell 34
        || bombsArray.includes(cellNumb - (gridLength * 2) + 1)
        // ↗ Nord-est blue cell 36 
        || !twoRightSide && bombsArray.includes(cellNumb - (gridLength * 2) + 2)
        // ↗↗ Nord-est-est blue cell 37
        || !twoRightSide && bombsArray.includes(cellNumb - gridLength + 2)
        // âž¡ West blue cell 47
        || !twoRightSide && bombsArray.includes(cellNumb + gridLength + 2)
        // ↘ South-est blue cell 67
        || !twoRightSide && bombsArray.includes(cellNumb + (gridLength * 2) + 2)
        // ↘↘ South-est-est blue cell 77
        || bombsArray.includes(cellNumb + (gridLength * 2) + 1)
        // âž¡ Est blue cell 76
        || bombsArray.includes(cellNumb + (gridLength * 2) - 1)
        // ⬅ West blue cell 74
        || !twoLeftSide && bombsArray.includes(cellNumb + (gridLength * 2) - 2)
        // ↙↙ South-west-west blue cell 73
        || !twoLeftSide && bombsArray.includes(cellNumb + gridLength - 2)
        // ⬅ Est blue cell 63
        || !twoLeftSide && bombsArray.includes(cellNumb - gridLength - 2)
        // ⬅ Est blue cell 43

    ) {

        singleCell.classList.add('blue');
        singleCell.addEventListener('click', function () {
            addBluePoints()
        })


    }

Solution

  • To avoid that the code looks at a cell that is at the other end of the board (because crossing the boundary), use modular logic, as follows:

        const atRightSide = (cellNumb + 1) % gridLenght === 0;
        const atLeftSide  = cellNumb % gridLenght === 0;
    

    And then:

        } else if (!atLeftSide && bombsArray.includes(cellNumb - 1)
            || !atRightSide && bombsArray.includes(cellNumb + 1)
            || bombsArray.includes(cellNumb - gridLenght)
            || bombsArray.includes(cellNumb + gridLenght)
            || !atLeftSide && bombsArray.includes(cellNumb - gridLenght - 1)
            || !atRightSide && bombsArray.includes(cellNumb - gridLenght + 1)
            || !atLeftSide && bombsArray.includes(cellNumb + gridLenght - 1)
            || !atRightSide && bombsArray.includes(cellNumb + gridLenght + 1)
        ) {
    
    

    Some other remarks:

    • The correct spelling is "length", not "lenght"
    • bombsArray can better be a Set than an Array

    Remark

    If your numbering of cells does not start with 0, but with 1, then just adapt the definition of the atLeftSide and atRightSide variables:

        const atRightSide = cellNumb % gridLenght === 0;
        const atLeftSide  = cellNumb % gridLenght === 1;