#include <iostream>
#include <limits>
#include <vector>
using namespace std;
//Оголошення змінних для розміру поля та самого поля
int fieldSize;
vector<vector<char>> field;
//Оголошення змінних для збереження результатів гри
int player1Score = 0;
int player2Score = 0;
//Функція, яка створює пусте поле заданого розміру
void createField() {
field.assign(fieldSize, vector<char>(fieldSize, '-'));
}
//Функція, яка виводить поле на екран
void printField() {
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
cout << field[i][j] << " ";
}
cout << endl;
}
}
//Функція, яка перевіряє, чи є переможець
bool checkWin(char player) {
int requiredSymbols = 3;
if (fieldSize >= 5) {
requiredSymbols = 5;
}
else if (fieldSize == 4) {
requiredSymbols = 4;
}
//Перевірка по горизонталі
for (int i = 0; i < fieldSize; i++) {
int symbolCount = 0;
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] == player) {
symbolCount++;
if (symbolCount == requiredSymbols) {
return true;
}
}
else {
symbolCount = 0;
}
}
}
//Перевірка по вертикалі
for (int j = 0; j < fieldSize; j++) {
int symbolCount = 0;
for (int i = 0; i < fieldSize; i++) {
if (field[i][j] == player) {
symbolCount++;
if (symbolCount == requiredSymbols) {
return true;
}
}
else {
symbolCount = 0;
}
}
}
//Перевірка по діагоналі (зліва направо)
for (int i = 0; i <= fieldSize - requiredSymbols; i++) {
for (int j = 0; j <= fieldSize - requiredSymbols; j++) {
int symbolCount = 0;
for (int k = 0; k < requiredSymbols; k++) {
if (field[i + k][j + k] == player) {
symbolCount++;
if (symbolCount == requiredSymbols) {
return true;
}
}
else {
symbolCount = 0;
}
}
}
}
//Перевірка по діагоналі (справа наліво)
for (int i = 0; i <= fieldSize - requiredSymbols; i++) {
for (int j = requiredSymbols - 1; j < fieldSize; j++) {
int symbolCount = 0;
for (int k = 0; k < requiredSymbols; k++) {
if (field[i + k][j - k] == player) {
symbolCount++;
if (symbolCount == requiredSymbols) {
return true;
}
}
else {
symbolCount = 0;
}
}
}
}
//Якщо немає переможця
return false;
}
//Функція, яка дозволяє комп'ютеру зробити хід
void makeComputerMove(char player) {
int row, col;
cout << "Хід Комп'ютера: ";
row = rand() % fieldSize;
col = rand() % fieldSize;
while (field[row][col] != '-') {
row = rand() % fieldSize;
col = rand() % fieldSize;
}
field[row][col] = player;
cout << row+1 << " " << col+1 << endl;
}
void makePlayerMove(char player) {
int row, col;
cout << "Гравець " << player << ", введіть рядок та стовпчик для ходу: ";
while (!(cin >> row >> col) || cin.get() != '\n' || row < 1 || row > fieldSize || col < 1 || col > fieldSize || field[row - 1][col - 1] != '-') {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Неправильний ввід. Введіть рядок та стовпчик ще раз: ";
}
//Додавання символу гравця на поле
field[row - 1][col - 1] = player;
}
//Функція, яка додає результат гри до відповідного гравця
void addResult(char winner, string player1Name) {
if (winner == 'X') {
player1Score++;
cout << "Гравець " << player1Name << " переміг!" << endl;
}
else if (winner == 'O') {
player2Score++;
cout << "Комп'ютер переміг!" << endl;
}
}
//Функція, яка виводить результат гри
void printResult(string player1Name) {
cout << "Рахунок: " << player1Name << " - " << player1Score << ", Комп'ютер - " << player2Score << endl;
}
//Основна програма з виправленням запиту на продовження гри та збереженням імені гравця
int main() {
//Введення розміру поля
cout << "Введіть розмір поля (більше 2): ";
while (!(cin >> fieldSize) || cin.get() != '\n' || fieldSize < 3) {
cin.clear();
cin.ignore(numeric_limits<streamsize> ::max(), '\n');
cout << "Неправильний ввід. Введіть розмір поля ще раз: ";
}
//Створення пустого поля та виведення його на екран
createField();
printField();
//Введення імені гравця 1
string player1Name;
cout << "Гравець 1, введіть своє ім'я: ";
cin >> player1Name;
//Головний цикл гри
char currentPlayer = 'X';
while (true) {
//Перевірка на хід комп'ютера
if (currentPlayer == 'O') {
makeComputerMove(currentPlayer);
}
else {
//Гравець робить хід
makePlayerMove(currentPlayer);
}
//Виведення поля на екран після ходу
printField();
//Перевірка на переможця
if (checkWin(currentPlayer)) {
addResult(currentPlayer, player1Name);
printResult(player1Name);
//Запит на продовження
char answer;
do {
cout << "Бажаєте продовжити? (y/n): ";
cin >> answer;
} while (answer != 'y' && answer != 'n');
if (answer == 'y') {
//Очищення поля та виведення його на екран
field.clear();
createField();
printField();
continue;
}
else {
//Виведення фінальної статистики
cout << "Фінальний рахунок: " << player1Name << " - " << player1Score << ", Комп'ютер - " << player2Score << endl;
break;
}
}
//Перевід ходу на іншого гравця
if (currentPlayer == 'X') {
currentPlayer = 'O';
}
else {
currentPlayer = 'X';
}
}
return 0;
}