Search code examples
c++tic-tac-toe

Can't figure out how to loop playerturns and moves Tic Tac Toe (C++)


EDIT: Solved now thank you triple_r and AJNeufield for your help on this problem I was having.

I've looked around multiple websites and YouTube about this and I can't seem to find anything on what I am specifically looking for this as my format for the program is a good bit different than others. Therefore, it's hard to decipher where I need to put the things I do need that I know of.

Please note that I'm relatively new to C++ so I'd appreciate all the feedback or criticism you might provide me.

Also, note my code does compile and run it just does not allow me to put in more than one input and more than likely does not allow for a switch of player turns.

Quick Edit: Switched the code with the new setup suggested by triple_r but I seemed to have messed it up somewhere along the line and it does compile(with the exception of x and y not being utilized and one other error) but it always starts off with player 2 going first and as soon as it receives input it ends automatically with a segmentation fault.

#include <iostream>
#include <cstdlib>
using namespace std;
//////////////////////////////////////////////////////////
void initboard(char board[3][3])
{
    int x,y;
    for (x=0;x<3;x++)
            for (y=0;y<3;y++)
            board[x][y]=' ';
    return;
}
//////////////////////////////////////////////////////////
void printboard(char board[3][3])
{
    int x,y;
    for (x=0;x<3;x++)
    {
        cout<<"\n";
        for (y=0;y<3;y++)
        {
            cout<<" "<<board[x][y]<<" ";
            if (y<2) cout<<"|";
        }
        if (x<2) cout<<"\n===========";
    }
    return;
}
//////////////////////////////////////////////////////////
void getmove(char board[3][3], int player)
{
    return;
}
//////////////////////////////////////////////////////////
int main()
{
    bool done=false;
    char board[3][3];
    int x,y,player=1,turn,playerchoice,playermark;

    initboard(board);
    turn=0;
    do
    {
        if (player==1)
            playermark='X';
        else
            playermark='O';
        if (turn%2)
            player=1;
        else
            player=2;

        cout<<"Player "<<player<<" where do you want to move?: ";   
        cin>>playerchoice;
        if (playerchoice==1)
        {
            board[0][0]=playermark;
        }
        else if (playerchoice==2)
        {
            board[0][1]=playermark; 
        }
        else if (playerchoice==3)
        {
            board[0][2]=playermark;
        }
        else if (playerchoice==4)
        {
            board[1][0]=playermark;
        }
        else if (playerchoice==5)
        {
            board[1][1]=playermark;
        }
        else if (playerchoice==6)
        {
            board[1][2]=playermark;
        }
        else if (playerchoice==7)
        {
            board[2][0]=playermark;
        }
        else if (playerchoice==8)
        {
            board[2][1]=playermark;
        }
        else if (playerchoice==9)
        {
            board[2][2]=playermark;
        }
        else
        {
            cout<<"Invalid move ";
        }
        if (board[x][y]!=' ')
            cout<<"Move is already taken."; 
        board[x][y]=playermark;

        if(board[x][y]==' ')
            turn++;
    }while (!done);
    void printboard(char board[3][3]);
    return 0;
}

Solution

  • EDIT: based on the updated code

    So, the first thing I can see is that you are using x and y in your program but you don't initialize them or assign any values to them. Also, try to use functions/classes/... yo make your code more readable. You already have a function for player move but you are not using it. You can move the large if statement inside that function and that will make your main code shorter and more readable.

    Here are my comments on the main part of your program:

    int main()
    {
        // add a new variable to see if the move was valid or not:
        bool done=false, validmove = true;
        char board[3][3];
        int x, y, player = 1, turn = 0, playerchoice, playermark;
    
        initboard(board);
        do
        {
            // swap the two `if`s so you decide who`s turn it is then assign the player mark,
            //  also, reverse the condition to make sure turn '0' is player 1's turn.
            if (!(turn % 2))
                player = 1;
            else
                player = 2;
            if (player == 1)
                playermark = 'X';
            else
                playermark = 'O';
    
            cout << "Player " << player << " where do you want to move?: ";
            cin >> playerchoice;
    
            // Assign `x` and `y` here instead of updating the board, because you want to make
            //  sure that the move is valid before putting the mark:
            validmove = true;
            if (playerchoice == 1)
            {
                x = 0; y = 0;
            }
            else if (playerchoice == 2)
            {
                x = 0; y = 1;
            }
            else if (playerchoice == 3)
            {
                x = 0; y = 2;
            }
            else if (playerchoice == 4)
            {
                x = 1; y = 0;
            }
            else if (playerchoice == 5)
            {
                x = 1; y = 1;
            }
            else if (playerchoice == 6)
            {
                x = 1; y = 2;
            }
            else if (playerchoice == 7)
            {
                x = 2; y = 0;
            }
            else if (playerchoice == 8)
            {
                x = 2; y = 1;
            }
            else if (playerchoice == 9)
            {
                x = 2; y = 2;
            }
            else
            {
                cout << "Invalid move, try again!";
    
                // Make sure to mark the move as invalid so they get a chance to
                //  change their move:
                validmove = false;
            }
    
            // check to see if the turn was valid:
            if(validmove)
            {
                if (board[x][y] != ' ')
                {
                    cout << "Move is already taken, try again";
                }
                else
                {
                    board[x][y] = playermark;
                    turn++;
                }
            }
    
            // have to make sure you have a condition for end of game. A simple
            //  one is to check if turn is less than `9`, otherwise the board is
            //  full:
            if(turn == 9)
                done = true;
    
            // you probably want to add a few more checks to see who won the game.
        }while (!done);
    
        // when calling a function, no need to put the return type or parameter type:
        printboard(board);
        return 0;
    }
    

    ========================================================================

    There are two do-while loops in your program and both seem to be meant as a game loop. What I would do is:

    initboard(...);
    turn = 0;
    do{
        //this is the game loop
        ...;
        if( validturn )
            turn++;
    }while(!done);
    release_resources(...);
    return 0;
    

    so, you fold everything into one loop. In that loop, you want to:

    1. find who's turn it is:

      if (turn % 2)
          player = 1;
      else
          player = 2;
      
    2. get users input:

      std::cin >> playerchoice;
      ...
      
    3. convert player choice to grid location:

      switch ( move )
      {
          case 0:
              x = 0;
              y = 0;
              break;
          case 1:
              ...;
          ...
          default:
              //invalid move
      }
      
    4. see if the move is valid:

      if( board[x][y] != ' ' )
          //already taken, invalid move
      
    5. then apply the move:

      board[x][y] = playermark;
      

    I hope this helps.