тральщик — неожиданный результат переполнение стека

Я создаю игру Сапер. Тем не менее, при тестировании генерирующей функции, она работает почти всегда (если не всегда), и я не понимаю, почему.

Вот мой код:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>using namespace std;
struct board {
int width=9, mines=10;
char board[9][9];
/* char board[][]
* -1 = Mine
* 0 = No mines near
* 0+ = x amount of mines are near
*/
};
struct point {
int x,y;
};
board newBoard(){
board board1;
point randPoint;
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++) board1.board[i][j]=0; // Initialize array
}
for(int i=0;i<board1.mines;i++){
randPoint.x=rand()%board1.width, randPoint.y=rand()%board1.width; // Where will the mine go?
if(board1.board[randPoint.x][randPoint.y]!=-1){ // If not already a mine
board1.board[randPoint.x][randPoint.y]=-1; //make a mine
} else i--; //else don't count this
}
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++){
if(board1.board[i][j]==-1) { // If mine exists
// The if checks preceding the ++'s are to prevent out of bounds erors
if (j-1>=0) board1.board[i][j-1]++;
if (j+1<board1.width) board1.board[i][j+1]++;
if (i-1>=0) board1.board[i-1][j]++;
if (i+1<board1.width) board1.board[i+1][j]++;
if ((i-1>=0) && (j-1>=0)) board1.board[i-1][j-1]++;
if ((i-1>=0) && (j+1<board1.width))board1.board[i-1][j+1]++;
if ((i+1<board1.width) && (j-1>=0))board1.board[i+1][j-1]++;
if ((i+1<board1.width) && (j+1<board1.width))board1.board[i+1][j+1]++;
}
}
}
return board1;
}

int main() {
board boardGame=newBoard();
printf("-   ");
for(int i=0;i<boardGame.width;i++) printf("%i ",i+1);
printf("\n\n");
for(int i=0;i<boardGame.width;i++){
printf("%i. ",i+1);
for(int j=0;j<boardGame.width;j++) if (boardGame.board[i][j]==-1) {
printf(" X");
} else {
printf(" %i", boardGame.board[i][j]);
}
printf("\n");
}
return 0;
}

Это производит:

-   1 2 3 4 5 6 7 8 9

1.  0 0 0 0 1 X 1 0 0
2.  1 1 0 0 2 2 2 1 1
3.  X 2 1 1 1 X 1 1 X
4.  1 2 X 0 1 1 0 1 1
5.  0 1 1 1 0 0 0 0 0
6.  0 0 0 0 1 1 1 0 0
7.  0 0 1 1 2 X 1 0 0
8.  1 1 2 X 2 1 1 0 0
9.  1 X 2 1 1 0 0 0 0

Как вы, скорее всего, уже знаете, в игре тральщик есть мины (в этом случае они будут помечены как X), и все соседние точки сетки — это количество мин рядом с ним (если вы все еще не знакомы с ним) этот страница может использовать). Как видите, цифры на 4,7 и 4,4 неверны.

Я не знаю, почему это так. Может ли кто-нибудь помочь мне в этом разобраться и рассказать, как это исправить?


Кроме того, я только что заметил, что при каждом запуске он выдает одинаковый вывод. Зачем?

-2

Решение

Я верна, вы не проверяете, является ли ячейка моей, прежде чем увеличивать ее. Однако с учетом того, как настроен ваш код в настоящий момент, это будет означать добавление проверки, что ячейка не равна -1 в каждом операторе if. Вам следует подумать о создании функции для безопасного увеличения ячейки, если она находится в пределах границ, а не шахты, например:

void safeIncrement(int x, int y, board& b)
{
if(x >= 0 && y >= 0 && x < b.width && y < b.width && b.board[x][y] != -1)
{
b.board[x][y]++;
}
}

Это означает, что вы можете заменить свои операторы if на:

safeIncrement(i-1,j,board1);
safeIncrement(i-1,j-1,board1);
safeIncrement(i-1,j+1,board1);
safeIncrement(i,j-1,board1);
safeIncrement(i,j+1,board1);
safeIncrement(i+1,j,board1);
safeIncrement(i+1,j-1,board1);
safeIncrement(i+1,j+1,board1);

Который, на мой взгляд, гораздо более читабелен Кроме того, поскольку функция не увеличивает ячейку, если она моя, вы также можете заменить операторы if следующим кодом!

for(int a=-1; a<=1; a++)
{
for(int b=-1; b<=1; b++)
{
safeIncrement(i+a,j+b, board1);
}
}
2

Другие решения

Проблема возникает, когда 2 мины находятся близко друг к другу: когда вы добавляете количество мин, вы не проверяете, есть ли в этой клетке мина.

Предположим, вы получили мину на (0, 0) и еще одну на (0, 1). Когда вы добавляете к счетчику мин около (0, 0), вы также случайно добавляете к мине в (0, 1), изменяя его с -1 на 0. Это также приводит к исчезновению второй обрабатываемой шахты.

Я предлагаю использовать другое число для обозначения мин, например, -999, и проверять, является ли число отрицательным при поиске. Это проще, чем добавить еще одно условие для всех, если у вас уже есть предложения.

0

По вопросам рекламы [email protected]