/************************************************
This program is a simple tic-tac-toe game.
*************************************************/

#include <iostream>

/************************************************
 ** PROTOTYPES
 ************************************************/
char **createboard();
void print(char **Board);
bool draw(char **Board);
char winningmove(char **Board, int i, int j);

/************************************************
 ** MAIN FUNCTION
 ************************************************/
int main()
{
  char **Board = createboard(), winner = 0, row, col, turn = 'X';

  while(!winner && !draw(Board))
  {
    print(Board);

    // Read Move
    cout << "Player " << turn << ", make your move: ";
    cin >> row >> col;

    // Make move if square free
    if (Board[row - 'A'][col - '1'] == ' ')
    {      
      Board[row - 'A'][col - '1'] = turn;
      if (turn == 'X')
	turn = 'O';
      else
	turn = 'X';
      winner = winningmove(Board,row - 'A',col - '1');
    }
    else
      cout << "Square occupied, try again!" << endl;
  }

  // Game over print board & declare finish
  print(Board);
  if (winner == 'X' || winner == 'Y')
    cout << "Congratulations " << winner << '!' << endl;
  else
    cout << "Game ends in a draw!" << endl;
  
  return 0;
}

/************************************************
 ** FUNCTION DEFINITIONS
 ************************************************/
// Creates the board with all squares init to ' '
char **createboard()
{
  char **B = new char*[3];
  for(int i = 0; i < 3; i++)
    B[i] = new char[3];
  for(int j =0;j < 3; j++)
    for(int k = 0; k < 3; k++)
      B[j][k] = ' ';
  return B;
}

// Prints the board
void print(char **Board)
{
  cout << " |1|2|3|" << endl;
  for(int i = 0; i < 3; i++)
  {
    cout << char(i + 'A') << '|';
    for(int j = 0; j < 3; j++)
      cout << Board[i][j] << '|';
    cout << endl;
  }
}
 
// Returns true if the game is a draw
bool draw(char **Board)
{
  bool full = true;
  for(int i = 0; full && i < 3; i++)
    for(int j = 0; full && j < 3; j++)
      full = Board[i][j] != ' ';
  return full;
}

// Returns 'X' if (i,j) was a winning move for X
// Returns 'Y' if (i,j) was a winning move for Y
// Retruns ASCII value 0 otherwise
char winningmove(char **Board, int i, int j)
{
  if (Board[i][j] == Board[i][(j+1)%3] && Board[i][j] == Board[i][(j+2)%3])
    return Board[i][j];
  if (Board[i][j] == Board[(i+1)%3][j] && Board[i][j] == Board[(i+2)%3][j])
    return Board[i][j];
  if (i == j &&  Board[i][j] == Board[(i+1)%3][(j+1)%3] && Board[i][j] == Board[(i+2)%3][(j+2)%3])
    return Board[i][j];
  if (i + j == 2 && Board[i][j] == Board[(i+2)%3][(j+1)%3] && Board[i][j] == Board[(i+1)%3][(j+2)%3])
    return Board[i][j];
  return 0;
}