首页 文章

检查对角线是否在tic tac toe中获胜

提问于
浏览
0

我已经获得了tic tac toe游戏的代码 . 我制作了代码来检查垂直是否会赢,并试图检查对角线 . 我能够检查主对角线,但似乎无法确定如何检查辅助对角线 . 我认为我的代码可以工作,但事实并非如此 . 我所遇到的问题始于第172行

#include <stdio.h>
#include <stdlib.h>  // rand(), srand()
#include <time.h>    // time()

// Size of the board (square)
const int  BOARD_SIZE     = 3;

// Symbols used for the board
const char BLANK_SYMBOL   = ' ';
const char COMP_SYMBOL    = 'O';
const char HUMAN_SYMBOL   = 'X';

// Human goes first
const int  HUMANS_TURN    = 0;
const int  COMPUTERS_TURN = 1;


// Function prototypes
void initializeBoard(char board[BOARD_SIZE][BOARD_SIZE]);
int  hasWon(char board[BOARD_SIZE][BOARD_SIZE], char mark);
int  hasWonHorizontal(char board[BOARD_SIZE][BOARD_SIZE], char mark);
int  hasWonVertical(char board[BOARD_SIZE][BOARD_SIZE], char mark);
int  hasWonDiagonal(char board[BOARD_SIZE][BOARD_SIZE], char mark);
void getComputerMove(char board[BOARD_SIZE][BOARD_SIZE]);
void getHumanMove(char board[BOARD_SIZE][BOARD_SIZE]);
void printBoard(char board[BOARD_SIZE][BOARD_SIZE]);
void clearScreen(void);


//
// The main function should not be changed
//
int main(void) {
   char board[BOARD_SIZE][BOARD_SIZE];
   int  humanWon    = 0; // boolean (0/1)
   int  computerWon = 0; // boolean (0/1)
   int  move        = 0;

   // Seed the random number generator
   srand(time(0));

   initializeBoard(board);

   while ((move < (BOARD_SIZE * BOARD_SIZE)) && !humanWon && !computerWon) {
      clearScreen();

      if ((move % 2) == COMPUTERS_TURN) {
         getComputerMove(board);
      } else {
         printBoard(board);
         getHumanMove(board);
      }

      computerWon = hasWon(board, COMP_SYMBOL);
      humanWon    = hasWon(board, HUMAN_SYMBOL);
      move++;
   }

   clearScreen();
   printBoard(board);

   if (humanWon) {
      printf(">>>> You won!\n");
   } else if (computerWon) {
      printf("<<<< I won!\n");
   } else { // move >= BOARD_SIZE * BOARD_SIZE
      printf("==== A Draw\n");  
   }

   return 0;
}


//
// Initialized the board to all BLANK_SYMBOL
//
void initializeBoard(char board[BOARD_SIZE][BOARD_SIZE]) {
   int row;

   for (row = 0; row < BOARD_SIZE; row++) {
      int col;

      for (col = 0; col < BOARD_SIZE; col++) {
         board[row][col] = BLANK_SYMBOL;
      }
   }
}


//
// Determines if the 'mark' completely fills a row, column, or diagonal
// returns 1 if yes, 0 if no
//
int hasWon(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
   return    hasWonHorizontal(board, mark)
      || hasWonVertical(board, mark)
      || hasWonDiagonal(board, mark);
}


//
// Determines if the 'mark' completely fills a row
// returns 1 if yes, 0 if no
//
int hasWonHorizontal(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
   int won = 0; // boolean (0/1).  Assume lost until proven true
   int row;

   for (row = 0; row < BOARD_SIZE && !won; row++) {
      int match = 1; // boolean (0/1)
      int col;

      for (col = 0; col < BOARD_SIZE; col++) {
         if (board[row][col] != mark) {
            match = 0;
         }
      } 

      won = match;
   }

   return won;
}


//
// Determines if the 'mark' completely fills a column
// returns 1 if yes, 0 if no
//
int hasWonVertical(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
   int won = 0;
   int col;

   for (col = 0; col < BOARD_SIZE && !won; col++) {
      int match = 1;
      int row;

      for (row = 0; row< BOARD_SIZE; row++) {
         if(board[row][col] != mark) {
            match = 0;
         }
      }

      won = match;
   }

   return won; // Stub -- make this return the correct value
}


//
// Determines if the 'mark' completely fills a diagonal
// returns 1 if yes, 0 if no
//
int hasWonDiagonal(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
   int won = 0;
   int match = 1;
   int col;

   for (col = 0; col < BOARD_SIZE && !won; col++) {
      if(board[col][col] != mark) {
         match=0;
      }
      else if(board[BOARD_SIZE-col-1][col] != mark){
         match=0;
      } 
   } 
   won = match;

   return won; // Stub -- make this return the correct value
}


//
// Gets computer move by randomly picking an unoccupied cell
//
void getComputerMove(char board[BOARD_SIZE][BOARD_SIZE]) {
   int row;
   int col;

   do {
      row = rand() % BOARD_SIZE;
      col = rand() % BOARD_SIZE;
   } while (board[row][col] != BLANK_SYMBOL);

   board[row][col] = COMP_SYMBOL;
}


//
// Gets human move by prompting user for row and column numbers
//
void getHumanMove(char board[BOARD_SIZE][BOARD_SIZE]) {
   int rowu;
   int colu;
   printf("Select the value of the row for your move: ");
   scanf("%i", &rowu);
   printf("Select the value of the column for you move: ");
   scanf("%i", &colu);

   board[rowu][colu] = HUMAN_SYMBOL;
}


//
// Prints the board to the screen.  Example:
//
//       0   1   2
//     +---+---+---+
//   0 | X |   |   |
//     +---+---+---+
//   1 |   | O | O |
//     +---+---+---+
//   2 |   |   | X |
//     +---+---+---+
//
void printBoard(char board[BOARD_SIZE][BOARD_SIZE]) {
   printf("   0   1   2\n");
   printf(" +---+---+---+\n");
   printf("0| %c | %c | %c |\n",board[0][0],board[0][1],board[0][2]);
   printf(" +---+---+---+\n");
   printf("1| %c | %c | %c |\n",board[1][0],board[1][1],board[1][2]);
   printf(" +---+---+---+\n");
   printf("2| %c | %c | %c |\n",board[2][0],board[2][1],board[2][2]);
   printf(" +---+---+---+\n");
}



//
// Clears the screen -- uses ANSI terminal control codes
//
void clearScreen(void) {
   const char ESC = 27;

   printf("%c[2J%c[H", ESC, ESC);
}

3 回答

  • 1

    你的代码的逻辑是错误的 . 如果主对角线上的单元格不等于 mark ,则仅检查辅助对角线 .

    您将需要两个单独的变量来跟踪每个对角线上是否有胜利 . 您的代码应如下所示:

    int match_prime = 1, match_second = 1;
    for(col = 0;col < BOARD_SIZE;++col){
        match_prime = board[col][col] == mark;
        match_second = board[BOARD_SIZE - col - 1][col] == mark;
    }
    won = match_prime || match_second;
    
  • 0

    Approach 1

    硬编码对角元素索引 .

    int hasWonDiagonal(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
       int won = 0;
       int match = 0;
    
       if ( ( board[0][0] == mark &&
              board[1][1] == mark &&
              board[2][2] == mark ) &&
            ( board[0][2] == mark &&
              board[1][1] == mark &&
              board[2][0] == mark ) )
    
       {
          match = 1;
       }
       won = match;
    
       return won; // Stub -- make this return the correct value
    }
    

    Approach 2

    使用 for 循环并迭代索引 .

    int hasWonDiagonal(char board[BOARD_SIZE][BOARD_SIZE], char mark) {
       int match = 1;
       int won = 0;
       int row = 0;
    
       // Check the first diagonal.
       for (row = 0; row < BOARD_SIZE && !won; row++) {
          if(board[row][row] != mark) {
             match=0;
          }
       } 
    
       // If the first diagonal check already produces a match,
       // there is no need to check the second diagonal.
       if ( match != 1 )
       {
          int col = BOARD_SIZE-1;
          for (row = 0; row < BOARD_SIZE && !won; row++, col--) {
             if(board[row][col] != mark){
                match=0;
             }  
          } 
       }
       won = match;
    
       return won; // Stub -- make this return the correct value
    }
    
  • 0

    功能可以通过以下方式查看

    //
    // Determines if the 'mark' completely fills a row
    // returns 1 if yes, 0 if no
    //
    int hasWonHorizontal( char board[BOARD_SIZE][BOARD_SIZE], char mark ) 
    {
        int won = 0; // boolean (0/1).  
    
        for ( int row = 0; row < BOARD_SIZE && !won; row++ ) 
        {
            int col = 0;
    
            while ( col < BOARD_SIZE && board[row][col] == mark ) ++col 
    
            won = col == BOARD_SIZE;
        } 
    
        return won;
    }
    
    
    //
    // Determines if the 'mark' completely fills a column
    // returns 1 if yes, 0 if no
    //
    int hasWonVertical( char board[BOARD_SIZE][BOARD_SIZE], char mark ) 
    {
        int won = 0;
    
        for ( int col = 0; col < BOARD_SIZE && !won; col++ ) 
        {
            int row = 0;
    
            while ( row < BOARD_SIZE && board[row][col] == mark ) ++row;
    
            won = row == BOARD_SIZE;     
        }
    
        return won; // Stub -- make this return the correct value
    }
    
    
    //
    // Determines if the 'mark' completely fills a diagonal
    // returns 1 if yes, 0 if no
    //
    int hasWonDiagonal(char board[BOARD_SIZE][BOARD_SIZE], char mark) 
    {
        int won = 0;
        int i = 0;
    
        while ( i < BOARD_SIZE && board[i][i ] == mark ) ++i;
    
        won = i == BOARD_SIZE;
    
        if ( !won )
        {
            i = 0;
            while ( i < BOARD_SIZE && board[i][BOARD_SIZE - i - 1 ] == mark ) ++i;
            won = i == BOARD_SIZE;
        }
    
        return won; // Stub -- make this return the correct value
    }
    

相关问题