/*
tictactoe.cpp
Written by: Ken Mathis
Written on: 07/08/02
Purpose: Play tic-tac-toe of course :)
This is a tictactoe game. The AI (artificial intelligence) is pretty strong.
First the engine checks if it can win, if it can it moves there ;) of course.
If the engine can't win on his next move he checks to see if the player can.
If he can't win and the player can't win, he moves to a random open square.
*/

// include the header files
#include 
#include 
#include 
#include 
#include 

// declare functions
void displayboard();
void pickagain();
void move(int pos);
void instructions();
int checkwin();
int checkcats();
int ai();

// global variables
int board[3][3];
int turn = 1;

// main function
int main()
{
  // declare necessary variables
  int position;
  int win, cats;
  int x;

  // make it more random :)
  srand((unsigned) time(NULL)); 

  instructions(); // show instructions
  displayboard(); // show board
  // main loop
  do
    {
      // get user move
      cout << "Enter your position (0 to exit): ";
      cin >> position;

      move(position); // move to position chosen

      turn = 2;      // set it to computers turn
      win = checkwin(); // check to see if the player won

      if (win == 0)     // if player didn't win then continue
	win = 0;
      else if (win == 1) // if player did win then declare it and exit
	{
	  displayboard();
	  cout << "You win!\n";
	  break;
	}

      cats = checkcats(); // check for cats

      if (cats == 0)      // if no cats then continue
	cats = 0;
      else               // if cats then declare it and exit
	{ 
	  displayboard();
	  cout << "cats!\n"; 
	  break;
	}

      x = ai();          // get computer move
      turn = 1;          // switch to players turn
      win = checkwin();  // check if the computer won

      if (win == 0)      // if comp doesn't win continue
	win = 0;
      else if (win == 2) // if comp wins then declare it and exit
	{
	  displayboard();
	  cout << "You lost!\n";
	  break;
	}

      cats = checkcats(); // check for cats

      if (cats == 0)      // if no cats then continue
	cats = 0;
      else                // if cats then declare it and continue
	{
	  displayboard();
	  cout << "cats!\n";
	  break;
	}

      displayboard();     // display the board
    } while(position != 0); // loop until the player enters 0

  cout << "come back soon\n";
  return 0;
}

// display board function
void displayboard()
{
  int x,y; // declare necessary variables

  for (x = 0; x < 3; x++) // step through the rows
    {
      for (y = 0; y < 3; y++) // step through the columns
	{
	  cout << board[x][y]; // display the [row][column]
	}
      cout << endl; // when the row is done, begin a new line
    }
} 

// pick again function
void pickagain()  
{
  int newposition; // declare necessary variables

  cout << "You can't move there!\n";
  cout << "enter new location: ";
  cin >> newposition;     // get the new position

  move(newposition); // move to new position
}

// move piece function
void move(int pos)
{
  int isok = 1; // declare necessary variables

  // check where to move and if the move is legal
  switch (pos)
    {
      case 1:
	if (board[2][0] == 0)
	   board[2][0] = turn;
	  else
	    isok = 0;
	  break;
	case 2:
	  if (board[2][1] == 0)
	    board[2][1] = turn;
	  else
	    isok = 0;
	  break;
	case 3:
	  if (board[2][2] == 0)
	    board[2][2] = turn;
	  else
	    isok = 0;
	  break;
	case 4:
	  if (board[1][0] == 0)
	    board[1][0] = turn;
	  else
	    isok = 0;
	  break;
	case 5:
	  if (board[1][1] == 0)
	    board[1][1] = turn;
	  else
	    isok = 0;
	  break;
	case 6:
	  if (board[1][2] == 0)
	    board[1][2] = turn;
	  else
	    isok = 0;
	  break;
	case 7:
	  if (board[0][0] == 0)
	    board[0][0] = turn;
	  else
	    isok = 0;
	  break;
	case 8:
	  if (board[0][1] == 0)
	    board[0][1] = turn;
	  else
	    isok = 0;
	  break;
	case 9:
	  if (board[0][2] == 0)
	    board[0][2] = turn;
          else
            isok = 0;
          break;
        default:
          break;
        }
  
  if (isok == 0) // if illegal move then pick again
      pickagain();
}

// checkwin function
int checkwin()
{
  // check if player won
  // check if player won across top
  if ((board[0][0] == 1) && (board[0][1] == 1) && (board[0][2] == 1))
    return 1;

  // check if player won across middle
  else if ((board[1][0] == 1) && (board[1][1] == 1) && (board[1][2] == 1))
    return 1;

  // check if player won across bottom
  else if ((board[2][0] == 1) && (board[2][1] == 1) && (board[2][2] == 1))
    return 1;

  // check if player won down left
  else if ((board[0][0] == 1) && (board[1][0] == 1) && (board[2][0] == 1))
    return 1;

  // check if player won down middle
  else if ((board[0][1] == 1) && (board[1][1] == 1) && (board[2][1] == 1))
    return 1;

  // check if player won down right
  else if ((board[0][2] == 1) && (board[1][2] == 1) && (board[2][2] == 1))
    return 1;

  // check if player has diagnal win left to right
  else if ((board[0][0] == 1) && (board[1][1] == 1) && (board[2][2] == 1))
    return 1;

  // check if player has diagnal win right to left
  else if ((board[0][2] == 1) && (board[1][1] == 1) && (board[2][0] == 1))
    return 1;

  
  // check if comp won
  // check if comp won across top
  else if ((board[0][0] == 2) && (board[0][1] == 2) && (board[0][2] == 2))
    return 2;

  // check if comp won across middle
  else if ((board[1][0] == 2) && (board[1][1] == 2) && (board[1][2] == 2))
    return 2;

  // check if comp won across bottom
  else if ((board[2][0] == 2) && (board[2][1] == 2) && (board[2][2] == 2))
    return 2;

  // check if comp won down left
  else if ((board[0][0] == 2) && (board[1][0] == 2) && (board[2][0] == 2))
    return 2;

  // check if comp won down middle
  else if ((board[0][1] == 2) && (board[1][1] == 2) && (board[2][1] == 2))
    return 2;

  // check if comp won down right
  else if ((board[0][2] == 2) && (board[1][2] == 2) && (board[2][2] == 2))
    return 2;

  // check if comp won diagnal left to right
  else if ((board[0][0] == 2) && (board[1][1] == 2) && (board[2][2] == 2))
    return 2;

  // check if comp won diagnal right to left
  else if ((board[0][2] == 2) && (board[1][1] == 2) && (board[2][0] == 2))
    return 2;

  // check if noone won
  else
    return 0;
}

// checkcats function
int checkcats()
{
  int x,y; // declare necessary variables
  int cats = 1; 

  for (x = 0; x < 3; x++) // probe rows
    {
      for (y = 0; y < 3; y++) // probe columns
	{
	  if (board[x][y] == 0) // check if a square is empty
	    {
	      cats = 0;
	      break;
	    }
	}
    }

  return (cats);
}

// ai function
int ai() 
{ 
  int random; // declare necessary variables
  int moved = 0;

  // check if i can win across top
  if ((board[0][0] == 2) && (board[0][1] == 2) && (board[0][2] == 0))
    {
      move(9);
      return 0;
    }

  else if ((board[0][0] == 2) && (board[0][2] == 2) && (board[0][1] == 0))
    {
      move(8);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[0][1] == 2) && (board[0][2] == 2)) 
    {
      move(7);
      return 0;
    }

  // check if i can win across middle
  else if ((board[1][0] == 2) && (board[1][1] == 2) && (board[0][2] == 0))
    {
      move(6);
      return 0;
    }

  else if ((board[1][0] == 2) && (board[1][1] == 0) && (board[1][2] == 2))
    {
      move(5);
      return 0;
    }

  else if ((board[1][0] == 0) && (board[1][1] == 2) && (board[1][2] == 2))
    {
      move(4);
      return 0;
    }

  // check if i can win across bottom
  else if ((board[2][0] == 2) && (board[2][1] == 2) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[2][0] == 2) && (board[2][1] == 0) && (board[2][2] == 2))
    {
      move(2);
      return 0;
    }

  else if ((board[2][0] == 0) && (board[2][1] == 2) && (board[2][2] == 2))
    {
      move(1);
      return 0;
    }
  
  // check if i can win down left
  else if ((board[0][0] == 2) && (board[1][0] == 2) && (board[2][0] == 0))
    {
      move(1);
      return 0;
    }

  else if ((board[0][0] == 2) && (board[1][0] == 0) && (board[2][0] == 2))
    {
      move(4);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[1][0] == 2) && (board[2][0] == 2))
    {
      move(7);
      return 0;
    }
  
  // check if i can win down middle
  else if ((board[0][1] == 2) && (board[1][1] == 2) && (board[2][1] == 0))
    {
      move(2);
      return 0;
    }

  else if ((board[0][1] == 2) && (board[1][1] == 0) && (board[2][1] == 2))
    {
      move(5);
      return 0;
    }

  else if ((board[0][1] == 0) && (board[1][1] == 2) && (board[2][1] == 2))
    {
      move(8);
      return 0;
    }

  // check if i can win down right
  else if ((board[0][2] == 2) && (board[1][2] == 2) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[0][2] == 2) && (board[1][2] == 0) && (board[2][2] == 2))
    {
      move(6);
      return 0;
    }

  else if ((board[0][2] == 0) && (board[1][2] == 2) && (board[2][2] == 2))
    {
      move(9);
      return 0;
    }

  //check if i can win by diagnal left to right

  else if ((board[0][0] == 2) && (board[1][1] == 2) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[0][0] == 2) && (board[1][1] == 0) && (board[2][2] == 2))
    {
      move(5);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[1][1] == 2) && (board[2][2] == 2))
    {
      move(7);
      return 0;
    }

  // check if i can win by diagnal right to left
  else if ((board[0][2] == 2) && (board[1][1] == 2) && (board[2][0] == 0))
    {
      move(1);
      return 0;
    }

  else if ((board[0][2] == 2) && (board[1][1] == 0) && (board[2][0] == 2))
    {
      move(5);
      return 0;
    }

  else if ((board[0][2] == 0) && (board[1][1] == 2) && (board[2][0] == 2))
    {
      move(9);
      return 0;
    }

  // if i can't win... let's see if the player can win

  // check for player winning across top
  else if ((board[0][0] == 1) && (board[0][1] == 1) && (board[0][2] == 0))
    {
      move(9);
      return 0;
    }

  else if ((board[0][0] == 1) && (board[0][1] == 0) && (board[0][2] == 1))
    {
      move(8);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[0][1] == 1) && (board[0][2] == 1))
    {
      move(7);
      return 0;
    }

  // check if player can win across middle
  else if ((board[1][0] == 1) && (board[1][1] == 1) && (board[1][2] == 0))
    {
      move(6);
      return 0;
    }

  else if ((board[1][0] == 1) && (board[1][1] == 0) && (board[1][2] == 1))
    {
      move(5);
      return 0;
    }

  else if ((board[1][0] == 0) && (board[1][1] == 1) && (board[1][2] == 1))
    {
      move(4);
      return 0;
    }

  // see if player can win across bottom
  else if ((board[2][0] == 1) && (board[2][1] == 1) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[2][0] == 1) && (board[2][1] == 0) && (board[2][2] == 1))
    {
      move(2);
      return 0;
    }

  else if ((board[2][0] == 0) && (board[2][1] == 1) && (board[2][2] == 1))
    {
      move(1);
      return 0;
    }

  // see if player can win down left
  else if ((board[0][0] == 1) && (board[1][0] == 1) && (board[2][0] == 0))
    {
      move(1);
      return 0;
    }

  else if ((board[0][0] == 1) && (board[1][0] == 0) && (board[2][0] == 1)) 
    {
      move(4);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[1][0] == 1) && (board[2][0] == 1))
    {
      move(7);
      return 0;
    }

  // see if player can win down middle
  else if ((board[0][1] == 1) && (board[1][1] == 1) && (board[2][1] == 0))
    {
      move(2);
      return 0;
    }

  else if ((board[0][1] == 1) && (board[1][1] == 0) && (board[2][1] == 1))
    {
      move(5);
      return 0;
    }

  else if ((board[0][1] == 0) && (board[1][1] == 1) && (board[2][1] == 1))
    {
      move(8);
      return 0;
    }

  // see if player can win down right
  else if ((board[0][2] == 1) && (board[1][2] == 1) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[0][2] == 1) && (board[1][2] == 0) && (board[2][2] == 1))
    {
      move(6);
      return 0;
    }

  else if ((board[0][2] == 0) && (board[1][2] == 1) && (board[2][2] == 1))
    {
      move(9);
      return 0;
    }

  // see if player can win diagnal left to right
  else if ((board[0][0] == 1) && (board[1][1] == 1) && (board[2][2] == 0))
    {
      move(3);
      return 0;
    }

  else if ((board[0][0] == 1) && (board[1][1] == 0) && (board[2][2] == 1))
    {
      move(5);
      return 0;
    }

  else if ((board[0][0] == 0) && (board[1][1] == 1) && (board[2][2] == 1))
    {
      move(7);
      return 0;
    }

  // see if player can win diagnal right to left
  else if ((board[0][2] == 1) && (board[1][1] == 1) && (board[2][0] == 0))
    {
      move(1);
      return 0;
    }

  else if ((board[0][2] == 1) && (board[1][1] == 0) && (board[2][0] == 1))
    {
      move(5);
      return 0;
    }

  else if ((board[0][2] == 0) && (board[1][1] == 1) && (board[2][0] == 1))
    {
      move(9);
      return 0;
    }

  // if i can't win and you can't win... chose a random square
  else
    {
      do
	{
	  random = 1 + rand() % 9; // chose random square
	  
	  // check if that square is empty
	  switch(random)
	    {
	    case 1:
	      if (board[2][0] == 0)
		{
		  move(1);
		  moved = 1;
		}
	      break;
	    case 2:
	      if (board[2][1] == 0)
		{
		  move(2);
		  moved = 1;
		}
	       break;
	    case 3:
	      if (board[2][2] == 0)
		{
		  move(3);
		  moved = 1;
		}
	       break;
	    case 4:
	      if (board[1][0] == 0)
		{
		  move(4);
		  moved = 1;
		}
	      break;
	    case 5:
	      if (board[1][1] == 0)
		{
		  move(5);
		  moved = 1;
		}
	      break;
	    case 6:
	      if (board[1][2] == 0)
		{
		  move(6);
		  moved = 1;
		}
	      break;
	    case 7:
	      if (board[0][0] == 0)
		{
		  move(7);
		  moved = 1;
		}
	      break;
	    case 8:
	      if (board[0][1] == 0)
		{
		  move(8);
		  moved = 1;
		}
	      break;
	    case 9:
	      if (board[0][2] == 0)
		{
		  move(9);
		  moved = 1;
		}
	      break;
	    }

	} while (moved == 0);
    }

  return 0;
} 

// instructions function
void instructions()
{
  cout << "Here is a list of commands.\n";
  cout << "1 - bottom left\n";
  cout << "2 - bottom middle\n";
  cout << "3 - bottom right\n";
  cout << "4 - middle left\n";
  cout << "5 - middle middle\n";
  cout << "6 - middle right\n";
  cout << "7 - top right\n";
  cout << "8 - top middle\n";
  cout << "9 - top right\n";
  cout << "0 - exit\n";
  cout << "These keys should look like this on your keyboard\n";
  cout << "789\n";
  cout << "456\n";
  cout << "123\n";
  cout << "0\n\n\n";
}

    Source: geocities.com/hiddenbunkerlabs/code

               ( geocities.com/hiddenbunkerlabs)