2016-02-29 29 views
0

這是一個益智遊戲,在4x4網格中必須按順序排列15個編號的圖塊。 大多數情況下,程序運行良好。但是,當將「1」數字交換到第n行,第n-2列時,程序似乎錯誤且重複了數字1.奇怪的錯誤,似乎通過添加額外的代碼行來解決。十五歲的遊戲

這裏有一個問題。當我添加的代碼的隨機行,說

int blah = 0; 

printf("abc"); 

問題只是奇蹟般地消失了。

因爲我無法找到問題的根源,所以我必須發佈它的全部內容。

要只看到問題,運行不帶任何命令行參數的代碼,然後輸入隨後2加1

當我添加的代碼的隨機線在我的main()函數結束,問題消失。請嘗試一下,並幫助我瞭解發生了什麼;這真是令人困惑。

#include <stdio.h> 
#include <stdlib.h> 

int n=4; 
int win(int board[n][n]); 
void print(int board[n][n]); 

int main(int argc, char * argv[]) 
{ 
    if(argc != 2) 
    { 
     printf("No valid number accepted. Board size set as 4x4.\n"); 
    } 
    else if(argc == 2) 
    { 
     n = atoi(argv[1]); 
     if(n<2 || n>5) 
     { 
      printf("No valid number accepted. Board size set as 4x4.\n"); 
     } 
     else 
     { 
      printf("Preparing board of size %dx%d\n",n,n); 
     } 
    } 

    int board[n][n]; 
    printf("\n The aim of the game is to sort the board so that it runs in ascending order, from 1 to %d, from left to right and up to down starting from the top left square. To make a move, enter the number of the tile you want to move. No diagonal movement is allowed.\n\n",n*n-1); 
    int c = n*n-1; 
    for(int x = 0;x<n;x++) 
    { 
     for(int y=0;y<n;y++) 
     { 
      board[x][y] = c; 
      c--; 
     } 
    } 
    if(n%2==0) 
    { 
     int temp1 = board[n-1][n-2]; 
     board[n-1][n-2] = board[n-1][n-3]; 
     board[n-1][n-3] = temp1; 
    } 
    print(board); 
    int spacex = n-1; 
    int spacey = n-1; 
    char buffer[10]; 
    while(win(board) == 0) 
    { 
     printf("To move, enter the number you wish to move. Take note that this number must be adjacent to the blank space. Diagonal movement is not allowed.\nYour move: "); 
     fgets(buffer,10,stdin); 
     int move; 
     char temp[20]; 
     if(sscanf(buffer," %d %s",&move,temp)!= 1) 
     { 
      printf("Enter a number please.\n"); 
      continue; 
     } 
     if(move == board[spacex+1][spacey]) 
     { 
      board[spacex][spacey] = board[spacex+1][spacey]; 
      board[spacex+1][spacey] = 0; 
      spacex++; 
     } 
     else if(move == board[spacex-1][spacey]) 
     { 
      board[spacex][spacey] = board[spacex-1][spacey]; 
      board[spacex-1][spacey] = 0; 
      spacex--; 
     } 
     else if(move == board[spacex][spacey+1]) 
     { 
      board[spacex][spacey] = board[spacex][spacey+1]; 
      board[spacex][spacey+1] = 0; 
      spacey++; 
     } 
     else if(move == board[spacex][spacey-1]) 
     { 
      board[spacex][spacey] = board[spacex][spacey-1]; 
      board[spacex][spacey-1] = 0; 
      spacey--; 
     } 
     else if(move == 0) 
     { 
      printf("Enter a valid digit please.\n"); 
      continue; 
     } 
     else 
     { 
      printf("Enter a valid number please.\n"); 
      continue; 
     } 
     printf("\n"); 
     print(board); 
    } 
    printf("You won!\n"); 
} 
/////////////////////////////////////////////////////// 
void print(int board[n][n]) 
{ 
    for(int x=0;x<n;x++) 
    { 
     for(int y=0;y<n;y++) 
     { 
      if(board[x][y] == 0) 
      { 
       printf("__ "); 
      } 
      else 
       printf("%2d ",board[x][y]); 
     } 
     printf("\n\n"); 
    } 
} 
/////////////////////////////////////////////////////// 
int win(int board[n][n]) 
{ 
    int check = 1; 
    for(int x=0;x<n;x++) 
    { 
     for(int y=0;y<n;y++) 
     { 
      if(board[x][y] != check) 
      { 
       if(x==n-1 && y == n-1); 
       else 
       { 
        return 0; 
       } 
      } 
      check++; 
     } 
    } 
    return 1; 
} 

有關代碼的任何其他意見將不勝感激。提前致謝!

+0

快速瀏覽:你嘗試檢查相鄰瓷磚超過15拼圖的邊界。例如,當'spacex'爲0時,不應該測試索引爲'spacex-1'的左邊的瓦片。 (實際上,當你嘗試它時,你可以環繞左右邊框。) –

+0

@M歐姆謝謝你的回答,我確實已經超出了陣列的界限。但是,添加隨機代碼行時,看似「固定」問題的解釋是什麼? –

+1

@Quek - 未定義的行爲*任何事情都可能發生,包括產生預期的輸出。沒有必要有任何真正的解釋。 –

回答

0

代碼正在讀取越界。

這兩個變量指向陣列board的最後元素:

int spacex = n-1; 
    int spacey = n-1; 

但在所有的if語句使用不正確。只要使用一個+1,他們會讀出範圍,或者讀一個不正確的元素:

if(move == board[spacex+1][spacey]) 
{ 
    board[spacex][spacey] = board[spacex+1][spacey]; 
    board[spacex+1][spacey] = 0; 
    spacex++; 
} 
else if(move == board[spacex-1][spacey]) 
{ 
... 
else if(move == board[spacex][spacey+1]) 
{ 
    board[spacex][spacey] = board[spacex][spacey+1]; 
... 
+0

謝謝你的回答;我沒有意識到這一點。我將不得不實施某種形式的邊界檢查。然而,當我添加一個隨機的代碼行時,看似「固定」問題的解釋是什麼? –

+0

@QuekYufei未定義的行爲。在代碼正確之前,討論它的行爲是沒有意義的。 – 2501