【问题标题】:Declaring winner in tic tac toe board在井字游戏中宣布获胜者
【发布时间】:2015-09-04 17:29:56
【问题描述】:

我为井字游戏问题编写了一个代码,您将数字输入到数组中,然后将打印出棋盘。还有一个宣布获胜者的函数,但似乎不起作用,该函数应该宣布任何尺寸的井字棋棋盘的获胜者(现在是 5x5)。

我做了一个双循环,它检查数组中的字符是否与它旁边的字符相同,所以它沿着行移动,还有另一个用于列,一个对角线和另一个。出于某种原因,它没有显示任何赢家,总是没有赢家出现。任何帮助表示赞赏。

#include <stdio.h>

#define TRUE 1
#define FALSE 0

#define SIZE 3

#define NONE -1
#define NOUGHTS 0
#define CROSSES 1
#define EMPTY 2

void  scanBoard(int board[SIZE][SIZE]);
void printBoard(int board[SIZE][SIZE]);
int   getWinner(int board[SIZE][SIZE]);

int main( void ){

  int board[SIZE][SIZE];
  int winner;

   printf("Please enter the board:\n");
   scanBoard( board );

   printf("Here is the board:\n");
   printBoard( board );

  printf("The winner is: ");

   winner = getWinner(board);

  if(winner == CROSSES){
printf("Crosses");
}
  else if(winner == NOUGHTS){
printf("Noughts");
}
  else{
printf("No one");
}
return 0;
}

void scanBoard(int board[SIZE][SIZE]){

int i;
int j;

for(i=0; i<SIZE; i++){
    for(j=0; j<SIZE; j++){
        scanf("%d", &board[i][j]);
    }
}
}

void printBoard(int board[SIZE][SIZE]){

int i;
int j;

for(i=0; i<SIZE; i++){
    for(j=0; j<SIZE; j++){
        if(board[i][j] == EMPTY){
            printf(". ");
        }
        else if(board[i][j] == CROSSES){
            printf("X ");
        }
        else if(board[i][j] == NOUGHTS){
            printf("O ");
        }
    }   
    printf("\n");   
}

}

int   getWinner(int board[SIZE][SIZE]){

int i;
int j;
int check;
int winner;

for(i=0; i<SIZE; i++){
    for(j=0; j<SIZE-1 && check == TRUE; j++){
        if(board[i][j] != board[i][j+1]){
            check = FALSE;
        }
    }
    if(check == TRUE && j == SIZE-1){
        winner=board[i][0];
    }
}
for(j=0; j<SIZE; j++){
    for(i=0; i<SIZE-1 && check == TRUE; i++){
        if(board[i][j] != board[i+1][j]){
            check = FALSE;
        }
    }
    if(check == TRUE && i == SIZE-1){
        winner=board[0][j];
    }
}
for(i=0; i<SIZE-1 && check == TRUE; i++){
    if(board[i][i] != board[i+1][i+1]){
        check = FALSE;
    }
    if(check == TRUE && i == SIZE-1){
        winner=(board[i][i]);
    }
}
for(i=SIZE; i>0 && check == TRUE; i--){
    if( board[i][i] != board[i-1][i-1])
        check = FALSE;
}
    if(check == TRUE && i == SIZE-1){
    winner=(board[i][i]);
}
return winner;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    我没有完全通过您的检查逻辑,但直接在getWinner 中,您正在触发未定义的行为:

      for(j=0; j<SIZE-1 && check == TRUE; j++){
    

    通过读取 check 变量尚未初始化(结果是任何类型的行为都可能发生)。因此,您可能需要先将其初始化为默认值。

    该游戏有一些实现,我建议您查看一些similar 实现并与您的获胜者检查逻辑进行比较。

    【讨论】:

    • 谢谢,只是需要让 check=TRUE 做的额外一点。
    • 1) 感谢您发布实际编译干净的代码。 2)请为了我们人类轻松阅读/理解代码,一致缩进。建议在每个左大括号 '{' 之后使用 4 个空格,并在每个右大括号 '}' 之前取消缩进 切勿使用制表符,因为每个文字处理器/编辑器的制表位/制表符宽度设置不同。注意:4 个空格足够宽,因此缩进在可变宽度字体中仍然可见
    • check == TRUE 这样的比较几乎总是一个坏主意。 (在这种情况下,我们知道 TRUE 等于什么)通常,任何非 0 都是 TRUE。所以通常最好这样说:if( check )if( check != FALSE )
    【解决方案2】:

    正如 Giorgi 指出的,您必须在开始测试其值之前初始化 check。您还需要在getWinner() 函数的开头将winner 初始化为EMPTY,否则如果没有获胜者,您的函数将返回一些不可预测的垃圾值并且您的main() 函数可能会打印出错误的结果.

    int getWinner(int board[SIZE][SIZE]){
      int i;
      int j;
      int check;
      int winner=EMPTY /* <<< */;
    
      for(i=0; i<SIZE; i++){
        for(j=0, check=TRUE /* <<< */; j<SIZE-1 && check == TRUE; j++){
          if(board[i][j] != board[i][j+1]){
            check = FALSE;
          }
        }
        if(check == TRUE && j == SIZE-1){
          winner=board[i][0];
        }
      }
      for(j=0; j<SIZE; j++){
        for(i=0, check=TRUE /* <<< */; i<SIZE-1 && check == TRUE; i++){
          if(board[i][j] != board[i+1][j]){
            /** etc... **/
    

    (注意:一旦您找到了获胜者,也无需继续检查,因此您可能只需要return board[i][j]; 而不是return board[i][j];。不过没什么大不了的。)

    您还检查了其中一条对角线两次(在两个不同的方向上)。根本没有检查另一条对角线。

    【讨论】:

    • 感谢您的帮助,在第二个 for 循环工作之前,它似乎正在初始化 check=true。我现在要研究对角线,但我想我现在明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多