2015-10-26 103 views
-2

我正在創建一個掃雷遊戲。然而,在測試生成函數時,幾乎總是(如果不是總是)出現故障,我不明白爲什麼。意外的結果C++

這裏是我的代碼:

#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),並且附近的所有網格點都是其附近的地雷數量(如果您還不熟悉this頁面可能會用到)。正如你所看到的,4,7和4,4的數字是不正確的。

我不知道這是爲什麼這樣。有人能幫助我理解這一點,並告訴我如何解決這個問題嗎?


此外,我只是注意到,它每次運行時都會產生相同的輸出。爲什麼?

+5

五塊錢說你可以通過調試器走過去,並儘快找出錯誤的位置。 – user4581301

+0

當增加礦山計數器時,你需要檢查礦山是否有礦。你正在挖礦(== -1)並添加一個。 – ioums

+1

「它出現故障」是什麼意思?崩潰?不會崩潰但會給出錯誤的結果? – PaulMcKenzie

回答

2

IOUMS是正確的,您不會在增加它之前檢查單元格是否屬於我的單元格。但是,通過您的代碼當前的設置方式,這意味着在每個if語句中添加一個檢查單元不等於-1。你應該考慮創建一個函數,安全地增加一個細胞,如果它是範圍之內,而不是我的,就像這樣:

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); 
    } 
} 
+0

非常感謝您的安全增量功能。我無法弄清楚如何使它更具可讀性。 –

0

2個地雷靠得很近時會發生問題:當您添加到地雷數量時,您不檢查該地方是否有地雷。

假設你在(0,0)和另一個在(0,1)上得到了一個地雷。當你在(0,0)附近增加礦點數時,你無意中也會在(0,1)中加入礦,並將其從-1改爲0.這也使得正在處理的第二個礦正在消失。

我建議使用另一個數字來表示礦井,例如-999,並在查找時檢查數字是否定的。如果你已經有了子句,那麼比添加另一個條件更容易。