我正在使用类编写这个井字游戏程序。我编写了这个名为 makeAMove()
的函数。这个函数应该验证玩家的移动,但它一直显示它是一个无效的移动并要求玩家重新输入。可能有一些逻辑错误,但我只是没有看到它们。谁能帮忙?这是一个使用名为 Cell board[ROW][COL]
的对象和另一个名为 Player players[2]
的对象的类。标记是 X
或 O
,而 iVal
是棋盘的初始值(棋盘上的每个单元格都有一个从 1 开始的数字- 9)。此处包含winGame()
和switchPlayer()
供您引用。虽然我认为我的 winGame()
函数没问题,但我知道我可以使用求和来做到这一点。换句话说,每个单元格都有内部标记,如 -1 或 1,如果行、列等的总和为 -3 或 3,则对应于玩家的内部标记将输出赢家。如果您对如何执行此操作有任何见解,请随时分享,否则,我的 winGam
e 就可以了。
int TicTacToe::switchPlayer(){
if ( currentPlayer == 0)
currentPlayer = 1;
else if ( currentPlayer == 1 )
currentPlayer = 0;
return (currentPlayer);
}
//
//method to make a move
//
void TicTacToe::makeAMove(){
char move;
int turns = 1;
do{
cout << "Player " << (getCurrentPlayer() + 1) << " make a move." << endl;
cin >> move;
for ( int i = 0; i < ROW; i++ ){
for ( int j = 0; j < COL; j++ ){
//This is where my problem begins
if ( board[i][j].getiVal() == move ){
board[i][j].setiVal( players[currentPlayer].getMarker());
DrawBoard();
switchPlayer();
turns++;
}
else if ( board[i][j].getiVal() == 'X' || board[i][j].getiVal() == 'O'){
cout << "Invalid move, please reenter. " << endl;
cin >> move;
}//the else if statement always outputs:x
}
}
} while ( turns <= 9 || !winGame() );
cout << "Congratulations " << ( getCurrentPlayer() + 1 ) << "you won the game!" << endl;
}
bool TicTacToe::winGame(){
bool validate = false;
int k = 0;
for ( int i = 0; i < ROW; i++ ){
//check column wins
if ( board[0][i].getMarker() == board[1][i].getMarker() && board[1][i].getMarker() == board[2][i].getMarker()){
players[currentPlayer].setNumWin(k++);
validate = true;
break;
}
//check row wins
else if ( board[i][0].getMarker() == board[i][1].getMarker() && board[i][1].getMarker() == board[i][2].getMarker()){
players[currentPlayer].setNumWin(k++);
validate = true;
break;
}
}
if( board[0][0].getMarker() == board[1][1].getMarker() && board[1][1].getMarker() == board[2][2].getMarker()){
players[currentPlayer].setNumWin(k++);
validate = true;
}
else if ( board[0][2].getMarker() == board[1][1].getMarker() && board[1][1].getMarker() == board[2][0].getMarker()){
players[currentPlayer].setNumWin(k++);
validate = true;
}
return (validate);
}
这是程序的示例运行
+--+--+--+
|1 |2 |3 |
+--+--+--+
|4 |5 |6 |
+--+--+--+
|7 |8 |9 |
+--+--+--+
Player 1 make a move.
1
+--+--+--+
|O |2 |3 |
+--+--+--+
|4 |5 |6 |
+--+--+--+
|7 |8 |9 |
+--+--+--+
Player 2 make a move.
5
Invalid move, please reenter.
6
+--+--+--+
|O |2 |3 |
+--+--+--+
|4 |5 |X |
+--+--+--+
|7 |8 |9 |
+--+--+--+
Player 1 make a move.
最佳答案
这里的逻辑错误可以归纳为:
for ( int i = 0; i < ROW; i++ ){
for ( int j = 0; j < COL; j++ ){
if ( board[i][j].getiVal() == move ){
// Not important what happens here
}
else if ( board[i][j].getiVal() == 'X' || board[i][j].getiVal() == 'O'){
cout << "Invalid move, please reenter. " << endl;
// Not important what happens here
}
这里可以使用“Rubber Duck”方法进行调试来识别逻辑错误。
“橡皮鸭”调试方法涉及将橡皮鸭(漂浮在浴缸中的那种)放在显示器屏幕旁边,然后尝试向橡皮鸭解释您的代码在做什么,然后您继续解释,直到您自己弄清楚问题为止。
在这里,您将首先向您的橡皮鸭解释您的代码将扫描井字游戏矩阵,一次一行,一次一列,从左上角开始,并在右下角结束。这就是嵌套 for 循环在这里所做的。
橡皮鸭会同意的,你继续解释这段代码。
现在您将告诉您的橡皮鸭,您的代码将继续扫描井字棋盘,直到它看到 move
或 X
或 O
在它正在扫描的当前位置。如果它看到 X
或 O
,您的代码将提示移动无效。
因此,如果第一个单元格,即左上角的单元格包含一个“X”或一个“O”,此代码将在内部循环的第一次迭代中看到它,并报告错误消息,否不管井字游戏矩阵的其余部分还包含什么。
至此,您已经成功地找出了此处的逻辑错误,使用 Rubber Duck 方法进行调试。
关于c++ - Tic Tac Toe Trouble(一些逻辑错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34303703/