Search code examples
c++tic-tac-toe

How to fix random number generator in Tic-Tac-Toe


First of all i would like to say that i am a beginner in programming (and my english sucks). I am building a Tic Tac Toe game that you can play with the computer (using a random number generator) but i am geting one strange error that i cannot find a way out.

I didn´t implement the "end game" condition but sometimes, when the pc gets stuck in one choise, the game ends. The funny thing is, if i add 2 lines of code just to see whats happening with the pc choise, it does not crash until the "end" of the game ("end" because there is no win condition yet)

other question that i have, that would solve my problem, is how to implement an exception to the function that randomize the number for the fields that have already something in it?

pcTurn();
    cout << "\nComputer chosed field " << field << endl;
    cout << endl;

Above are the lines i talked about. The lines at the beginning of the function "input ()" that makes the program runs differently when they are read are the two "cout" under "pcTurn()". i tried them in and out of the code putting "//" in front of it, and with then, the program MORE OFTEN, runs until the end, without the, it always crashes before the end, and i have no idea why.

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

char matrix [3][3] = {'.','.','.','.','.','.','.','.','.',};
char player = 'X';
int field = 0;
int pcChoice = 0;
bool endGame = false;


//matrix
void draw (){

        for (int i=0; i<3; i++){
            for (int j=0; j<3; j++){
                cout << matrix [i][j] << " ";
        }
        cout << endl;
    }   
}

//pc turn - choice
int pcTurn (){

    srand(time(0));
    pcChoice = 1+ (rand () %9);
    field = pcChoice;


}

//input
void input (){

    if (player == 'X')
    {
        cout << "\nplayer " << player << " chose your field: ";
        cin >> field;
        cout << endl;
    }
    else
    {
        pcTurn();
        cout << "\nComputer chosed field " << field << endl;
        cout << endl;
    }   


    if (field == 1)
    {
        if (matrix [0][0] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [0][0] = player;
        }
    }
    else if (field == 2)
    {
        if (matrix [0][1] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [0][1] = player;
        }
    }
    else if (field == 3)
    {
        if (matrix [0][2] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [0][2] = player;
        }
    }
    else if (field == 4)
    {
        if (matrix [1][0] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [1][0] = player;
        }
    }
    else if (field == 5)
    {
        if (matrix [1][1] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [1][1] = player;
        }
    }
    else if (field == 6)
    {
        if (matrix [1][2] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [1][2] = player;
        }
    }
    else if (field == 7)
    {
        if (matrix [2][0] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [2][0] = player;
        }
    }
    else if (field == 8)
    {
        if (matrix [2][1] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [2][1] = player;
        }
    }
    else if (field == 9)
    {
        if (matrix [2][2] != '.')
        {
            if (player == 'X')
            {
                cout << "\ninvalid choice!" << endl;
            } 
            input ();
        }
        else
        {
            matrix [2][2] = player;
        }
    }
}




//toggle player
void togglePlayer (){
    if (player == 'X')
        player = 'O';
    else
        player = 'X';
}

int main (){

    draw ();

    do {
    input ();
    draw ();
    togglePlayer ();

    } while (endGame == false);
    return 0;
}

I would like, as it is right now, to be able to finish all the free spaces on the game and then and only then, get the program to an infinite loop "since i didnt implemet a lot of features yet, including end game condition)


Solution

  • Well i fixed your input function the recursive calls were too much * the changes are commented* whats left for you is to determine the end of game :) + as pointed above srand is used once when you start your program

    void input() {
    
        if (player == 'X')
        {
            cout << "\nplayer " << player << " chose your field: ";
            cin >> field;
            cout << endl;
        }
        else
        {
            pcTurn();
            cout << endl;
        }
    
    
        // instead of testing each field by its self you can just do it like this for example
        // field = 4 (filed-1)/3 is 1 & field-1 %3 is 0 so second line first column that would make it much shorter
    
        // now you ask the used for its choice till its an empty place
        // same thing for the pc play it will generate randoms till it finds an empty place 
    
        while(matrix[(field - 1) / 3][((field - 1) % 3)] != '.')
            {
                if (player == 'X')
                {
    
                    cout << "\ninvalid choice!" << endl;
                    cout << "\nplayer " << player << " chose your field: ";
                    cin >> field;
                    cout << endl;
                }
                else {
    
                    pcTurn();
    
                }
    
            }
    
                if (player!= 'X')
                {
    
                    cout << "\nComputer chosed field " << field << endl;
                    cout << endl;
                    }
    
                matrix[(field - 1) / 3][((field - 1) % 3)] = player;
    
    
                }