Search code examples
javascriptalgorithmminesweeper

javascript minesweeper floodfill algorithm not working as it should


I'm trying to write my first simple minesweeper game. For revealing empty fields I wrote a simple flood fill algorithm, however it isn't working as it should. Here's a snippet of code:

function reveal(a,b){
var fieldId = getFieldId(a,b);  

/*
cells are stored in array fields[]. Each cell is an object {x: x,y: y, hasBomb: boolean,
hasBeenDiscovered: boolean}. Function getFieldId returns array key for (x,y) cell.
*/

if(a < 0 || a > boardWidth-1){return}
if(b < 0 || b > boardHeight-1){return}

if(fields[fieldId].hasBeenDiscovered == true){return}

if(getNeighbourNumber(a,b) > 0){
    document.getElementById(a+'x'+b).innerHTML = getNeighbourNumber(a,b);
    document.getElementById(a+'x'+b).style.backgroundColor = 'white';
    document.getElementById(a+'x'+b).setAttribute('discovered',1);
    fields[fieldId].hasBeenDiscovered = true;
    return
}else if(getNeighbourNumber(a,b) == 0){
    document.getElementById(a+'x'+b).innerHTML = ' ';
    document.getElementById(a+'x'+b).style.backgroundColor = 'white';
    document.getElementById(a+'x'+b).setAttribute('discovered',1);  
    fields[fieldId].hasBeenDiscovered = true;


}

    reveal(a,b);
    console.log('0 ' + '0');
    reveal(a+1,b);
    console.log('+1' + ' ' + '0');
    reveal(a-1,b);
    console.log('-1 ' + '0');
    reveal(a,b+1);
    console.log('0 ' + '+1');
    reveal(a,b-1);
    console.log('0 ' + '-1');
    reveal(a-1,b-1);
    console.log('-1 ' + '-1');
    reveal(a-1,b+1);
    console.log('-1 ' + '+1');
    reveal(a+1,b+1);
    console.log('+1 ' + '+1');
    reveal(a+1,b-1);
    console.log('+1 ' + '-1');
    console.log('------------');

}

When discovering empty cell which north, northwest and west neighbours has neighbours bombs, floodfill reveal just those cells, even if other neighbours (south, south east west, east, northeast) are empty. I'm beginner coder and I can't figure out why this code isn't fully working. Any help will be greatly appreciated :)

Edit: console logs were put in just for debug attempt.


Solution

  • I am happy to say that you wrote an awesome code it was so easy to read and understand the code.

    You just need to check a small thing in the revealField function, Here one thing you need to remember is when you get value from the attribute it will give you in string always, so you need to parse the string to number with the decimal base.

    function revealField(){
        var x = this.getAttribute('x');
        var y = this.getAttribute('y');
        x = parseInt(x, 10);
        y = parseInt(y, 10);
    
        var fieldId = getFieldId(x,y);
    
        if(fields[fieldId].hasBomb == true){
            document.getElementById(x+'x'+y).innerHTML = 'B';
            this.style.backgroundColor = 'brown';
            this.setAttribute('hasBomb', 1);
            removeEvents();
            alert('Bomba! Przegrales!');
        }else{
            this.style.backgroundColor = 'white';
            this.setAttribute('discovered',1);
            reveal(x,y);
            if(validateVictory() == true){
                removeEvents();
                alert('Brawo! Odkryles wszystkie bomby!');          
            }   
        }
    }
    

    Here is your updated fiddle aswell