当前位置: 首页 > 知识库问答 >
问题:

检查对角线是否在井字游戏中获胜

韦晟睿
2023-03-14

有人给了我一个井字游戏的代码。我制作了代码来检查垂直方向是否会赢,并尝试检查对角线。我能够检查主对角线,但似乎无法确定如何检查辅助对角线。我以为我拥有的代码会起作用,但事实并非如此。我的问题从第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个答案

童华池
2023-03-14

函数可以如下所示:

//
// 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
}
单于骁
2023-03-14

方法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
}

方法2

用于循环并遍历索引。

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
}
陆洲
2023-03-14

代码的逻辑是错误的。仅当主对角线上的单元格不等于标记时,才检查次要对角线。

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

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;
 类似资料:
  • 请原谅长标题。StackOverflow不会接受较短的。 我试图在科特林制作一个井字游戏。到目前为止,除了对角线检查之外,一切都运行得非常好。 基本上, 函数的作用是创建一个矩阵,其中包含井字棋棋盘中的所有容器,然后检查棋盘的行,列和对角线值是否相等。如果检测到获胜者,该函数会将文本设置为“您获胜”。行和列检查工作正常,但是如果我在对角线上有3个X-s,则没有任何反应。 代码对我来说似乎很好,所以

  • 嗨,我正在编写一个井字游戏。我已经在代码中的注释中详细说明了我需要什么。我现在遇到的问题是制作一个getMobile方法。我想我需要在按下行和列后的if/else语句中调用getMobile方法? 我不确定如何从获取行/列编号并将其放入我的板上以获取用户输入的内容。 以下是我的代码:

  • 我正在制作一个名为SOS的游戏。这是一款3x3的棋盘游戏,与Tic Tac Toe的概念相同,但在这款游戏中,玩家无法选择是以X还是O的身份进行游戏,游戏中唯一的规则是形成“SOS”。 我们的项目应该在所有职位被填补后终止,每个组成的“SOS”将被添加到组成“SOS”的玩家中。 我的问题是关于得分。在第一行输入SOS后,即,我尝试在第二行第一列输入“O”,玩家2将递增。它不应该递增,因为它不满足我

  • 所以我为我的课做了一个抽动练习作业。我已经成功地创建了一个简单的Tic Tac Toe程序,但不知何故,检查绘制的方法有时并不正确。如果所有东西都填满了,但没有赢家,那就是平局。但如果除第0行第1列外,其他所有内容都已填满,则即使该框仍为空白,它仍将显示“Draw”。如果你不明白我的意思,就试着把所有的东西都填满,但不是赢,即使最后一个框没有填满,它也会说“平局”。我在代码中做错了什么????驱动

  • 我用Java写了Tic-Tac-Toe。我似乎遇到的问题是,当(人类)播放器1和(计算机)播放器2之间出现平局时,GUI会冻结。我已经在“Buttonlistener”类和“Methods”中创建了一个tieCheck,以获得一个平局。 我的程序的工作方式是,当按下一个按钮时,它会将一个值传递给methods类中的数组。在这个数组中,1=玩家1,2=玩家2。 人类玩家总是先走,所以当人类玩家走了4

  • 我在Java中创建了一个小TicTacToe游戏,我想编写更有效的代码,我会制作一个for循环来创建9个按钮。 我现在面临的问题是如何测试按下哪个按钮以确定胜利者。我已经注释掉了我的旧测试代码,因为它不再工作。