Tic Tac Toe Code

skiboy209 2 Tallied Votes 272 Views Share

I thought i would share this with the community wrote most of it in school but the ai i wrote at home enjoy!

Dani commented: Thanks for sharing +0
DeanMSands3 commented: Nice, though he's right. Too many if-else statements. +4
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

using namespace std;

bool isP1;
enum results{xWins, oWins, draw, goOn};

void compMove(const char board[3][3]);
void drawBoard(const char board[3][3]);
void getMove(char board[3][3]);
void getMove2(char board[3][3]);
results getResults(const char board[3][3]);
void displayResults(results result, const char board[3][3]);

int main()
{
  
  srand ( time(NULL) );
  results result;
  char ans;
  int move;
  int cpMv;
  int numPlyrs;
    do
    {
  system("cls");
  char board[3][3] = {{' ', ' ', ' '},
		      {' ', ' ', ' '},
		      {' ', ' ', ' '}};
  do
  {
	cout <<"Would you like to play 1 or 2 player?";
	cin >> numPlyrs;
  }while(numPlyrs != 1 && numPlyrs != 2);
  
  do
  {
    if(numPlyrs == 1)
    {
        isP1 = true;
        break;
    }
	cout <<"Would you like to be x or o?\n";
	cin >> ans;
  if(ans == 'x')
	isP1 = true;
  else if(ans == 'o')
	isP1 = false;
  else
  {
	cout <<"That is not a valid choice\n";
	ans = 'r';
  }
  }while(ans == 'r');
  
  if(numPlyrs == 1)
  {
  
  do
    {
		getMove2(board);
		drawBoard(board);
		result = getResults(board);
		displayResults(result,board);
	}while(result == goOn);
   }
  else if(numPlyrs == 2)
  {
  do
    {
      getMove(board);
      drawBoard(board);
      result = getResults(board);
      displayResults(result,board);
    }while(result == goOn);
   }
    cout <<"Play again? (y/n)\n";
    cin >>ans;
    }while(ans == 'y' || ans == 'Y');
  
  return 0;  
}

void drawBoard(const char board[3][3])
{
  cout << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl;
  cout << "--+---+--\n";
  cout << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl;
  cout << "--+---+--\n";
  cout << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl;
}   

void getMove(char board[3][3])
{
  int move;
  cout << "Where would you like to move?\n";
  cout << "7 | 8 | 9\n";
  cout << "--+---+--\n";
  cout << "4 | 5 | 6\n";
  cout << "--+---+--\n";
  cout << "1 | 2 | 3\n";
  cin >> move;
  system("cls");

  if (move == 7)
    {
      if (board[0][0] == 'o' || board[0][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 8)
    {
      if (board[0][1] == 'o' || board[0][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 9)
    {
      if (board[0][2] == 'o' || board[0][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 4)
    {
      if (board[1][0] == 'o' || board[1][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 5)
    {
      if (board[1][1] == 'o' || board[1][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 6)
    {
      if (board[1][2] == 'o' || board[1][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 1)
    {
      if (board[2][0] == 'o' || board[2][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 1)
    {
      if (board[2][0] == 'o' || board[2][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
 else if (move == 2)
    {
      if (board[2][1] == 'o' || board[2][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
 else if (move == 3)
    {
      if (board[2][2] == 'o' || board[2][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
}
		  
	      
void getMove2(char board[3][3])
{
  int move;
  
  if(isP1)
  {
  cout << "Where would you like to move?\n";
  cout << "7 | 8 | 9\n";
  cout << "--+---+--\n";
  cout << "4 | 5 | 6\n";
  cout << "--+---+--\n";
  cout << "1 | 2 | 3\n";
  cin >> move;
  }
  
  else if(!isP1)
  { 
    if((board[2][0] == 'x' && board[1][0] == 'x')
        ||(board[2][2] == 'x' && board[1][1] == 'x')
        ||(board[0][1] == 'x' && board[0][2] == 'x'))
        if(board[0][0] != 'x' && board[0][0] != 'o')
            move = 7;
        else
            move = rand() % 9 + 1;
            
    else if((board[0][0] == 'x' && board[0][2] == 'x')
            ||(board[1][1] == 'x' && board[2][1] == 'x'))
        if(board[0][1] != 'x' && board[0][1] != 'o')
            move = 8; 
        else
            move = rand() % 9 + 1;  
    
    else  if((board[0][0] == 'x' && board[0][1] == 'x')
            ||(board[2][0] == 'x' && board[1][1] == 'x')
            ||(board[2][2] == 'x' && board[1][2] == 'x'))
        if(board[0][2] != 'x' && board[0][2] != 'o')
            move = 9;
        else
            move = rand() % 9 + 1;  
        
    else if((board[1][1] == 'x' && board[1][2] == 'x')
            ||(board[0][0] == 'x' && board[2][0] == 'x'))
        if(board[1][0] != 'x' && board[1][0] != 'o')
            move = 4;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][0] == 'x' && board[2][2] == 'x')
            ||(board[1][0] == 'x' && board[1][2] == 'x')
            ||(board[2][0] == 'x' && board[0][2] == 'x')
            ||(board[2][1] == 'x' && board[0][1] == 'x'))
        if(board[1][1] != 'x' && board[1][1] != 'o')
            move = 5;
        else
            move = rand() % 9 + 1;  
        
    else if((board[1][0] == 'x' && board[1][1] == 'x')
            ||(board[0][2] == 'x' && board[2][2] == 'x'))
        if(board[1][2] != 'x' && board[1][2] != 'o')
            move = 6;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][0] == 'x' && board[1][0] == 'x')
           ||(board[0][2] == 'x' && board[1][1] == 'x')
           ||(board[2][1] == 'x' && board[2][2] == 'x'))
        if(board[2][0] != 'x' && board[2][0] != 'o')
            move = 1;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][1] == 'x' && board[1][1] == 'x')
            ||(board[2][0] == 'x' && board[2][2] == 'x'))
        if(board[2][1] != 'x' && board[2][1] != 'o')
            move = 2;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][2] == 'x' && board[1][2] == 'x')
            ||(board[0][0] == 'x' && board[1][1] == 'x')
            ||(board[2][0] == 'x' && board[2][1] == 'x'))
        if(board[2][2] != 'x' && board[2][2] != 'o')
            move = 3;
        else
            move = rand() % 9 + 1;    
            
    if((board[2][0] == 'o' && board[1][0])
        ||(board[2][2] == 'o' && board[1][1] == 'o')
        ||(board[0][1] == 'o' && board[0][2] == 'o'))
        if(board[0][0] != 'x' && board[0][0] != 'o')
            move = 7;
        else
            move = rand() % 9 + 1;
            
    else if((board[0][0] == 'o' && board[0][2] == 'o')
            ||(board[1][1] == 'o' && board[2][1] == 'o'))
        if(board[0][1] != 'x' && board[0][1] != 'o')
            move = 8; 
        else
            move = rand() % 9 + 1;  
    
    else  if((board[0][0] == 'o' && board[0][1] == 'o')
            ||(board[2][0] == 'o' && board[1][1] == 'o')
            ||(board[2][2] == 'o' && board[1][2] == 'o'))
        if(board[0][2] != 'x' && board[0][2] != 'o')
            move = 9;
        else
            move = rand() % 9 + 1;  
        
    else if((board[1][1] == 'o' && board[1][2] == 'o')
            ||(board[0][0] == 'o' && board[2][0] == 'o'))
        if(board[1][0] != 'x' && board[1][0] != 'o')
            move = 4;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][0] == 'o' && board[2][2] == 'o')
            ||(board[1][0] == 'o' && board[1][2] == 'o')
            ||(board[2][0] == 'o' && board[0][2] == 'o')
            ||(board[2][1] == 'o' && board[0][1] == 'o'))
        if(board[1][1] != 'x' && board[1][1] != 'o')
            move = 5;
        else
            move = rand() % 9 + 1;  
        
    else if((board[1][0] == 'o' && board[1][1] == 'o')
            ||(board[0][2] == 'o' && board[2][2] == 'o'))
        if(board[1][2] != 'x' && board[1][2] != 'o')
            move = 6;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][0] == 'o' && board[1][0] == 'o')
           ||(board[0][2] == 'o' && board[1][1] == 'o')
           ||(board[2][1] == 'o' && board[2][2] == 'o'))
        if(board[2][0] != 'x' && board[2][0] != 'o')
            move = 1;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][1] == 'o' && board[1][1] == 'o')
            ||(board[2][0] == 'o' && board[2][2] == 'o'))
        if(board[2][1] != 'x' && board[2][1] != 'o')
            move = 2;
        else
            move = rand() % 9 + 1;  
        
    else if((board[0][2] == 'o' && board[1][2] == 'o')
            ||(board[0][0] == 'o' && board[1][1] == 'o')
            ||(board[2][0] == 'o' && board[2][1] == 'o'))
        if(board[2][2] != 'x' && board[2][2] != 'o')
            move = 3;
        else
            move = rand() % 9 + 1;           
     
    else
    {
        move = rand() % 9 + 1;
    }
}
  system("cls");
  
  if (move == 7)
    {
      if (board[0][0] == 'o' || board[0][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 8)
    {
      if (board[0][1] == 'o' || board[0][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 9)
    {
      if (board[0][2] == 'o' || board[0][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[0][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[0][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 4)
    {
      if (board[1][0] == 'o' || board[1][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 5)
    {
      if (board[1][1] == 'o' || board[1][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 6)
    {
      if (board[1][2] == 'o' || board[1][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[1][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[1][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 1)
    {
      if (board[2][0] == 'o' || board[2][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
  else if (move == 1)
    {
      if (board[2][0] == 'o' || board[2][0] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][0] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][0] = 'o';
	      isP1 = !isP1;
		}
	}
    }
 else if (move == 2)
    {
      if (board[2][1] == 'o' || board[2][1] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][1] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][1] = 'o';
	      isP1 = !isP1;
		}
	}
    }
 else if (move == 3)
    {
      if (board[2][2] == 'o' || board[2][2] == 'x')
	{
	  cout <<"Someone is on this spot already\n";
	}
      else
	{
	  if (isP1)
	    {
	      board[2][2] = 'x';
	      isP1 = !isP1;
	    }
	  else
	    {
	      board[2][2] = 'o';
	      isP1 = !isP1;
		}
	}
    }
}

		  
results getResults(const char board[3][3])
{
  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][2] == 'x' && board[1][1] == 'x' && board[2][0] == '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[1][0] == 'x' && board[1][1] == 'x' && board[1][2] == 'x')
      || (board[2][0] == 'x' && board[2][1] == 'x' && board[2][2] == 'x'))
    return xWins;

  else 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][2] == 'o' && board[1][1] == 'o' && board[2][0] == '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[1][0] == 'o' && board[1][1] == 'o' && board[1][2] == 'o')
	   || (board[2][0] == 'o' && board[2][1] == 'o' && board[2][2] == 'o'))
    return oWins;

  else if ((board[0][0] != ' ' && board[1][0] != ' ' && board[2][0] != ' ')
	   && (board[0][1] != ' ' && board[1][1] != ' ' && board[2][1] != ' ')
	   && (board[0][2] != ' ' && board[1][2] != ' ' && board[2][2] != ' '))
    return draw;
  
  else
    return goOn;
}

void displayResults(results result, const char board[3][3])
{
  if(result == oWins)
    cout <<"O wins!\n";
  
  else if(result == xWins)
    cout <<"X wins!\n";
  
  else if(result == draw)
    cout <<"You tied!\n";
}

Dani AI

Generated

Nice share, — compact and playable. A few concrete problems and practical refactors will make the program safer, easier to maintain, and let the AI stop losing as pointed out. ’s OOP hint is on target: isolating player behavior and using a small set of utilities reduces the many repeated if/else blocks.

Immediate issues to fix

  • Duplicate branch: else if (move == 1) appears twice — remove the duplicate.
  • Typo in AI checks: if((board[2][0] == 'o' && board[1][0]) is missing == 'o'. That condition is wrong and can evaluate unexpectedly.
  • Random picks can choose an occupied square and the code then prints a message but does not retry; that can stall the game flow.
  • system("cls") is Windows-only and hides portability; prefer printing the board or using a cross-platform clear routine.
  • Lots of repeated placement logic — move-to-index mapping + a single placement function will clean up both getMove and getMove2.

Small refactor example (use a 1D board and one placement routine):

static const int keyToIndex[10] = { -1, 6,7,8,3,4,5,0,1,2 };

bool placeMove(char board[9], int move, char mark) {
    if (move < 1 || move > 9) return false;
    int i = keyToIndex[move];
    if (board[i] != ' ') return false;
    board[i] = mark;
    return true;
}

static const int wins[8][3] = {
  {0,1,2},{3,4,5},{6,7,8},
  {0,3,6},{1,4,7},{2,5,8},
  {0,4,8},{2,4,6}
};

AI guidance

  • Short fix: prefer this priority — win if possible, block opponent, take center (index 4), take an empty corner, take any side. That eliminates pure-random weaknesses.
  • For an unbeatable opponent, implement Minimax (recursively simulate moves, score terminal states, pick the best score). Minimax is heavier but deterministic and small for 3×3 tic-tac-toe.

Quick tips

  • Validate input in a loop until placeMove succeeds for humans and re-roll random picks for the AI until a free cell is found.
  • Replace the global isP1 with a small Player class or an enum for clarity.
    These changes keep the original structure but remove most duplication, fix the bugs above, and make the AI useful rather than merely random.
Saith 74 Junior Poster

That is a lot of if-else statements. Think you can rewrite this with a more logical approach?

Note: This is not to bash you! If you can think of creating this with another approach, it may help with other types of OOP. Consider using a class for each player as either X or O, and using enum. ::hint hint:: :D
2nd Note: Oh, sorry. This was posted ~2 weeks ago. Likely should not have replied to this thread by now.

PalashBansal96 0 Newbie Poster

You will always lose if you play randomly

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.