尝试完成一个简单的井字游戏的作业,而不使用函数或我们班上未涉及的任何内容。目前代码中的所有内容都是可以接受的,但是在选择一个正方形并使用非数字字符时,我一直遇到无限循环问题。任何帮助将不胜感激!
#include <iostream>
using namespace std;
int i;
char board[10];
bool gameover;
bool check_choice;
char player;
int choice = 0;
char restart;
int main()
{
do
{
for (int i = 0; i < 10; i++) board[i] = ' ';
bool gameover = false;
bool check_choice = true;
char player = 'X';
do
{
// Draw game board
cout << "+---+---+---+ \n";
cout << "| " << board[1] << " | " << board[2] << " | " << board[3] << " | \n";
cout << "+---+---+---+ \n";
cout << "| " << board[4] << " | " << board[5] << " | " << board[6] << " | \n";
cout << "+---+---+---+ \n";
cout << "| " << board[7] << " | " << board[8] << " | " << board[9] << " | \n";
cout << "+---+---+---+ \n";
// Win Check
if ((board[1] == 'X' && board[2] == 'X' && board[3] == 'X') ||
(board[4] == 'X' && board[5] == 'X' && board[6] == 'X') ||
(board[7] == 'X' && board[8] == 'X' && board[9] == 'X') ||
(board[1] == 'X' && board[4] == 'X' && board[7] == 'X') ||
(board[2] == 'X' && board[5] == 'X' && board[8] == 'X') ||
(board[3] == 'X' && board[6] == 'X' && board[9] == 'X') ||
(board[1] == 'X' && board[5] == 'X' && board[9] == 'X') ||
(board[3] == 'X' && board[5] == 'X' && board[7] == 'X'))
{
cout << "Game Over - X wins! \n";
gameover = true;
}
else if ((board[1] == 'O' && board[2] == 'O' && board[3] == 'O') ||
(board[4] == 'O' && board[5] == 'O' && board[6] == 'O') ||
(board[7] == 'O' && board[8] == 'O' && board[9] == 'O') ||
(board[1] == 'O' && board[4] == 'O' && board[7] == 'O') ||
(board[2] == 'O' && board[5] == 'O' && board[8] == 'O') ||
(board[3] == 'O' && board[6] == 'O' && board[9] == 'O') ||
(board[1] == 'O' && board[5] == 'O' && board[9] == 'O') ||
(board[3] == 'O' && board[5] == 'O' && board[7] == 'O'))
{
cout << "Game Over - O wins! \n \n";
gameover = true;
}
// Draw Check
else if ((board[1] != ' ' && board[2] != ' ' && board[3] != ' ') &&
(board[4] != ' ' && board[5] != ' ' && board[6] != ' ') &&
(board[7] != ' ' && board[8] != ' ' && board[9] != ' '))
{
cout << "Game Over - Draw \n \n";
gameover = true;
}
else
check_choice = true;
while (check_choice == true)
{
cout << "Place " << player << " at: ";
cin >> choice;
if (choice > sizeof(board) || choice == 0 || choice == 10)
{
cout << "Invalid input! 1-9 only. \n";
check_choice = true;
}
else if (board[choice] == ' ')
{
board[choice] = (player == 'X') ? 'X' : 'O';
player = (player == 'X') ? 'O' : 'X';
check_choice = false;
}
else
{
cout << "Invalid input! Position already filled. \n";
check_choice = true;
}
}
} while (gameover == false);
cout << "Would you like to play again? (Y / N): ";
cin >> restart;
cin.ignore();
} while (restart == 'y' || restart == 'Y');
cout << "Thanks for playing!! \n \n";
system("pause");
return 0;
}
答案 0 :(得分:1)
当从流中读取时发生错误时,将设置一个错误标志,除非清除错误标志,否则无法再进行读取。这就是为什么您会遇到无限循环的原因。
从here复制了答案,所以对我不屑一顾:P
正如@PaulMcKenzie所说,最好先将其读取为字符串,然后再进行必要的检查。
答案 1 :(得分:0)
正如麦尔克正确指出的那样,问题在于错误标志,当您输入错误时会设置该错误标志,从而阻止您在清除标志之前使用流。
其他人建议使用字符串,然后验证输入效果,效果很好。但是,如果您不想在代码中进行很多更改,则只需声明choice
变量为char
类型即可。
现在,在接受输入之后,由于char
数据类型的工作方式,您的选择变量将存储用户输入的字符的ASCII值。要使其存储数值本身,您可以执行以下巧妙的操作:
choice -= '0';
这利用了以下事实:在ASCII中,数字字符从'0'
开始一个接一个地出现。因此'1' - '0'
将给出1
,而'5' - '0'
将给出5
。
现在,剩下的代码现在可以正常工作了,因为检查输入的字符是否为1到9之间的数字不会遇到任何问题。
您还需要做的一件事是,当用户输入错误的选择时刷新输入缓冲区。如果用户输入多个字符,这是为了防止错误消息多次出现(对于输入的每个字符一次)。
因此您的代码总体上应如下所示(我刚刚添加了两行):
#include <iostream>
using namespace std;
int i;
char board[10];
bool gameover;
bool check_choice;
char player;
char choice = 0; // the choice variable is now a character
char restart;
int main()
{
do
{
for (int i = 0; i < 10; i++) board[i] = ' ';
bool gameover = false;
bool check_choice = true;
char player = 'X';
do
{
// Draw game board
cout << "+---+---+---+ \n";
cout << "| " << board[1] << " | " << board[2] << " | " << board[3] << " | \n";
cout << "+---+---+---+ \n";
cout << "| " << board[4] << " | " << board[5] << " | " << board[6] << " | \n";
cout << "+---+---+---+ \n";
cout << "| " << board[7] << " | " << board[8] << " | " << board[9] << " | \n";
cout << "+---+---+---+ \n";
// Win Check
if ((board[1] == 'X' && board[2] == 'X' && board[3] == 'X') ||
(board[4] == 'X' && board[5] == 'X' && board[6] == 'X') ||
(board[7] == 'X' && board[8] == 'X' && board[9] == 'X') ||
(board[1] == 'X' && board[4] == 'X' && board[7] == 'X') ||
(board[2] == 'X' && board[5] == 'X' && board[8] == 'X') ||
(board[3] == 'X' && board[6] == 'X' && board[9] == 'X') ||
(board[1] == 'X' && board[5] == 'X' && board[9] == 'X') ||
(board[3] == 'X' && board[5] == 'X' && board[7] == 'X'))
{
cout << "Game Over - X wins! \n";
gameover = true;
}
else if ((board[1] == 'O' && board[2] == 'O' && board[3] == 'O') ||
(board[4] == 'O' && board[5] == 'O' && board[6] == 'O') ||
(board[7] == 'O' && board[8] == 'O' && board[9] == 'O') ||
(board[1] == 'O' && board[4] == 'O' && board[7] == 'O') ||
(board[2] == 'O' && board[5] == 'O' && board[8] == 'O') ||
(board[3] == 'O' && board[6] == 'O' && board[9] == 'O') ||
(board[1] == 'O' && board[5] == 'O' && board[9] == 'O') ||
(board[3] == 'O' && board[5] == 'O' && board[7] == 'O'))
{
cout << "Game Over - O wins! \n \n";
gameover = true;
}
// Draw Check
else if ((board[1] != ' ' && board[2] != ' ' && board[3] != ' ') &&
(board[4] != ' ' && board[5] != ' ' && board[6] != ' ') &&
(board[7] != ' ' && board[8] != ' ' && board[9] != ' '))
{
cout << "Game Over - Draw \n \n";
gameover = true;
}
else
check_choice = true;
while (check_choice == true)
{
cout << "Place " << player << " at: ";
cin >> choice;
choice -= '0'; // added this line to convert character to number
if (choice > sizeof(board) || choice == 0 || choice == 10)
{
cout << "Invalid input! 1-9 only." << std::endl;
check_choice = true;
fflush(stdin); // added this line to clear input buffer
}
else if (board[choice] == ' ')
{
board[choice] = (player == 'X') ? 'X' : 'O';
player = (player == 'X') ? 'O' : 'X';
check_choice = false;
}
else
{
cout << "Invalid input! Position already filled. \n";
check_choice = true;
}
}
} while (gameover == false);
cout << "Would you like to play again? (Y / N): ";
cin >> restart;
cin.ignore();
} while (restart == 'y' || restart == 'Y');
cout << "Thanks for playing!! \n \n";
system("pause");
return 0;
}
顺便说一句,在游戏上做得很好。对于控制台项目看起来很棒。
答案 2 :(得分:-1)
您可以使用类似的
string mystr;
getline (cin,mystr);
将cin的一行读为字符串。此后,您可以检查它是否为数字,然后获取它,或者如果不是,则显示错误。
PS:您不应使用全局变量,而应将代码拆分为函数。另外,您的数组比需要的数组大一个(您正在为10个元素分配空间,但只需要9个)。请小心,因为您错误地将索引从1开始,而数组从0开始,这意味着您现在完全忽略了第一个元素。如果将其更改为分配9个元素,请确保对所有索引正确地减去1(否则,当您将9个元素移出数组边界时,将9赋值将导致错误)。