4
\$\begingroup\$

I've already created a code in python here with almost the same logic:
Tic-Tac-Toe with changeable board size (Part 1)
Tic-Tac-Toe with changeable board size (Part 2)

Here's the code in C++. As I'm still a beginner in C++, I don't know many of the STL functions or such. Please help me on improving the code

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <vector>

using namespace std;

class TicTacToe{
public:
    vector<vector<char>> board{{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
    vector<vector<char>> s_board{{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};

    string player = "Player";
    int s;
    int start = 0;

    char X = 'X';
    char O = 'O';

    int countWins(char p1, char p2){
        int count = 0;

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != p1 && board[i][j] != p2){
                    char c = board[i][j];
                    board[i][j] = p1;

                    if(win(p1) == 1)
                        count++;

                    board[i][j] = c;
                }
            }
        }

        return count;
    }

    void getInsaneAIMove(char ai, char pl, int x = 0, string name = ""){
        srand(time(NULL));

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != ai && board[i][j] != pl){
                    char c = board[i][j];
                    board[i][j] = ai;

                    if(win(ai) == 1 || tie() == 1){
                        if(x) cout << name << " Moved To Grid " << i * 3 + j + 1 << endl;
                        return ;
                    }

                    board[i][j] = c;
                }
            }
        }

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != ai && board[i][j] != pl){
                    char c = board[i][j];
                    board[i][j] = pl;

                    if(win(pl) == 1 || tie() == 1){
                        board[i][j] = ai;
                        if(x) cout << name << " Moved To Grid " << i * 3 + j + 1 << endl;
                        return ;
                    }

                    board[i][j] = c;
                }
            }
        }

        vector<vector<int>> wins2;
        int l = 0;

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != ai && board[i][j] != pl){
                    char c = board[i][j];
                    board[i][j] = ai;

                    if(countWins(ai, pl) > 1){
                        l++;
                        vector<int> r{i, j};
                        wins2.push_back(r);
                    }

                    board[i][j] = c;
                }
            }
        }

        if(l){
            vector<int> m = wins2[rand() % l];
            board[m[0]][m[1]] = ai;
            if(x) cout << name << " Moved To Grid " << m[0] * 3 + m[1] + 1 << endl;
            return ;
        }

        if(board[1][1] == '5'){
            board[1][1] = ai;
            if(x) cout << name << " Moved To Grid 5\n";

            return ;
        }

        int l1 = 0, l2 = 0;

        vector<vector<int>> pos_edges{{0, 0}, {0, 2}, {2, 0}, {2, 2}};
        vector<vector<int>> edges;

        for(int i = 0; i < 4; i++){
            int x = pos_edges[i][0], y = pos_edges[i][1];

            if(board[x][y] != ai && board[x][y] != pl){
                edges.push_back(pos_edges[i]);
                l1++;
            }
        }

        if(l1){
            vector<int> r = edges[rand() % l1];
            board[r[0]][r[1]] = ai;
            if(x) cout << name << " Moved To Grid " << r[0] * 3 + r[1] + 1 << endl;

            return ;
        }

        vector<vector<int>> pos_middles{{0, 1}, {1, 0}, {1, 2}, {2, 1}};
        vector<vector<int>> middles;

        for(int i = 0; i < 4; i++){
            int x = pos_middles[i][0], y = pos_middles[i][1];

            if(board[x][y] != ai && board[x][y] != pl){
                middles.push_back(pos_middles[i]);
                l2++;
            }
        }

        vector<int> r = middles[rand() % l2];
        board[r[0]][r[1]] = ai;
        if(x) cout << name << " Moved To Grid " << r[0] * 3 + r[1] + 1 << endl;

        return ;
    }

    void getHardAIMove(char ai, char pl, int x = 0, string name = ""){
        srand(time(NULL));

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != ai && board[i][j] != pl){
                    char c = board[i][j];
                    board[i][j] = ai;

                    if(win(ai) == 1 || tie() == 1){
                        if(x) cout << name << " Moved To Grid " << i * 3 + j + 1 << endl;
                        return ;
                    }

                    board[i][j] = c;
                }
            }
        }

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                if(board[i][j] != ai && board[i][j] != pl){
                    char c = board[i][j];
                    board[i][j] = pl;

                    if(win(pl) == 1 || tie() == 1){
                        board[i][j] = ai;
                        if(x) cout << name << " Moved To Grid " << i * 3 + j + 1 << endl;
                        return ;
                    }

                    board[i][j] = c;
                }
            }
        }

        int l = 0;

        vector<vector<int>> possible{{0, 0}, {0, 2}, {2, 0}, {2, 2},
                                      {0, 1}, {1, 0}, {1, 2}, {2, 1}};

        vector<vector<int>> available;

        for(int i = 0; i < 8; i++){
            int x = possible[i][0], y = possible[i][1];

            if(board[x][y] != ai && board[x][y] != pl){
                available.push_back(possible[i]);
                l++;
            }
        }

        vector<int> r = available[rand() % l];
        board[r[0]][r[1]] = ai;
        if(x) cout << name << " Moved To Grid " << r[0] * 3 + r[1] + 1 << endl;
        return ;
    }

    void getEasyAIMove(char ai, char pl, int x = 0, string name = ""){
        srand(time(NULL));

        int l = 0;

        vector<vector<int>> possible{{0, 0}, {0, 2}, {2, 0}, {2, 2},
                                      {0, 1}, {1, 0}, {1, 2}, {2, 1}};

        vector<vector<int>> available;

        for(int i = 0; i < 8; i++){
            int x = possible[i][0], y = possible[i][1];

            if(board[x][y] != ai && board[x][y] != pl){
                available.push_back(possible[i]);
                l++;
            }
        }

        vector<int> r = available[rand() % l];
        board[r[0]][r[1]] = ai;
        if(x) cout << name << " Moved To Grid " << r[0] * 3 + r[1] + 1 << endl;
        return ;
    }

    void getUserMove(char p1, char p2){
            int g;

            cout << "Please Enter Grid Number (1 - 9) : ";
            cin >> g;

            g -= 1;

            int x = g / 3;
            int y = g % 3;

            if(board[x][y] == p1 || board[x][y] == p2){
                cout << "Please Enter A Valid Move\n" << endl;
                getUserMove(p1, p2);
                return ;
            }

            cout << endl << player << " Moved To Grid " << g + 1;

            board[x][y] = p1;
            cout << "\n";
        }

    void getWin(char p){
        bool r1 = board[0][0] == board[0][1] && board[0][1] == board[0][2] && board[0][0] == p;
        bool r2 = board[1][0] == board[1][1] && board[1][1] == board[1][2] && board[1][0] == p;
        bool r3 = board[2][0] == board[2][1] && board[2][1] == board[2][2] && board[2][0] == p;
        bool c1 = board[0][0] == board[1][0] && board[1][0] == board[2][0] && board[0][0] == p;
        bool c2 = board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] == p;
        bool c3 = board[0][2] == board[1][2] && board[1][2] == board[2][2] && board[0][2] == p;
        bool d1 = board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == p;
        bool d2 = board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == p;

        if(r1 == 1) {s_board[0][0] = p; s_board[0][1] = p; s_board[0][2] = p;}
        if(r2 == 1) {s_board[1][0] = p; s_board[1][1] = p; s_board[1][2] = p;}
        if(r3 == 1) {s_board[2][0] = p; s_board[2][1] = p; s_board[2][2] = p;}
        if(c1 == 1) {s_board[0][0] = p; s_board[1][0] = p; s_board[2][0] = p;}
        if(c2 == 1) {s_board[0][1] = p; s_board[1][1] = p; s_board[2][1] = p;}
        if(c3 == 1) {s_board[0][2] = p; s_board[1][2] = p; s_board[2][2] = p;}
        if(d1 == 1) {s_board[0][0] = p; s_board[1][1] = p; s_board[2][2] = p;}
        if(d2 == 1) {s_board[0][2] = p; s_board[1][1] = p; s_board[2][0] = p;}
    }

    void print1(){
        cout << "      |       |\n";
        cout << "  " << board[0][0] << "   |   " << board[0][1] << "   |   " << board[0][2] << "\n";
        cout << "      |       |\n";
        cout << "---------------------\n";
        cout << "      |       |\n";
        cout << "  " << board[1][0] << "   |   " << board[1][1] << "   |   " << board[1][2] << "\n";
        cout << "      |       |\n";
        cout << "---------------------\n";
        cout << "      |       |\n";
        cout << "  " << board[2][0] << "   |   " << board[2][1] << "   |   " << board[2][2] << "\n";
        cout << "      |       |\n";
        cout << "\n";
    }

    void print2(){
        cout << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << "\n";
        cout << "---------\n";
        cout << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << "\n";
        cout << "---------\n";
        cout << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << "\n";
        cout << "\n";
    }

    void printWin(char p){
        getWin(p);
        cout << s_board[0][0] << " | " << s_board[0][1] << " | " << s_board[0][2] << endl;
        cout << "---------\n";
        cout << s_board[1][0] << " | " << s_board[1][1] << " | " << s_board[1][2] << endl;
        cout << "---------\n";
        cout << s_board[2][0] << " | " << s_board[2][1] << " | " << s_board[2][2] << endl;
        cout << endl;
    }

    string getRandomName(){
        srand(time(NULL));

        string names[250] = {
                "Jacob", "Michael",
                "Joshua", "Ethan", "Matthew", "Daniel",
                "Christopher", "Andrew", "Anthony", "William",
                "Joseph", "Alexander", "David", "Ryan",
                "Noah", "James", "Nicholas", "Tyler",
                "Logan", "John", "Christian", "Jonathan",
                "Nathan", "Benjamin", "Samuel", "Dylan",
                "Brandon", "Gabriel", "Elijah", "Aiden",
                "Angel", "Jose", "Zachary", "Caleb",
                "Jack", "Jackson", "Kevin", "Gavin",
                "Mason", "Isaiah", "Austin", "Evan",
                "Luke", "Aidan", "Justin", "Jordan",
                "Robert", "Isaac", "Landon", "Jayden",
                "Thomas", "Cameron", "Connor", "Hunter",
                "Jason", "Diego", "Aaron", "Bryan",
                "Owen", "Lucas", "Charles", "Juan",
                "Luis", "Adrian", "Adam", "Julian",
                "Alex", "Sean", "Nathaniel", "Carlos",
                "Jeremiah", "Brian", "Hayden", "Jesus",
                "Carter", "Sebastian", "Eric", "Xavier",
                "Brayden", "Kyle", "Ian", "Wyatt",
                "Chase", "Cole", "Dominic", "Tristan",
                "Carson", "Jaden", "Miguel", "Steven",
                "Caden", "Kaden", "Antonio", "Timothy",
                "Henry", "Alejandro", "Blake", "Liam",
                "Richard", "Devin", "Riley", "Jesse",
                "Seth", "Victor", "Brady", "Cody",
                "Jake", "Vincent", "Bryce", "Patrick",
                "Colin", "Marcus", "Cooper", "Preston",
                "Kaleb", "Parker", "Josiah", "Oscar",
                "Ayden", "Jorge", "Ashton", "Alan",
                "Jeremy", "Joel", "Trevor", "Eduardo",
                "Ivan", "Kenneth", "Mark", "Alexis",
                "Omar", "Cristian", "Colton", "Paul",
                "Levi", "Damian", "Jared", "Garrett",
                "Eli", "Nicolas", "Braden", "Tanner",
                "Edward", "Conner", "Nolan", "Giovanni",
                "Brody", "Micah", "Maxwell", "Malachi",
                "Fernando", "Ricardo", "George", "Peyton",
                "Grant", "Gage", "Francisco", "Edwin",
                "Derek", "Max", "Andres", "Javier",
                "Travis", "Manuel", "Stephen", "Emmanuel",
                "Peter", "Cesar", "Shawn", "Jonah",
                "Edgar", "Dakota", "Oliver", "Erick",
                "Hector", "Bryson", "Johnathan", "Mario",
                "Shane", "Jeffrey", "Collin", "Spencer",
                "Abraham", "Leonardo", "Brendan", "Elias",
                "Jace", "Bradley", "Erik", "Wesley",
                "Jaylen", "Trenton", "Josue", "Raymond",
                "Sergio", "Damien", "Devon", "Donovan",
                "Dalton", "Martin", "Landen", "Miles",
                "Israel", "Andy", "Drew", "Marco",
                "Andre", "Gregory", "Roman", "Ty",
                "Jaxon", "Avery", "Cayden", "Jaiden",
                "Roberto", "Dominick", "Rafael", "Grayson",
                "Pedro", "Calvin", "Camden", "Taylor",
                "Dillon", "Braxton", "Keegan", "Clayton",
                "Ruben", "Jalen", "Troy", "Kayden",
                "Santiago", "Harrison", "Dawson", "Corey",
                "Maddox", "Leo", "Johnny", "Kai",
                "Drake", "Julio", "Lukas", "Kaiden",
                "Zane", "Aden", "Frank", "Simon",
                "Sawyer", "Marcos", "Hudson", "Trey"
        };

        string name = names[rand() % 250];
        return name;
    }

    void help(){
        system("CLS");
        string option;

        cout << "B for Back\n\n";
        cout << "1.) Rules\n";
        cout << "2.) Tips\n";
        cout << "3.) About\n";

        cout << "\nPlease Enter Your Option : "; cin >> option;
        cout << endl;

        system("CLS");

        if(option == "b" || option == "B")
            return ;

        if(option == "1")
            rules();

        if(option == "2")
            tips();

        if(option == "3")
            about();

        system("pause");
        system("CLS");
        help();
    }

    void about(){
        cout << "This Game Of Tic-Tac-Toe Is Created By Srivaths\n";
        cout << "If You Are Unfamiliar With This Game, Please Read The Rules And Tips\n";
        cout << "Enjoy!!\n\n";
    }

    void changeName(){
        cout << "Please Enter Your Name : "; cin >> player;
    }

    void changeBoard(){
        system("CLS");
        cout << "B for Back\n\n";
        cout << "1.)\n\n";
        print1();
        cout << "2.)\n\n";
        print2();

        cout << endl;
        string option;

        cout << "\nPlease Enter Your Option : "; cin >> option;

        if(option == "b" || option == "B")
            return ;

        if(option == "1") s = 1;
        if(option == "2") s = 2;
    }

    void changeColor(){
        system("CLS");
        string c = "color ";
        string option;

        cout << "B for Back\n\n";
        cout << "1 = Blue\n";
        cout << "2 = Green\n";
        cout << "3 = Aqua\n";
        cout << "4 = Red\n";
        cout << "5 = Purple\n";
        cout << "6 = Yellow\n";
        cout << "7 = White\n";
        cout << "8 = Gray\n";
        cout << "9 = Light Blue\n";
        cout << "A = Light Green\n";
        cout << "B = Light Aqua\n";
        cout << "C = Light Red\n";
        cout << "D = Light Purple\n";
        cout << "E = Light Yellow\n";
        cout << "F = Bright White\n";
        cout << "\nPlease Enter Your Option : "; cin >> option;

        if(option == "b" || option == "B")
            return ;

        const char* x = (c + option).c_str();

        system(x);
    }

    void changeCharacters(){
        system("CLS");
        cout << "Please Enter Character For Player 1 (currently " << X << ") : "; cin >> X;
        cout << "Please Enter Character For Player 2 (currently " << O << ") : "; cin >> O;
    }

    void settings(){
        system("CLS");
        string option;

        cout << "B for Back\n\n";
        cout << "1.) Change Name\n";
        cout << "2.) Change Board\n";
        cout << "3.) Change Color\n";
        cout << "4.) Change Characters\n";
        cout << "\nPlease Enter Your Option : "; cin >> option;

        if(option == "b" || option == "B")
            return ;

        if(option == "1") changeName();
        if(option == "2") changeBoard();
        if(option == "3") changeColor();
        if(option == "4") changeCharacters();

        system("CLS");
        settings();
    }

    void main_menu(){
        system("CLS");
        string option;

        if(start == 0){
            intro();
            start = 1;
            main_menu();
            return ;
        }

        cout << "Hello " << player << endl;

        cout << "\nQ for Quit\n\n";
        cout << "1.) Help\n";
        cout << "2.) Settings\n";
        cout << "3.) Play\n";
        cout << "\nPlease Enter Your Option : "; cin >> option;

        if(option == "1")
            help();

        if(option == "2")
            settings();

        if(option == "3"){
            initialize();
            play('X', 'O');
        }

        if(option == "q" || option == "Q"){
            cout << "Thanks For Playing!\n";
            return ;
        }

        system("CLS");
        main_menu();
    }

    void rules(){
        cout << "1.) In Tic-Tac-Toe, There Are 2 Players \n\tAnd Their Characters Are X and O respectively\n";
        cout << "2.) Any Row Or Column or Diagonal Filled With The Same Characters Is A Win\n";
        cout << "3.) A Board Where There Are No Moves Left Is A Tie Or Draw\n";
        cout << "4.) You Are Not Allowed To Place Characters Over Another\n";
        cout << endl;
    }

    void tips(){
        cout << "1.) Always Try To Capture The Center\n";
        cout << "2.) Next Try To Capture The Edges\n";
        cout << "3.) Be Aware Of Instant Moves\n";
        cout << "4.) Always Try To Think A Move Ahead\n";
        cout << "5.) Try The Easy Bot To Get The Hang Of The Game\n";
        cout << endl;
    }

    void intro(){
        initialize();

        cout << "Hello Player, ";

        changeName();

        cout << "\nHello " << player << ", ";
        cout << "Welcome To The Game Of Tic-Tac-Toe!!\n";

        string know;

        cout << "Are You Familiar With The Game? (y / n) : "; cin >> know;

        if(know == "n" || know == "N"){
            cout << "\nFirst A Little Introduction To The Rules : \n\n";
            rules();
            cout << "\nNext A Few Tips : \n\n";
            tips();
            cout << "\nAnd That's ALL!!!\n\n";
            system("pause");
            cout << "\n\n";
        }

        cout << "\nPlease Pick Your Board Preference : \n\n";

        cout << "1.)\n";
        print1();
        cout << "2.)\n\n";
        print2();

        cout << endl;

        string option;
        cout << "Please Enter Your Option : "; cin >> option;

        if(option == "1") s = 1;
        if(option == "2") s = 2;

        cout << endl;

        cout << "Change Characters Via [Main Menu -> Settings -> Change Characters]\n";
        cout << endl;

        cout << "Here You Must Try Your Luck Against Three Levels!!\n\n";
        cout << "1.) Easy\n";
        cout << "2.) Hard\n";
        cout << "3.) Insane\n";
        cout << endl;

        cout << "Can YOU Beat Them ALL????\n";
        cout << "Let's See....\n\n";

        system("pause");
        system("CLS");
    }

    void play(char p1, char p2){
        system("CLS");
        initialize();
        srand(time(NULL));

        string computer = getRandomName();

        int level;

        cout << "1.) Easy\n";
        cout << "2.) Hard\n";
        cout << "3.) Insane\n";
        cout << endl;
        cout << "Please Enter Level : "; cin >> level;

        system("CLS");

        while(computer == player){
            computer = getRandomName();
        }

        cout << "\t\t" << player << " VS " << computer << "\n\n\n";

        int c = rand() % 2;

        char pl = p1, ai = p2;

        if(c == 0){
            ai = p1;
            pl = p2;

            cout << "\n" << computer << " Goes First!\n\n\n";
        }

        else {
            cout << "\n" << player << " Goes First!\n\n\n";
            if(s == 1) print1();
            else print2();
        }

        int d = 0;

        while(true){
            int t = d % 2;

            if(t == c){
                if(level == 1) getEasyAIMove(ai, pl, 1, computer);
                if(level == 2) getHardAIMove(ai, pl, 1, computer);
                if(level == 3) getInsaneAIMove(ai, pl, 1, computer);

                if(s == 1) print1();
                else print2();

                if(win(ai)){
                    cout << computer << " Wins!\n" << endl;
                    cout << "Below Is How " << computer << " Won\n\n";
                    printWin(ai);
                    break;
                }
            }

            else {
                getUserMove(pl, ai);

                if(s == 1) print1();
                else print2();

                if(win(pl)){
                    cout << player << " Wins!\n";
                    cout << "Below Is How " << player << " Won\n\n";
                    printWin(pl);
                    break;
                }
            }

            if(tie()){
                cout << "Tie!\n";
                break;
            }

            d += 1;
        }

        playAgain(p1, p2);
    }

    void initialize(){
        board[0][0] = '1'; s_board[0][0] = ' ';
        board[0][1] = '2'; s_board[0][1] = ' ';
        board[0][2] = '3'; s_board[0][2] = ' ';
        board[1][0] = '4'; s_board[1][0] = ' ';
        board[1][1] = '5'; s_board[1][1] = ' ';
        board[1][2] = '6'; s_board[1][2] = ' ';
        board[2][0] = '7'; s_board[2][0] = ' ';
        board[2][1] = '8'; s_board[2][1] = ' ';
        board[2][2] = '9'; s_board[2][2] = ' ';
    }

    void playAgain(char p1, char p2){
        cout << "\n";

        string option;
        cout << "Would You Like To Play Again? (y(yes) / n(no) / m(Main Menu) : "; cin >> option;

        if(option == "y" || option == "Y")
            play(p1, p2);

        else if(option == "n" || option == "N")
            return ;

        else if(option == "m" || option == "M")
            return ;

        else {
            cout << "\nPlease Enter a Valid Option";
            playAgain(p1, p2);
        }
    }

    bool win(char p){
        bool r1 = board[0][0] == board[0][1] && board[0][1] == board[0][2] && board[0][0] == p;
        bool r2 = board[1][0] == board[1][1] && board[1][1] == board[1][2] && board[1][0] == p;
        bool r3 = board[2][0] == board[2][1] && board[2][1] == board[2][2] && board[2][0] == p;

        bool c1 = board[0][0] == board[1][0] && board[1][0] == board[2][0] && board[0][0] == p;
        bool c2 = board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] == p;
        bool c3 = board[0][2] == board[1][2] && board[1][2] == board[2][2] && board[0][2] == p;

        bool d1 = board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == p;
        bool d2 = board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] == p;

        return r1 || r2 || r3 || c1 || c2 || c3 || d1 || d2;
    }

    bool tie(){
        bool c1 = board[0][0] != '1';
        bool c2 = board[0][1] != '2';
        bool c3 = board[0][2] != '3';
        bool c4 = board[1][0] != '4';
        bool c5 = board[1][1] != '5';
        bool c6 = board[1][2] != '6';
        bool c7 = board[2][0] != '7';
        bool c8 = board[2][1] != '8';
        bool c9 = board[2][2] != '9';

        return c1 && c2 && c3 && c4 && c5 && c6 && c7 && c8 && c9;
    }
};

int main()
{
    TicTacToe game;

    game.main_menu();
}
\$\endgroup\$
  • \$\begingroup\$ The code is either "almost the same", or it is "similar". "Almost similar" sounds like "totally different" :) Anyway, avoid one letter variables, or at least the small "L", I keep reading it as "one", In either case i don't know what it is for... \$\endgroup\$ – slepic Nov 22 '19 at 13:36
  • \$\begingroup\$ @slepic Yes, I will edit my question fixing it. And l is for the length \$\endgroup\$ – Sriv Nov 22 '19 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.