help with Tic-tac-toe game; computer vs human

Discussion in 'C++' started by cozylittlekat, Apr 1, 2016.

  1. cozylittlekat

    cozylittlekat New Member

    Joined:
    Apr 1, 2016
    Messages:
    1
    Likes Received:
    1
    Trophy Points:
    0
    I am trying to make it so that if the human enters an number of a space that is already occupied, it will give an error message and not continue the program until a proper number is entered. currently, it gives an error message but the computer still takes its next turn. i think its giving an error message no matter what entered actually. This is the most pressing matter, but i am also trying to make the game be agressive against the human (take the middle spot if its not already take, if two spots are taken in a row/column/diagonally, fill the space so that it wins the game for the computer, or if thats not possible, block the human from getting a winning move). there is also a problem with the buffer that make there be an error message when starting the game over again.

    Code:
    // Code Block
    #include <iostream>
    #include <string>
    #include <cmath>
    #include <ctime>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <sstream>
    #include <fstream>
    #include <cctype>
    #include <iomanip>
    
    using namespace std;
    
    int Initialize(char[], const int);
    int OuputGameBoard(char[], const int);
    int InputMove(int, char[], int);
    int validateMove(int, char[], int);
    int InsertGamePiece(int, char[], int, const int);
    int IsspaceOccupied(char[], int);
    int winCondition(char[], char);
    int drawCondition(char[], const int);
    int playAgain(void);
    int main(void)
    {
        char GameBoard[] = {'0','0','0','0','0','0','0','0','0'};
        
        int    iIndex = 0;
        int    iSwitch = 0;
        int    iGameOver = 0;
        int i_IndexPosition=0;
        Initialize(GameBoard, 9);
    
        while(iGameOver==0)
        {
            
            iIndex = InputMove(iSwitch, GameBoard, i_IndexPosition);
            iGameOver = InsertGamePiece(iSwitch, GameBoard, iIndex, 9);
            OuputGameBoard(GameBoard, 9);
            iSwitch = iSwitch + 1;
            if (iSwitch==2)
                iSwitch = 0;
            
            if (iGameOver==1)
                iGameOver = playAgain();
            
            if (iGameOver==2)
            {
                iIndex = 0;
                iSwitch = 0;
                iGameOver=0;
                Initialize(GameBoard, 9);
            }   
        }
        return 0;
        
    }
    
    int Initialize(char cGameBoard[], const int iMaxNumberOfSpaces)
    {
        int iReturnValue = 0;
        for (int iIndex=0;iIndex<iMaxNumberOfSpaces;iIndex++)
        {
            cGameBoard[iIndex] = char(49+iIndex);
        }
        return iReturnValue;
        
    }
    
    int OuputGameBoard(char cGameBoard[], const int iMaxNumberOfSpaces)
    {
        int iReturnValue = 0;
        cout << "     |     |     " << endl;
        cout << "  " << cGameBoard[0] << "  |  " << cGameBoard[1] << "  |  " << cGameBoard[2] << endl;
        
        cout << "_____|_____|_____" << endl;
        cout << "     |     |     " << endl;
        
        cout << "  " << cGameBoard[3] << "  |  " << cGameBoard[4] << "  |  " << cGameBoard[5] << endl;
        
        cout << "_____|_____|_____" << endl;
        cout << "     |     |     " << endl;
        
        cout << "  " << cGameBoard[6] << "  |  " << cGameBoard[7] << "  |  " << cGameBoard[8] << endl;
        
        cout << "     |     |     " << endl << endl;
        
        return iReturnValue;
        
    }
    int InputMove(int iSwitch, char c_GameBoard[], int i_IndexPosition)
    {
        string sBuffer; 
        int iReturnValue = 0;
        
        while (iReturnValue==0)
        {
            if (iSwitch==0)
            {
                cout << "Please Enter your move" << endl;
                getline(cin, sBuffer);
                istringstream buffer(sBuffer);
                buffer >> iReturnValue;
            }
            else
            {
                iReturnValue = 0;
            }
            
            if (iSwitch==1)
            {
                iReturnValue = rand() % 9;
            }
            iReturnValue = validateMove(iReturnValue, c_GameBoard, i_IndexPosition);
            
        }
        
        iReturnValue = iReturnValue - 1;
        
        return iReturnValue;
        
    }
    int validateMove(int entryNumber, char c_GameBoard[], int i_IndexPosition)
    {
        
        int iReturnVaue = 0;
        
        if ((entryNumber>=1) && (entryNumber<=9))
        {
            iReturnVaue = entryNumber;
        }
        if(IsspaceOccupied(c_GameBoard, i_IndexPosition)==0)
        {
            cout << "Invalid entry." << endl;
            //iReturnVaue=0;
        }
        else
        {
            cout << "Invalid entry." << endl;
        }
        
        
        return iReturnVaue;
        
    }
    
    int InsertGamePiece(int iPlayerNumber, char c_GameBoard[], int i_IndexPosition, const int i_MaxNumberOfSpaces)
    {    
        int iReturnValue = 0;
        int iWinCondtionTest = 0;
        int idrawConditionTest = 0;
        char cGamePiece = NULL;
        string sPlayerType = "NOTHING";
        
        if(iPlayerNumber==0)
            cGamePiece ='X';
        
        if(iPlayerNumber==1)
            cGamePiece ='O';
        
        if (IsspaceOccupied(c_GameBoard, i_IndexPosition)==0)
        {
            if (cGamePiece!=NULL)
            {
                c_GameBoard[i_IndexPosition] = cGamePiece;
            }
            
        }
        else
        {
            if (iPlayerNumber==1)
            { 
                for (int iIndex=0;iIndex<i_MaxNumberOfSpaces;iIndex++)
                {
                    if(IsspaceOccupied(c_GameBoard, iIndex)==0)
                    {
                        c_GameBoard[iIndex]=cGamePiece;
                        iIndex=i_MaxNumberOfSpaces;
                    }   
                }    
            }    
        }
        
        iWinCondtionTest = winCondition(c_GameBoard, cGamePiece);
        idrawConditionTest = drawCondition(c_GameBoard, i_MaxNumberOfSpaces);
        
        if (iWinCondtionTest==1)
        {
            
            if (iPlayerNumber==0)
                sPlayerType = "Human";
            
            if (iPlayerNumber==1)
                sPlayerType = "Computer";
            
            cout <<  sPlayerType << " wins!!!" << endl;
            
        }
        
        if (idrawConditionTest==1)
        {
            cout << "Tie" << endl;    
        }
        
        if ((iWinCondtionTest==1) || (idrawConditionTest==1))
        {
            cout << "Game Over" << endl;
            iReturnValue = 1;
        }
        
        return iReturnValue;    
    }
    
    int IsspaceOccupied(char c_GameBoard[], int i_IndexPosition)
    {    
        int iReturnValue = 0;
        int iAsciiValue  = 0;
        iAsciiValue = (int) c_GameBoard[i_IndexPosition];
        
        if ((iAsciiValue>=49) && (iAsciiValue<=57))
        {
            iReturnValue = 0;
        }
        else
        {
            iReturnValue = 1;
        }
        
        return iReturnValue;    
    }
    
    int winCondition(char c_GameBoard[], char c_GamePiece)
    {
        
        int iReturnValue = 0;
        
        /*Across*/
        if ((c_GameBoard[0]==c_GamePiece) && (c_GameBoard[1]==c_GamePiece) && (c_GameBoard[2]==c_GamePiece))
            iReturnValue=1;
        
        if ((c_GameBoard[3]==c_GamePiece) && (c_GameBoard[4]==c_GamePiece) && (c_GameBoard[5]==c_GamePiece))
            iReturnValue=1;
        
        if ((c_GameBoard[6]==c_GamePiece) && (c_GameBoard[7]==c_GamePiece) && (c_GameBoard[8]==c_GamePiece))
            iReturnValue=1;
        
        /*Down*/
        if ((c_GameBoard[0]==c_GamePiece) && (c_GameBoard[3]==c_GamePiece) && (c_GameBoard[6]==c_GamePiece))
            iReturnValue=1;
        
        if ((c_GameBoard[1]==c_GamePiece) && (c_GameBoard[4]==c_GamePiece) && (c_GameBoard[7]==c_GamePiece))
            iReturnValue=1;
        
        if ((c_GameBoard[2]==c_GamePiece) && (c_GameBoard[5]==c_GamePiece) && (c_GameBoard[8]==c_GamePiece))
            iReturnValue=1;
        
        /*Diag*/
        if ((c_GameBoard[0]==c_GamePiece) && (c_GameBoard[4]==c_GamePiece) && (c_GameBoard[8]==c_GamePiece))
            iReturnValue=1;
        
        if ((c_GameBoard[2]==c_GamePiece) && (c_GameBoard[4]==c_GamePiece) && (c_GameBoard[6]==c_GamePiece))
            iReturnValue=1;
        
        return iReturnValue; // No one has won/game continues if game end condition isn't met either
        
    }
    
    int drawCondition(char c_GameBoard[], const int iMaxNumberOfSpaces)
    {
        
        int iCounter    = 0;
        int iAsciiValue = 0;
        int iReturnValue = 0;
        
        for (int iIndex=0;iIndex<iMaxNumberOfSpaces;iIndex++)
        {
            iAsciiValue = (int) c_GameBoard[iIndex];
            
            if ((iAsciiValue<49) || (iAsciiValue>57))
                iCounter = iCounter + 1;
            
        }
        
        if (iCounter==iMaxNumberOfSpaces)
        {
            cout << "All Spaces are Occupied" << endl;
            iReturnValue = 1;
        }
        
        return iReturnValue;
        
    }
    
    
    
    int playAgain(void)
    {
        
        
        int iReturnValue = -1;
        char cCharacter = NULL;
        
        while(iReturnValue==-1)
        {
            
            cout << "play again? Y/N";
            
            cCharacter = getchar();
            
            if (cCharacter=='y') cCharacter = 'Y';
            if (cCharacter=='n') cCharacter = 'N';
            
            if (cCharacter=='N') iReturnValue = 1;
            if (cCharacter=='Y') iReturnValue = 2;
            
            if ((cCharacter!='N') && (cCharacter!='Y'))
            {
                cout << "Error";
            }
            
        }
        
        return iReturnValue;
        
    }
    
     
    shabbir likes this.
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Your code looks pretty good so what you need help with here is how to debug.

    Looking at InputMove() we can see from your problem description that iReturnValue must be getting set to non-zero when an occupied position is chosen. So we need to look into validateMove() to find out why.

    This is where I would start adding printf statements to the code, so that we can see what it's doing. Clearly we need to see why iReturnVaue is getting wrongly set to non-zero. Add a printf statement each time you change iReturnVaue so that you can see how and why it changes, for example:
    Code:
        if ((entryNumber>=1) && (entryNumber<=9))
        {
            iReturnVaue = entryNumber;
            printf("Position validation: set iReturnVaue to %d\n",iReturnVaue);
        }
    
    Also I would change the duplicate error with a numeric index so that I can see why the error was displayed. Currently it displays "Invalid entry." whether IsspaceOccupied returns TRUE or FALSE. I would change that to display "Invalid entry(1)." and "Invalid entry(2)."

    I suspect by now you will have found the bug, because I think I have. But if not then repeat the above approach inside IsspaceOccupied(); perhaps the problem is caused by that function returning the wrong value, so you would need to work out why.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice