Как правильно указал melk, проблема в том, что флаг ошибки устанавливается, когда вы вводите неверный ввод, не позволяющий вам использовать поток до того, как вы сбросите флаг.
Другие предложили использовать строки и затем проверить вход, который будет работать довольно хорошо. Но, если вы не хотите вносить много изменений в свой код, вы можете просто объявить переменную choice
типа char
.
Теперь, после того как вы взяли ввод, потому что Как работает тип данных char
, ваша переменная выбора будет хранить значение ASCII символа, введенного пользователем. Чтобы вместо этого хранить само значение числового значения c, вы можете выполнить этот изящный трюк:
choice -= '0';
Это использует тот факт, что в ASCII числовые символы c приходят один за другим, начиная с '0'
. Так что '1' - '0'
даст 1
, а '5' - '0'
даст 5
.
Теперь остальная часть вашего кода теперь работает хорошо, так как у вас не возникнет проблем с проверкой, был ли введенный символ число между 1-9.
Хотя вам нужно сделать еще одну вещь, чтобы очистить буфер ввода sh, когда пользователь вводит неправильный выбор. Это сделано для того, чтобы сообщение об ошибке не появлялось несколько раз (по одному разу для каждого введенного символа), если пользователь вводит несколько символов.
Таким образом, ваш код должен выглядеть примерно так (я только что добавил еще две строки):
#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;
}
Отличная работа над игрой, в остальном, кстати. Отлично смотрится для консольного проекта.