I am trying to program minesweeper, and I'm not having too much trouble except in where you try to clear all the zeroes from a section you enter the coordinates to. I had one method that almost worked, but it failed when the program went to a new line, so I tried a recursive function to search for all the zeroes connected to one zero. When I tried this, I ended up with more problems than before, so I've tried outputting what's happening and it seems that after going through two layers of recursion, the program just stops and goes back to the start without searching all possible connections. What's wrong with this?
//gives regions of zeroes in minesweeper zones
//so that they can be cleared all at once
void Minesweeper::zone()
{
//declare variables
int zone = 1;
//start zoning
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < columns; x++)
{
//only search neighboring cells if current cell
//has no zone and no neighboring bombs
if(board[x][y][DISPLAY] == 0 && board[x][y][ZONES] == 0)
{
//don't check this cell again
board[x][y][ZONES] = zone;
//search all neighboring cells
search(x, y, zone);
//next occurrences will have different zone
zone++;
}//end if
}//end for
}//end for
//zone non-zeroes
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < columns; x++)
{
//if cell has no neighboring bombs
//force zone upon all neighboring cells
if(board[x][y][DISPLAY] == 0 && board[x][y][ZONES] != 0)
{
//declare temps
int aMin;
int aMax;
int bMin;
int bMax;
//get mins and maxes
//was originally a switch statement
//but rows and columns are not constants
if(x == 0)
{
aMin = 0;
aMax = 1;
}
elseif(x == columns - 1)
{
aMin = -1;
aMax = 0;
}
else
{
aMin = -1;
aMax = 1;
}//end ifs
if(y == 0)
{
bMin = 0;
bMax = 1;
}
elseif(y == rows - 1)
{
bMin = -1;
bMax = 0;
}
else
{
bMin = -1;
bMax = 1;
}//end ifs
zone = board[x][y][ZONES];
for(int b = bMin; b <= bMax; b++)
{
for(int a = aMin; a <= aMax; a++)
{
//put zones of both cells into
//stringstream objects so that they
//can be concatenated
stringstream z;
stringstream find;
z << board[a + x][b + y][ZONES];
find << zone;
//if zone of neighbor cell does not contain
//zone of initial, neighbor has a bomb as a
//neighbor, and neighbor already has a zone
if(int(z.str().find(find.str(), 0)) < 0 && board[a + x][b + y][DISPLAY] != 0 && board[a + x][b + y][ZONES] != 0)
{
//concatenate two zones into one
//for neighbor cell
stringstream s;
s.str(z.str() + find.str());
stringstream(s.str()) >> board[a + x][b + y][ZONES];
}
//if cell has a bomb as a neighbor and
//does not meet previous requirements
elseif(board[a + x][b + y][DISPLAY] != 0)
board[a + x][b + y][ZONES] = zone;
//end ifs
//clear objects for next use
z.str("");
find.str("");
}//end for
}//end for
}//end if
}//end for
}//end for
}//end zone
/*Recursive method meant to search all cells
around a cell for zeroes to add to the region
of the initial cell being searched around*/
/*This method calls itself once before returning to the
calling method (not search) without reading any more
lines of search*/
void Minesweeper::search(int xPos, int yPos, int z)
{
//declare variables
int xMin;
int xMax;
int yMin;
int yMax;
//get mins and maxes
//these were originally a switch statement
//but rows and columns are not constants
if(xPos == 0)
{
xMin = 0;
xMax = 1;
}
elseif(xPos == columns - 1)
{
xMin = -1;
xMax = 0;
}
else
{
xMin = -1;
xMax = 1;
}//end ifs
//get mins and maxes
//same as above mins and maxes
if(yPos == 0)
{
yMin = 0;
yMax = 1;
}
elseif(yPos == rows - 1)
{
yMin = -1;
yMax = 0;
}
else
{
yMin = -1;
yMax = 1;
}//end ifs
for(int y = yMin; y <= yMax; y++)
{
for(int x = xMin; x <= xMax; x++)
{
//only search all neighboring cells if this cell
//has no zone and zero neighboring bombs
if(board[xPos + x][yPos + y][DISPLAY] == 0 && board[xPos + x][yPos + y][ZONES] == 0)
{
//give cell a zone so that it will
//not be checked multiple times
board[xPos + x][yPos + y][ZONES] = z;
//search all neighboring cells
search(x, y, z);
}//end if
}//end for
}//end for
}//end search
RowBombCount (x, y, bool is_midst)
{
count = 0
if x > 0
if board[x - 1][y] == bomb
++count;
if is_midst
if board[x][y] == bomb
++count;
if x < MaxX - 1
if board[x + 1][y] == bomb
++count;
return count;
}
SetNeighbouringBombCount (x, y)
{
count = RowBombCount(x, y, false)
if y > 0
count += RowBombCount(x, y - 1, true)
if y < MaxY - 1
count += RowBombCount(x, y + 1, true)
board[x][y] = count
}
I've already finished that part. The part I'm working on now is when there are no neighboring bombs and I want to clear a whole section of neighboring bombs. My method for counting neighboring bombs works, but my method for putting large sections with no neighboring bombs into zones so that they can all be cleared at once is not working.
bool SetFreeRow(x, y)
{
has_free = false;
if board[x][y] != bomb
free_board[x][y] = true
has_free = true
go_left = true
go_right = truefor i = 1 -> i < MaxX
if go_left
free_index_left = x - i
go_left = free_index_left >= 0
if go_left
go_left = board[free_index_left][y] != bomb
if go_left
free_board[free_index_left][y] = true
has_free = trueif go_right
free_index_right = x + i
...
if not go_right and not go_left
breakreturn has_free
}
SetSurroundingFree(x, y)
{
if SetFreeRow(x, y)
for i = y - 1 -> i >= 0 --i
if not SetFreeRow(x, i)
breakfor i = y + 1 -> i < MaxY ++i
if not SetFreeRow(x, i)
break
}
The algorithm for 'go_right' is almost the same as for 'go_left'
Are you able to read that pseudo code?
I think I get what you're saying, but you're missing the second dimension. If it's only looking left and right, then I'm only going to be able to clear part of a line. My search method is intended to set zones for odd shapes. I think I may have just figured out how to fix my code, but it worries me that my recursive method is skipping out for no reason that I can see.