#include <iostream>
#include <fstream>
#include <limits>
#include <random>
#include <string>
using namespace std;
const char PLAYER = 'X';
const char COMPUTER = 'O';
const char EMPTY = '-';
const int max_size = 50;
const int min_size = 3;
void drawBoard(const int fieldSize, char** board) {
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
cout << board[i][j] << ' ';
}
cout << endl;
}
}
bool checkWin(const int fieldSize, char** board, char player) {
for (int i = 0; i < fieldSize; ++i) {
bool rowWin = true;
bool colWin = true;
for (int j = 0; j < fieldSize; ++j) {
rowWin &= (board[i][j] == player);
colWin &= (board[j][i] == player);
}
if (rowWin || colWin) {
return true;
}
}
bool diagonalWin = true;
bool reverseDiagonalWin = true;
for (int i = 0; i < fieldSize; ++i) {
diagonalWin &= (board[i][i] == player);
reverseDiagonalWin &= (board[i][fieldSize - i - 1] == player);
}
return diagonalWin || reverseDiagonalWin;
}
void computerMove(const int fieldSize, char** board, char player) {
char opponent = (player == PLAYER) ? COMPUTER : PLAYER;
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = opponent;
if (checkWin(fieldSize, board, opponent)) {
board[i][j] = COMPUTER;
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
board[i][j] = EMPTY;
}
}
}
// If no potential winning moves by the player are found, check for potential winning moves by the computer and make a move to win the game
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = COMPUTER;
if (checkWin(fieldSize, board, COMPUTER)) {
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
board[i][j] = EMPTY;
}
}
}
// If no winning moves are found, make a move in the center of the board if it's available
if (board[fieldSize/2][fieldSize/2] == EMPTY) {
board[fieldSize/2][fieldSize/2] = COMPUTER;
cout << "Computer move: row " << fieldSize/2 + 1 << ", column " << fieldSize/2 + 1 << endl;
return;
}
// If the center is not available, make a move in the first available cell
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = COMPUTER;
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
}
}
}
void printResults(const int result[], int numGames) {
int playerWin = 0;
int computerWin = 0;
int draws = 0;
for (int i = 0; i < numGames; ++i) {
if (result[i] == 1) {
++playerWin;
}
else if (result[i] == -1) {
++computerWin;
}
else {
++draws;
}
}
cout << "Player wins: " << playerWin << endl;
cout << "Computer wins: " << computerWin << endl;
cout << "Draws: " << draws << endl;
}
int main() {
string playerName;
cout << "Enter your name: ";
getline(cin, playerName);
int fieldSize;
cout << "Enter the size of the field (";
cout << min_size << "-" << max_size << "): ";
if (!(cin >> fieldSize) || fieldSize < min_size || fieldSize > max_size) {
cout << "Error. Field size can only be a number ";
cout << min_size << "-" << max_size << "!" << endl;
return 1;
}
int numGames = 0;
int result[max_size] = {0};
while (true) {
char** board = new char* [fieldSize];
for (int i = 0; i < fieldSize; ++i) {
board[i] = new char[fieldSize];
for (int j = 0; j < fieldSize; ++j) {
board[i][j] = EMPTY;
}
}
bool playerOneTurn = true;
int moves = fieldSize * fieldSize;
while (moves > 0) {
drawBoard(fieldSize, board);
if (playerOneTurn) {
int row, col;
cout << playerName << ", enter your move in the format 'row column': ";
cin >> row >> col;
row -= 1; // subtract 1 from row
col -= 1; // subtract 1 from column
while (cin.fail() || row < 0 || row >= fieldSize || col < 0
|| col >= fieldSize || board[row][col] != EMPTY) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please enter 'row column': ";
cin >> row >> col;
row -= 1; // subtract 1 from row
col -= 1; // subtract 1 from column
}
board[row][col] = PLAYER;
if (checkWin(fieldSize, board, PLAYER)) {
drawBoard(fieldSize, board);
cout << "You won, " << playerName << "!" << endl;
result[numGames] = 1;
++numGames;
break;
}
playerOneTurn = false;
}
else {
computerMove(fieldSize, board, COMPUTER);
if (checkWin(fieldSize, board, COMPUTER)) {
drawBoard(fieldSize, board);
cout << "Computer won!" << endl;
result[numGames] = -1;
++numGames;
break;
}
playerOneTurn = true;
}
--moves;
}
if (moves == 0) {
drawBoard(fieldSize, board);
cout << "Draw!" << endl;
result[numGames] = 0;
++numGames;
}
// Release the memory for the board
for (int i = 0; i < fieldSize; ++i) {
delete[] board[i];
}
delete[] board;
// Ask the user if they want to play again
string playAgain;
cout << "Do you want to play again? (yes/no): ";
cin >> playAgain;
while (playAgain != "yes" && playAgain != "no") {
cout << "Invalid input. Please enter 'yes' or 'no': ";
cin >> playAgain;
}
if (playAgain == "no") {
break;
}
}
printResults(result, numGames);
return 0;
}