Search code examples
javascriptjqueryhtmlminesweeper

Minesweeper reveal nearby tiles function


I am trying to make the blank or "0" function of ms in a web page.

The goal:

what happens in mine: what should happen:

the red square indicates the button that was clicked, and the green circles indicate its adjacent squares/tiles.

My approach or logic to make this function was:

  • step1: if the button that was clicked is a 0, reveal its adjacent tiles.
  • step 2: for every adjacent tile, if THAT tile is 0, reveal THAT TILES' adjacent tiles. and so on until all adjacent tiles of every connected 0 is revealed.

The code of my function: (the parameters are the coordinates of the button that is clicked. e.g.the red square/tile in the picture above has coordinates 3,6)

function RevealNearbyTiles(y,x){

    var cordsx;                     //cordsx and cordsy represent the adjacent tiles of the coordinates (the parameters).
    var cordsy;                             
    var coordinates; 
    for(i=-1; i<2; i++){   //for every adjacent tile:
        for(j=-1;j<2;j++){
            cordsx = x;
            cordsy = y;
            if(i === 0 && j === 0){    
                continue;
            }
            else{
                cordsx += j; 
                cordsy += i;
                //if this ^ offset is within the grid:
                if((cordsx >= 0 && cordsx < 10) && (cordsy >= 0 && cordsy < 10)){
                    //the coordinates of the tile.
                    coordinates = $("#mstable tr:nth-of-type("+(cordsy+1)+") td:nth-of-type("+(cordsx+1)+") .tiles");
                    //if it has not been revealed
                    if(coordinates.parent().attr("data-revealed") === "false"){
                        //reveal this coordinate.   
                        coordinates.empty().append("<p id='number'>"+coordinates.parent().attr("data-value")+"</p>");                           
                        coordinates.parent().attr("data-revealed", "true");
                        //if this coordinate is 0
                        if(coordinates.parent().attr("data-value") === " "){
                            //reveal this coordiantes' nerabytiles
                            RevealNearbyTiles(cordsy,cordsx);
                        }

                    }       
                }
            }  
        }
    }
}

The attribute "data-value" is the number of nearby bombs the tile has. The attribute "data-revealed" is true if the tile is revealed, or false if it's not. They both work, don't worry too much about them.

The code for every tile button:

$(".tiles").click(function(){
        //if this button is clicked, reveal this tile
        $(this).empty().append("<p id='number'>"+$(this).parent().attr("data-value")+"</p>");
        $(this).parent().attr("data-revealed","true");
        //if this tile's value is 0, call the function
        if($(this).parent().attr("data-value") === " "){
            RevealNearbyTiles($(this).parent().data("index").a,$(this).parent().data("index").b);
        }
    });

What I think the problem is: The for loop is supposed to run for every adjacent tile of the tile that was clicked, but when it runs the function for the first tile, it forgets about all other adjacent tiles. I need to make it so that the function runs on all adjacent tiles that are 0, and on all of THEIR adjacent tiles that are 0 and so on.

Thanks for your help, its a hard problem to explain =/. I searched many places but could not find an answer. Sorry for the very long and specific problem.


Solution

  • I think the issue is with your two for loops, they use global vars called i and j which are the same for each call to RevealNearbyTiles(). You can fix this with the following code...

    for(var i=-1; i<2; i++){   //for every adjacent tile:
        for(var j=-1;j<2;j++){
    

    I think what happened was that your algorithm ran until it hit the case where it had revealed all adjacent tiles (e.g. i = 1, j = 1), it then exited up the call chain with those values and exited each loop rather than keep executing them.