I have a few code snippets which may help.
http://www.daniweb.com/code/snippet1019.html
http://www.daniweb.com/code/snippet1034.html
Have a look at the GenerateRandomIntegers2 function. It's easier to follow. You need to generate 20 random numbers from 0 to 99 with no repeats (if you use my method).
However, your method could also work, with some fixing. Here is my guess as to what your problem is (or at least one of them):
if (randNum <= minesLeft)
{
mine [r][c] = true;
minesLeft --;
}
if (randNum > minesLeft)
{
mine [r][c] = false;
}
See red. What if mine[r][c] was already picked as true? You've now "unpicked" it without changing your minesLeft count. Check to see if that is a problem.
VernonDozier
Posting Expert
5,527 posts since Jan 2008
Reputation Points: 2,633
Solved Threads: 711
I'm a little suspicious of the line in red below too.
void Minesweeper::init ()
{
srand((unsigned)time(0));
int minesLeft = 0, cellsLeft = 0, randNum = 0;
// sets minesLeft to the data member numMines
minesLeft = numMines;
//sets cellsLeft to the number of rows and cols in the board
//nrows and ncols are both data members
cellsLeft = nRows * nCols;
while (minesLeft > 0)
{
for (int r = 0; r < nRows; r++)//rows
{
for (int c = 0; c < nCols; c++)//cols
{
//places mines with a probibility of numMines / cellsLeft
randNum = (rand()%cellsLeft)+1;
if (randNum <= minesLeft)
{
mine [r][c] = true;
minesLeft --;
}
/* if (randNum > minesLeft)
{
mine [r][c] = false;
}*/
cellsLeft--;
mark [r][c] = NO_MARK;
}
}
}
}//Minesweeper::init
I commented out what I think you deleted above, and perhaps this red line is now different from before or has a different effect. But it seems to me that, while you have fixed the minesLeft problem, you potentially still have a cellsLeft problem (i.e. you are subtracting a cell WITHOUT subtracting a mine). I think the red line should be inside the if statement ( cellsLeft only adjusted when a new mine is placed), but I'd have to see the updated code.
Also, thanks for using code tags and formatting on your first Daniweb post.
VernonDozier
Posting Expert
5,527 posts since Jan 2008
Reputation Points: 2,633
Solved Threads: 711
the part that you put into red is needed because of the way that the mines are being determined. The mine placement is based on the probability of numMines / cellsLeft the probability increases every time the loop occurs by reducing the number of cells (as it is the number that is working with the random number generator). So every time the loop happens the number of cells decreases, raising the probability of there being a mine on that spot. Below i will put how i ended up fixing the problem.
while (minesLeft > 0)
{
for (int r = 0; r < nRows; r++)//rows
{
for (int c = 0; c < nCols; c++)//cols
{
//pick a random num between 0 and the number of cells left
randNum = (rand()%cellsLeft)+1;
//probibility check.
if (randNum <= minesLeft)
{
mine [r][c] = true;
minesLeft --;
}
cellsLeft--;
}
}
}
thanks again for the help!
Mattwaab;
You are welcome. I understood why you had the line. My point was that I thought it should be here (red below), given that you had the while loop so that you could go through the while loop more than once without cellsLeft being smaller than minesLeft (the while loop confused me):
while (minesLeft > 0)
{
for (int r = 0; r < nRows; r++)//rows
{
for (int c = 0; c < nCols; c++)//cols
{
//pick a random num between 0 and the number of cells left
randNum = (rand()%cellsLeft)+1;
//probibility check.
if (randNum <= minesLeft)
{
if (!mine[r][c])
{
mine [r][c] = true;
minesLeft --;
cellsLeft--;
}
}
}
}
}
It looks like it will work either way, and I think I prefer keeping it outside the if statement as you have it rather than my earlier suggestion, but the way you have it, I think it will always only go through the while loop only once, in which case you can get rid of the while loop to simplify the code (the way you have it now will not lead to any problems; you just have a while loop which only executes once, I think, so it's not really a loop. You'd have problems if it went through MORE than once, but I don't think you do):
// no while loop needed, I don't think
for (int r = 0; r < nRows; r++)//rows
{
for (int c = 0; c < nCols; c++)//cols
{
//pick a random num between 0 and the number of cells left
randNum = (rand()%cellsLeft)+1;
//probibility check.
if (randNum <= minesLeft)
{
//if prob check is true set that mine to true
mine [r][c] = true;
minesLeft --;
}
cellsLeft--;
}
}
VernonDozier
Posting Expert
5,527 posts since Jan 2008
Reputation Points: 2,633
Solved Threads: 711