Thread: Tic Tac Toe issue

  1. #1
    Registered User
    Join Date
    Mar 2014
    Posts
    2

    Tic Tac Toe issue

    Hello all, forgive me for including my entire program, but the problem
    is very annoying and I can't figure out where it is. Essentially, after a winner or a tie, program will reach the return statement which should exit the class, but it doesn't. It jumps out of the drawBoard() member function and into the two_in_row() member function, where it goes through that and sometimes makes an additional move, changing the outcome of the game.

    Code:
    
    
    Code:
    //Implementaion file that includes all of the classes and their innards
    //classImp.h
    
    #include <iostream>
    #include <cstdlib>        //for random number generator
    #include <ctime>        //for seed (srand)
    #include "dec.h"
    
    
    #define LINES "\n\n\n\n\n\n\n\n\n\n\n\n"
    #define TAB "   "
    #define BIGTAB "\t\t\t" 
    using namespace std;
    
    
    void Draw::opponent(int &opp)
    {
        cout << "Who do you want to play against?\nEnter the number corresponding to your choice.\n";
        cout << "1. Player\n";
        cout << "2. Computer\n";
        cin >> opp;
        
        //discards characters until new line is found
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << endl;
        //if user did not enter a valid repsonse
        if (opp != 1 && opp != 2)
        {
            cout << "Please choose a valid choice.\n";
            opponent(opp);
        }
        player = 0;
        //playing against another player
        if (opp == 1)
            p_v_p(player1, player2);
        //playing against the computer
        else
            p_v_comp(player1);
    }
    
    
    void Draw::p_v_p(string &player1, string &player2)
    {
        cout << "Player 1 name: ";
        getline(cin, player1);
        cout << "Player 2 name: ";
        getline(cin, player2);
        cout << endl;
        cout << "To choose a square, type in the corresponding number.\n";
    }
    
    
    void Draw::p_v_comp(string &player1)
    {
        cout << "Player name: ";
        getline(cin, player1);
        cout << "To choose a square, type in the corresponding number.\n";
        srand(time(NULL));        //For the random number generator
    }
    
    
    void Draw::cells()
    {
        board[0][0] = '1';
        board[0][1] = '2';
        board[0][2] = '3';
        board[1][0] = '4';
        board[1][1] = '5';
        board[1][2] = '6';
        board[2][0] = '7';
        board[2][1] = '8';
        board[2][2] = '9';    
    }
    
    
    //Draws the empty playing board
    int Draw::drawBoard()
    {
        cout << LINES;
        cout << BIGTAB << TAB << board[0][0] << " |" << TAB << board[0][1] << " |" << TAB << board[0][2] << "\n";
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        cout << BIGTAB << " " << "----+-----+----\n";
        cout << BIGTAB << TAB << board[1][0] << " |" << TAB << board[1][1] << " |" << TAB << board[1][2] << "\n";
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        cout << BIGTAB << " " << "----+-----+----\n";
        cout << BIGTAB << TAB << board[2][0] << " |" << TAB << board[2][1] << " |" << TAB << board[2][2] << "\n";
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        cout << BIGTAB << TAB << "  |" << TAB << "  |" << endl;
        //next person's turn
        if (player == 0 || player == 2)
            player = 1;
        else
            player = 2;
        int win = testWinner();
        //if there is a winner or tie, exit the program
        if (win == 1)
        {
            cout << "RETURN\n";
            return 0;
        }
        if (win == 0)
        {
            //if playing against another player
            if (opp == 1)
                playerMoves(player1, player2, player, opp);
            //if playing against computer
            else
            {
                success = compMoves(player1, player);
                if (success == 1)
                    return 0;
            }
        }
    }
    
    
    void Draw::playerMoves(string player1, string player2, int player, int opp)
    {
        if (player == 0 || player == 1)
            cout << player1 << "'s turn: ";
        else
        {
            if (opp == 1)            
                cout << player2 << "'s turn: ";        
            //if playing against computer, move to compMoves
            else
                compMoves(player1, player);
        }
        string input;        //each player's move
        getline(cin, input);
        while (input != "1" && input != "2" && input != "3" && input != "4" && input != "5" &&
               input != "6" && input != "7" && input != "8" && input != "9")
        {
            cout << "Error: Please enter a cell 1-9\n";
            cout << "Please choose again: ";
            getline(cin, input);
        }
        //makes the letter a character
        char move = input[0];
        //if the number is different, move on
        if (!isSame(move))
            newBoard(move, player);
        //if it is the same, print revert back to ask for another number
        else
            playerMoves(player1, player2, player, opp);
    }
    
    
    int Draw::compMoves(string player1, int player)
    {
        opp = 2;
        //defaults to playerMoves
        if (player == 0 || player == 1)
            playerMoves(player1, player2, player, opp);
        else if (count == 9)
            return 1;
        else 
        {
            //if it's the computer's turn
            //if there are no possible winners
            if (!two_in_row())
            {
                char move = randomCell();
                newBoard(move, player);
            }
        }
    }
    
    
    bool Draw::two_in_row()
    {
        int moveTest = 0;            //tests to see if any move has been made
        char moveComp = 'a';        //the computers move
        //testing each cell for the opponent's piece
        for (int r = 0; r < 3; r++)
        {
            int tempR = r;
            for (int c = 0; c < 3; c++)
            {
                int tempC = c;
                //if the cell has 'X' test for adjacent cells
                if (board[r][c] == 'X')
                {
                    //if the cell is on the edge, move to the other side
                    if (r == 2)
                    {
                        tempR = 0;
                        //MOVING IN THE MIDDLE OF THE COLUMN
                        if (board[tempR][c] == 'X')
                        {
                            if (!isSame(tempR, c))
                            {
                                //assigns the new move to the array
                                if (c == 0)
                                    moveComp = '4';
                                if (c == 1)
                                    moveComp = '5';
                                if (c == 2)
                                    moveComp = '6';
                                //stores the new value into the array
                                storeArr(moveComp);
                                board[tempR + 1][c] = 'O'; //0 + 1 = middle cell
                                tempArr[count] = moveComp;
                                drawBoard();
                                moveTest = 1;
                            }
                            else
                                continue;
                        }
                    }
                    else if (c == 2)
                    {
                        tempC = 0;
                        //MOVING IN THE MIDDLE OF THE ROW
                        if (board[r][tempC] == 'X')
                        {
                            if (!isSame(r, tempC))
                            {
                                if (r == 0)
                                    moveComp = '2';
                                if (r == 1)
                                    moveComp = '5';
                                if (r == 2)
                                    moveComp = '8';
                                storeArr(moveComp);
                                board[r][tempC + 1] = 'O';
                                tempArr[count] = moveComp;
                                drawBoard();
                                moveTest = 1;
                            }
                            else
                                continue;
                        }
                    }
                    else
                    {
                        //if the next cell right has an 'X'
                        if (board[r][c + 1] == 'X')
                        {
                            //MOVING TO THE LEFT SIDE OF THE ROW
                            if ((c + 1) == 2)
                            {
                                tempC = 0;
                                if (!isSame(r, tempC))
                                {
                                    if (r == 0)
                                        moveComp = '1';
                                    if (r == 1)
                                        moveComp = '4';
                                    if (r == 2)
                                        moveComp = '7';
                                    storeArr(moveComp);
                                    board[r][tempC] = 'O';
                                    tempArr[count] = moveComp;
                                    drawBoard();
                                    moveTest = 1;
                                }
                                else
                                    continue;
                            }
                            //MOVING TO THE RIGHT SIDE OF THE ROW
                            else
                            {
                                if (!isSame(r, c + 2))
                                {
                                    if (r == 0)
                                        moveComp = '3';
                                    if (r == 1)
                                        moveComp = '6';
                                    if (r == 2)
                                        moveComp = '9';
                                    storeArr(moveComp);
                                    board[r][c + 2] = 'O';
                                    tempArr[count] = moveComp;
                                    drawBoard();
                                    moveTest = 1;
                                }
                                else
                                    continue;
                            }                        
                        }
                        //if the cell below has an 'X'
                        if (board[r + 1][c] == 'X')
                        {
                            //MOVING TO THE TOP OF THE COLUMN
                            if ((r + 1) == 2)
                            {
                                tempR = 0;
                                if (!isSame(tempR, c))
                                {
                                    if (c == 0)
                                        moveComp = '1';
                                    if (c == 1)
                                        moveComp = '2';
                                    if (c == 2)
                                        moveComp = '3';
                                    storeArr(moveComp);
                                    board[tempR][c] = 'O';
                                    tempArr[count] = moveComp;
                                    drawBoard();
                                    moveTest = 1;
                                }
                            }
                            //MOVING TO THE BOTTOM OF THE COLUMN
                            else
                            {
                                if (!isSame(r + 2, c))
                                {
                                    if (c == 0)
                                        moveComp = '7';
                                    if (c == 1)
                                        moveComp = '8';
                                    if (c == 2)
                                        moveComp = '9';
                                    storeArr(moveComp);
                                    board[r + 2][c] = 'O';
                                    tempArr[count] = moveComp;
                                    drawBoard();
                                    moveTest = 1;
                                }
                                else
                                    continue;
                            }
                        }
                    }
                }
            }
        }
        //MOVING IN THE CENTER CELL (testing the corners)
        if ((board[0][0] == 'X' && board[2][2] == 'X') || (board[0][2] == 'X' && board[2][0] == 'X'))
        {
            if (!isSame(1, 1))
            {
                moveComp = '5';
                storeArr(moveComp);
                board[1][1] = 'O';
                tempArr[count] = moveComp;
                drawBoard();
                moveTest = 1;
            }
        }
        //testing each diagonal combination
        if (board[0][0] == 'X' && board[1][1] == 'X')
        {
            if (!isSame(2, 2))
            {
                moveComp = '9';
                storeArr(moveComp);
                board[2][2] = 'O';
                tempArr[count] = moveComp;
                drawBoard();
                moveTest = 1;
            }
        }
        if (board[1][1] == 'X' && board[2][2] == 'X')
        {
            if (!isSame(0, 0))
            {
                moveComp = '1';
                storeArr(moveComp);
                board[0][0] = 'O';
                tempArr[count] = moveComp;
                drawBoard();
                moveTest = 1;
            }
        }
        if (board[2][0] == 'X' && board[1][1] == 'X')
        {
            if (!isSame(0, 2))
            {
                moveComp = '3';
                storeArr(moveComp);
                board[0][2] = 'O';
                tempArr[count] = moveComp;
                drawBoard();
                moveTest = 1;
            }
        }
        if (board[1][1] == 'X' && board[0][2] == 'X')
        {
            if (!isSame(2, 0))
            {
                moveComp = '7';
                storeArr(moveComp);
                board[2][0] = 'O';
                tempArr[count] = moveComp;
                drawBoard();
                moveTest = 1;
            }
        }
        //if there are no cells that are 2 in a row
        if (moveTest == 0)
            return false;
    }
    char Draw::randomCell()
    {
        int random;
        //makes the seed time different every time it is run    
        random = 1 + (rand() % (57 - 48) + 48);        //picks a random number from 1-9
        char randomChar = static_cast<char>(random);    //converts random number to applicable char
        if (!isSame(randomChar))
            return randomChar;
        else
            randomCell();
    }
    
    
    bool Draw::isSame(int r, int c)
    {
        if (board[r][c] == 'O')
            return true;
        else
            return false;
    }
    
    
    bool Draw::isSame(char move)
    {
        
        for (int i = 0; i < count; i++)
        {
            storeArr(move);
            //tests if the current move is the same as previous ones
            if (tempArr[i] == move)
            {
                if (opp == 1 || (opp == 2 && player == 1))
                {
                    cout << "YOU'RE A DUMBASS.\n";
                    cout << "Enter another number.\n";
                }
                return true;
            }
        }
        return false;
    }
    
    
    void Draw::storeArr(char move)
    {
        //stores the current move
        tempArr[count] = move;
    }
    
    
    //inserts and  'X' or 'O' into the correct cell
    void Draw::newBoard(int move, int player)
    {
        switch (move)
        {
        case '1':
            if (player == 1)
                board[0][0] = 'X';
            else
                board[0][0] = 'O';
            drawBoard();
            break;
        case '2':
            if (player == 1)
                board[0][1] = 'X';
            else
                board[0][1] = 'O';
            drawBoard();
            break;
        case '3':
            if (player == 1)
                board[0][2] = 'X';
            else
                board[0][2] = 'O';
            drawBoard();
            break;
        case '4':
            if (player == 1)
                board[1][0] = 'X';
            else
                board[1][0] = 'O';
            drawBoard();
            break;
        case '5':
            if (player == 1)
                board[1][1] = 'X';
            else
                board[1][1] = 'O';
            drawBoard();
            break;
        case '6':
            if (player == 1)
                board[1][2] = 'X';
            else
                board[1][2] = 'O';
            drawBoard();
            break;
        case '7':
            if (player == 1)
                board[2][0] = 'X';
            else
                board[2][0] = 'O';
            drawBoard();
            break;
        case '8':
            if (player == 1)
                board[2][1] = 'X';
            else
                board[2][1] = 'O';
            drawBoard();
            break;
        case '9':
            if (player == 1)
                board[2][2] = 'X';
            else
                board[2][2] = 'O';
            drawBoard();
            break;
        }
    }
    
    
    //tests to see if there is a winner or not
    int Draw::testWinner()
    {
        //tests every possible winning combination
        //Player 1 wins
        if ((board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X') ||
            (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X') ||
            (board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X') ||
            (board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X') ||
            (board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X') ||
            (board[0][2] == 'X' && board[1][1] == 'X' && board[2][0] == 'X') ||
            (board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X') ||
            (board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X'))
        {
            cout << player1 << " wins!!" << endl;
            return 1;
        }
        //Player 2 wins
        if ((board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O') ||
            (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O') || 
            (board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O') ||
            (board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O') ||
            (board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O') ||
            (board[0][2] == 'O' && board[1][1] == 'O' && board[2][0] == 'O') ||
            (board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O') ||
            (board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O'))
        {
            cout << player2 << " wins!!" << endl;
            return 1;
        }
        //if all cells have been entered with no winner
        if (count == 9)
        {
            cout << "It's a tie!!" << endl;
            return 1;
        }
        //if no winner
        else
        {
            count++;
            return 0;
        }
    }


  2. #2
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    It would be handy to see where the member function drawBoard() is called from.

    Additionally, testing for a winner doesn't really belong in drawBoard() does it? What does drawing the board have to do with testing for winning? Also, what does getting the next player move having to do with drawing the board?

    I'm guessing that the evaluation (test for win) is out of order

    Edit:
    What I mean by things being in the wrong place is that none of the code below belongs in drawBoard()... it should be at the same "level" as drawBoard() is called from

    Code:
        //next person's turn
        if (player == 0 || player == 2)
            player = 1;
        else
            player = 2;
        int win = testWinner();
        //if there is a winner or tie, exit the program
        if (win == 1)
        {
            cout << "RETURN\n";
            return 0;
        }
        if (win == 0)
        {
            //if playing against another player
            if (opp == 1)
                playerMoves(player1, player2, player, opp);
            //if playing against computer
            else
            {
                success = compMoves(player1, player);
                if (success == 1)
                    return 0;
            }
        }
    Last edited by Hodor; 03-11-2014 at 10:14 PM.

  3. #3
    Registered User
    Join Date
    Mar 2014
    Posts
    2
    Yes I understand this now. Was adding onto it, but you are right, i need a new member function for the code you selected.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bandwidth issue / network issue with wireless device communication
    By vlrk in forum Networking/Device Communication
    Replies: 0
    Last Post: 07-05-2010, 11:52 PM
  2. DNS issue
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 08-02-2008, 10:15 AM
  3. DLL issue
    By crazybucky in forum C++ Programming
    Replies: 1
    Last Post: 04-02-2008, 12:12 PM
  4. Issue with FAQ example
    By 3saul in forum C Programming
    Replies: 2
    Last Post: 04-16-2007, 05:13 AM
  5. What is the issue?
    By al_engler in forum C Programming
    Replies: 2
    Last Post: 12-19-2006, 01:54 PM

Tags for this Thread