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()
})
}
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:
bombsArray
can better be a Set than an ArrayIf 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;