Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
8.1 kB
5
Indexable
Never
#include <iostream>
#include <limits>
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; i++) {
        for (int j = 0; j <= fieldSize - winSymbols; j++) {
            win= true;
            for (int k = 0; k < winSymbols; k++) {
                if (field[i][j + k] != player) {
                    win = false;
                    break;
                }
            }
            if (win) {
                return true;
            }
        }
    }


    for (int j = 0; j < fieldSize; j++) {
        for (int i = 0; i <= fieldSize - winSymbols; i++) {
            win= true;
            for (int k = 0; k < winSymbols; k++) {
                if (field[i + k][j] != 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;
    if (player == 'X') {
        cout << "Player " << playerName << ", enter row and column for your move (1-" << fieldSize << "): ";
        while (!(cin >> row >> col) || row < 1 || row > fieldSize || col < 1 || col > fieldSize || field[row - 1][col - 1] != '-') {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid input. Enter row and column again: ";
            cin >> row >> col; // repeat input
        }
        field[row - 1][col - 1] = player;
    }
    else {
        // Computer's move
        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] = '-';
                    }
                }
            }
        }

        // Checking for blocking move
        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;
                }
            }
        }
    }
}

bool isValidChoice(char choice) {
    return (choice == 'y' || choice == 'n');
}

int main() {
    cout << "Enter field size (from 3 to " << MAX_FIELD_SIZE << "): ";
    while (!(cin >> fieldSize) || fieldSize < 3 || fieldSize > MAX_FIELD_SIZE) {
        cin.clear(); // clear the error flag
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "Invalid input. Enter field size again: ";
    }

    createField();
    printField();

    string playerName;
    cout << "Enter your name: ";
    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;

            char choice;
            cout << "Do you want to continue? (y/n): ";
            while (!(cin >> choice) || !isValidChoice(choice)) {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "Invalid input. Enter y or n: ";
            }
            if (choice == 'y') {
                createField();
                printField();
                currentPlayer = 'X';
                continue;
            }
            else {
                break;
            }
        }

        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;

            char choice;
            cout << "Do you want to continue? (y/n): ";
            while (!(cin >> choice) || !isValidChoice(choice)) {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "Invalid input. Enter y or n: ";
            }
            if (choice == 'y') {
                createField();
                printField();
                currentPlayer = 'X';
                continue;
            }
            else {
                break;
            }
        }

        if (currentPlayer == 'X') {
            currentPlayer = 'O';
        }
        else {
            currentPlayer = 'X';
        }
    }

    return 0;
}