2016-02-29 33 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