// File: inclass16.cpp
// This program allows two players to play tic-tac-toe.  It makes sure that
// a move is valid and determines if there is a winner.

// Class: CS 210                     Instructors: Drs. Hwang & Roberts
// Assignment: Programming exercise for 3/12/07 & 3/13/07
// Programmer(s): <fill in your name(s)>

#include <iostream>
using namespace std;

// Constants
const int BOARD_SIZE = 3;                         // tic-tac-toe board is 3x3
const int MAX_POSITIONS = 9;                      // maximum valid position
const int MAX_TURNS = MAX_POSITIONS;      

// Function prototypes
void Instructions();
void InitializeBoard (char board[BOARD_SIZE][BOARD_SIZE]);
void PrintBoard (const char board[BOARD_SIZE][BOARD_SIZE]);
bool PlaceMove (char board[BOARD_SIZE][BOARD_SIZE], char player, int position);

int main ()
{
   char theBoard[BOARD_SIZE][BOARD_SIZE],   // tic-tac-toe board
        player,                             // player's turn, X or O
        winner;                             // winning player
   int position,                            // position chosen by player
       turns;                               // number of turns taken so far

   // Greet the users and give instructions
   Instructions();

   // Initialize game
   InitializeBoard (theBoard);
   player = 'X';                // X goes first
   winner = '-';                // no winner, yet
   turns = 0;
   PrintBoard (theBoard);

   // Play until someone wins (winner is 'X' or 'O'), or there is a draw
   while ((winner == '-') && (turns < MAX_TURNS))
   {
      // Ask for a position
      cout << "Player " << player << ", please choose a position: ";
      cin >> position;

      // Place the move
      if (PlaceMove (theBoard, player, position))
      {
         // Move is valid.  Check for a win and alternate players

         // For now, just set winner to '-' so we can test the rest of the
         // program.  To be replaced by call to CheckForWinner function
         winner = '-';

         turns++;

         // Make it the next player's turn
         if (player == 'X')
            player = 'O';
         else
            player = 'X';
      }  // end if valid
      else  // Move is invalid
         cout << "That was an invalid move.  Please try again\n";
      PrintBoard (theBoard);
   }  // end while

   // Print out the winner
   if (winner != '-')
      cout << "Player " << winner << " has won.\n\n";
   else
      cout << "The game has ended in a draw.\n\n";

   cout << "Thank you for playing!\n";
   return 0;
}  // end main

// Function: Instructions
// Prints the instructions for using this program
void Instructions ()
{
   cout << "\nWelcome to the tic-tac-toe game server.  Please decide who\n"
        << "will be Player X and who will be Player O.  Player X always goes\n"
        << "first.  The positions on the board are numbered.  Please enter a\n"
        << "position number between 1 and 9 when asked.  This program will\n"
        << "check for a winner after every turn.  Have fun!\n\n";
}  // end Instructions


// Function: InitializeBoard
// Initializes the position numbers of the board
void InitializeBoard (char board[BOARD_SIZE][BOARD_SIZE])
                           // PASSED BACK: game board
{
   char position;    // character counter

   position = '1';
   for (int row = 0; row < BOARD_SIZE; row++)
      for (int column = 0; column < BOARD_SIZE; column++)
      {
         board[row][column] = position;
         position++;
      }  // end for column
}  // end InitializeBoard


// Function: PrintBoard
// Prints out the board
void PrintBoard (const char board[BOARD_SIZE][BOARD_SIZE]) // REC'D: game board
{
   cout << endl;
   for (int row = 0; row < BOARD_SIZE; row++)
   {
      for (int column = 0; column < BOARD_SIZE; column++)
         cout << board[row][column];
      cout << endl;
   }  // end for row
   cout << endl;
}  // end PrintBoard


// Function: PlaceMove
// Checks that position has not been taken and marks it with player's
// character.  
// Returns: true if move was valid, false otherwise.
bool PlaceMove (char board[BOARD_SIZE][BOARD_SIZE],   
                                 // REC'D/PASS BACK: game board
                char player,     // REC'D: 'X' or 'O'
                int position)    // REC'D: move position
{
   int row,      // indexes
       column;
   bool valid;   // status of placement

   valid = true;   

   // Check for valid position number
   if ((position < 1) || (position > MAX_POSITIONS))
      valid = false;
   else
   {
      // Compute row and column indexes
      row = (position - 1) / 3;
      column = (position - 1) % 3;
   
      // Check if position is already taken      
      if ((board[row][column] == 'X') || (board[row][column] == 'O'))
         valid = false;
      else  // Set position to player
         board[row][column] = player;
   }  // end else valid position
   return valid;
}  // end PlaceMove
