#include <iostream>
#include <limits>
#include <sstream>
#include <string>
using namespace std;
const int MAX_FIELD_SIZE = 25;
int fieldSize;
char field[MAX_FIELD_SIZE][MAX_FIELD_SIZE];
void createField() {
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
field[i][j] = '-';
}
}
}
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 winSymbols = (fieldSize >= 5) ? 5 : 4;
for (int i = 0; i < fieldSize; i++) {
bool win = true;
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
}
for (int j = 0; j < fieldSize; j++) {
bool win = true;
for (int i = 0; i < fieldSize; i++) {
if (field[i][j] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
}
bool win = true;
for (int i = 0; i < fieldSize; i++) {
if (field[i][i] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
win = true;
for (int i = 0; i < fieldSize; i++) {
if (field[i][fieldSize - 1 - i] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
for (int i = 0; i <= fieldSize - winSymbols; i++) {
for (int j = 0; j <= fieldSize - winSymbols; j++) {
win = true;
for (int k = 0; k < winSymbols; k++) {
if (field[i + k][j + k] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
}
}
for (int i = 0; i <= fieldSize - winSymbols; i++) {
for (int j = winSymbols - 1; j < fieldSize; j++) {
win = true;
for (int k = 0; k < winSymbols; k++) {
if (field[i + k][j - k] != player) {
win = false;
break;
}
}
if (win) {
return true;
}
}
}
return false;
}
void makeMove(char player, const string& playerName) {
int row, col;
string move;
if (player == 'X') {
cout << "Player " << playerName << ", enter row and column for your move (1-" << fieldSize << "): ";
while (true) {
getline(cin, move);
if (move.empty()) {
cout << "Invalid input. Enter row and column again: ";
continue;
}
if (move == "n") {
exit(0);
}
stringstream ss(move);
if (ss >> row >> col && ss.eof() && row >= 1 && row <= fieldSize && col >= 1 && col <= fieldSize && field[row - 1][col - 1] == '-') {
break;
}
else {
cout << "Invalid input. Enter row and column again: ";
}
}
field[row - 1][col - 1] = player;
}
else {
cout << "Computer's move: " << endl;
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] == '-') {
field[i][j] = player;
if (checkWin(player)) {
return;
}
else {
field[i][j] = '-';
}
}
}
}
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] == '-') {
field[i][j] = 'X';
if (checkWin('X')) {
field[i][j] = player;
return;
}
else {
field[i][j] = '-';
}
}
}
}
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] == '-') {
field[i][j] = player;
return;
}
}
}
}
}
int main() {
cout << "Warning! A new game will start immediately after the end of your current game. To end the game, you can press n at any time." << endl;
cout << "Enter the field size (more than 2): ";
while (!(cin >> fieldSize) || cin.get() != '\n' || fieldSize < 3) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Enter the field size again: ";
}
createField();
printField();
string playerName;
cout << "Enter your name: ";
getline(cin, playerName);
int playerScore = 0, computerScore = 0;
char currentPlayer = 'X';
while (true)
{
makeMove(currentPlayer, playerName);
printField();
if (checkWin(currentPlayer)) {
if (currentPlayer == 'X') {
playerScore++;
} else {
computerScore++;
}
cout << "Player " << currentPlayer << " wins!" << endl;
cout << "Score: " << playerName << " - " << playerScore << ", Computer - " << computerScore << endl;
createField();
printField();
}
bool tie = true;
for (int i = 0; i < fieldSize; i++) {
for (int j = 0; j < fieldSize; j++) {
if (field[i][j] == '-') {
tie = false;
break;
}
}
if (!tie) {
break;
}
}
if (tie) {
cout << "It's a tie!" << endl;
cout << "Player " << currentPlayer << " wins!" << endl;
cout << "Score: " << playerName << " - " << playerScore << ", Computer - " << computerScore << endl;
createField();
printField();
}
if (currentPlayer == 'X') {
currentPlayer = 'O';
} else {
currentPlayer = 'X';
}
}
}