2
\$\begingroup\$

I am trying to build a simple minesweeper game. The game gets stuck in an infinite recursion whenever a user clicks on a tile which is not a mine...

I have used the following function code for the click event..

When a user clicks on a tile which is not a mine, its adjacent tiles are to be checked for a mine and the process repeats.... I have used a recursive function which disables the tiles for which adjacent tile is not a mine...

  protected void set_text_of_button(Button btn)
  {
      //all these objects specify the location of adjacent tiles
      Block Top, Top_Left, Top_Right, Left, Right, Bottom, Bottom_Left, Bottom_Right;

      //code to specify the location of adjacent tiles...



      //if adjacent tile is a mine then display the total number of tiles....
      //recursive function should end in this if part..


      else
      {
      //recursive calls for all the adjacent tiles..

              if (Top != null && !Top.Mine)
                  set_text_of_button(Top.btn);         //recursive call
              if (Top_Left != null && !Top_Left.Mine)
                  set_text_of_button(Top_Left.btn);
              if (Top_Right != null && !Top_Right.Mine)
                  set_text_of_button(Top_Right.btn);
              if (Left != null && !Left.Mine)
                  set_text_of_button(Left.btn);
              if (Right != null && !Right.Mine)
                  set_text_of_button(Right.btn);
              if (Bottom.btn != null)
                  set_text_of_button(Bottom.btn);
              if (Bottom_Left.btn != null)
                  set_text_of_button(Bottom_Left.btn);
              if (Bottom_Right.btn != null)
                  set_text_of_button(Bottom_Right.btn);


      }
  }

can the following code be implemented or is there a better algorithm to perform the task...

\$\endgroup\$
3
  • \$\begingroup\$ You should use a debugger.. \$\endgroup\$
    – bummzack
    Commented Mar 10, 2012 at 9:44
  • \$\begingroup\$ m still not able to remove the bug..... it says System.StackOverflowException Code \$\endgroup\$ Commented Mar 10, 2012 at 10:00
  • \$\begingroup\$ @TanujWadhwa I poked at your code some more and expanded my answer with some additional points that might interest you. \$\endgroup\$
    – Anton
    Commented Mar 10, 2012 at 10:41

3 Answers 3

8
\$\begingroup\$

I can't tell from your (lack of) code, but you are probably just missing a stop to make sure that you don't handle tiles which have already been handled. At the top of the function you should put something like:

if(thistile.hasbeenhandled){
    return;
}
else{
    thistile.hasbeenhandled=true;
}

Otherwise any two adjacent tiles that are to display empty will keep on asking one another to update.

\$\endgroup\$
3
  • \$\begingroup\$ even if i do that... the application stops responding without even raising an exception. \$\endgroup\$ Commented Mar 10, 2012 at 9:32
  • \$\begingroup\$ the complete solution of the app :: link \$\endgroup\$ Commented Mar 10, 2012 at 9:34
  • \$\begingroup\$ thanx @eBusiness. \$\endgroup\$ Commented Mar 10, 2012 at 10:56
5
\$\begingroup\$

eBuisiness's answer is correct. But you're setting the HasBeenHandled flag after trying to update all the neighbors which then causes a stack overflow. You should instead set the flag before doing anything else.

EDIT: You've also made typos in the if statements.

  if (Bottom.btn != null)
      set_text_of_button(Bottom.btn);
  if (Bottom_Left.btn != null)
      set_text_of_button(Bottom_Left.btn);
  if (Bottom_Right.btn != null)
      set_text_of_button(Bottom_Right.btn);

should be

  if (Bottom != null)
      set_text_of_button(Bottom.btn);
  if (Bottom_Left != null)
      set_text_of_button(Bottom_Left.btn);
  if (Bottom_Right != null)
      set_text_of_button(Bottom_Right.btn);

Also, you'll need to stop this habit of initializing variables by allocating dummy objects. It is better to assign null than create a new object you're not going to use. For example, your find_by_coordinates function would be better written as

  protected Block find_by_coordinates(int x,int y)
  {
      Block return_value = null;
      foreach (Block blk in arr_buttons)
      {
          if (blk.x == x && blk.y == y)
          {
              return_value = blk;
              break;
          }
      }
      return return_value;
  }

Now, when the coordinate has no button a null value is returned instead of a dummy Block object which was leading to NullReferenceExceptions because the program was trying to work with these dummy objects.

\$\endgroup\$
3
  • \$\begingroup\$ "eBuisiness' answer is correct." I think I'll save that quote for later use. ;-) \$\endgroup\$ Commented Mar 10, 2012 at 10:22
  • \$\begingroup\$ @eBuisiness Happy to oblige :) \$\endgroup\$
    – Anton
    Commented Mar 10, 2012 at 10:33
  • \$\begingroup\$ hmmm okayz..... Thanks @AntonMårtensson. I will definitly take care about it in future. \$\endgroup\$ Commented Mar 10, 2012 at 10:51
0
\$\begingroup\$

Your code is ok. I've created my own minesweeper for fun and did the same thing. However I would suggest leaving out the corner tiles ( the adjacent ones ) out. This will make it easier for you to create your algorithm. So instead of 8 tiles it will only check 4.

Basically the easiest way to make your check up stop is to add something to an array, and while this array is not empty, do more check ups:

click tile 

 > tile is safe? > add to openList ( an array)
 > else gameover

  -while openList is not empty
    -pop tile in array and check adjacent tiles.
     -for every adjacent is safe add to array.

The while loop will automatically stop if the openList is empty. For every tile added to the openlist you also remove its click mechanic.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .