提问者:小点点

井字交趾更好的方式找到匹配的符号和赢家?


我是一个编码的初学者,这是我所创建的最复杂的代码,我是一个简单的井字游戏,我在问是否有更好的方法来找到匹配的X和O

string getWinner(string _gameBoard[ROW][COL]) // get the winner
{
    

    for (int i = 0; i < ROW; i++)
        {
            if (_gameBoard[i][0] != " " && _gameBoard[i][0] == _gameBoard[i][1] && _gameBoard[i][1] == _gameBoard[i][2])
                return _gameBoard[i][0]; //horizontal match
        }
    
        for (int j = 0; j < COL; j++)
        {
            if (_gameBoard[0][j] != " " && _gameBoard[0][j] == _gameBoard[1][j] && _gameBoard[1][j] == _gameBoard[2][j])
                return _gameBoard[0][j]; //vertical match
        }
    
        if (_gameBoard[0][0] != " " && _gameBoard[0][0] == _gameBoard[1][1] && _gameBoard[1][1] == _gameBoard[2][2])
            return _gameBoard[0][0]; // diagonal match // upper left to lower right
    
        if (_gameBoard[2][0] != " " && _gameBoard[2][0] == _gameBoard[1][1] && _gameBoard[1][1] == _gameBoard[0][2])
            return _gameBoard[2][0]; // diagonal match // upper lower left to upper right
    
        return "";
    }

共1个答案

匿名用户

首先,您最好将游戏板保持为字符的2D数组,因为字符串很重,而且没有必要。

接下来,正如我在评论中建议的,您可以像那样将所有逻辑拆分成单独的函数。 不要害怕它们返回奇怪的std::pair这只是从一个函数返回两个值的一种方法(技术上它返回一个值,但是它有一个bool和一个char)。 布尔值对应于检查后是否找到胜利者,字符对应于胜利者的字符(如果有的话)。

在每个函数中都有一个循环。 这个循环比较第i'个元素和第0'个元素。 如果有一次你发现它们不相等,那么整个行/列/对角线都不相等,所以我们返回没有赢家。 如果函数到达终点,则意味着所有值都相等,因此存在赢家。

getWinner然后调用所有函数并决定谁是最终赢家。

std::pair<bool, char> checkRow(char gameBoard[ROW][COL], int rowId) {
  for (int i = 1; i < COL; ++i) {
    if (gameBoard[rowId][i] != gameBoard[rowId][0]) {
      return std::make_pair(false, ' '); // false indicates no winner on this row 
    }
  }
  return std::make_pair(true, gameBoard[rowId][0]); // true indicates there is a winner
}

std::pair<bool, char> checkCol(char gameBoard[ROW][COL], int colId) {
  for (int i = 1; i < ROW; ++i) {
    if (gameBoard[colId][i] != gameBoard[colId][0]) {
      return std::make_pair(false, ' '); // false indicates no winner on this col 
    }
  }
  return std::make_pair(true, gameBoard[colId][0]); // true indicates there is a winner
}

std::pair<bool, char> checkDownDiagonal(char gameBoard[ROW][COL]) {
  for (int i = 1; i < COL; ++i) {
    if (gameBoard[i][i] != gameBoard[0][0]) {
      return std::make_pair(false, ' '); // false indicates no winner on this diagonal 
    }
  }
  return std::make_pair(true, gameBoard[0][0]); // true indicates there is a winner
}

std::pair<bool, char> checkUpDiagonal(char gameBoard[ROW][COL]) {
  for (int i = 1; i < COL; ++i) {
    if (gameBoard[ROW-1-i][i] != gameBoard[ROW-1][0]) {
      return std::make_pair(false, ' '); // false indicates no winner on this diagonal 
    }
  }
  return std::make_pair(true, gameBoard[0][0]); // true indicates there is a winner
}

std::pair<bool, char> getWinner(char gameBoard[ROW][COL]) {
  auto downDiag = checkDownDiagonal(gameBoard);
  if (downDiag.first) return downDiag; // `first` is flag if there's a winner
  
  auto upDiag = checkUpDiagonal(gameBoard);
  if (upDiag.first) return upDiag;
  
  for(int i = 0; i < ROW; ++i) {
    auto rowCheck = checkRow(gameBoard, i);
    if (rowCheck.first) return rowCheck;
  }

  for(int i = 0; i < COL; ++i) {
    auto colCheck = checkRow(gameBoard, i);
    if (colCheck.first) return colCheck;
  }
  return std::make_pair(false, ' ');
}