//////////////////////////////////////////////////////////////////////
// Game Playing using Minimax                                       //
// By: Nick Cash                                                    //
//                                                                  //
// Fall 2007                                                        //
// 810:161 - Aritifical Intelligence                                //
//                                                                  //
// main.cpp - Contains main(), the starting point for the program   //
//////////////////////////////////////////////////////////////////////

// Local include
#include "game.h"

using namespace std;

// Everything starts here!
int main(int argc, char *argv[])
{
  cNode* root = NULL; // Holds our root value
  cNode* ret = NULL;  // Our return value from the algorithm
  cNode* iter = NULL; // Used for traversing -up- the tree
  string s;           // For our command line arg
  
  // if we have more then one arg, grab the second one
  if ( argc > 1 )
    s = argv[1];
  else
   Error( "Main(int, char*): No arguments supplied." );
  
  // Build the game tree and save root
  root = BuildGameTree( s );
  
  cout << "\n---------------\nStarting Board:\n---------------\n\n";
  root->PrintBoard();
  
  // check to see if root is an eng-game board
  if ( root->GetEGValue() != None )
  {
    root->Print();
    return EXIT_SUCCESS;
  }
  else // it wasn't, so run the algorithm
   ret = iter = MiniMax( root );

  // check to make sure we have a return value
  if ( !ret )
    Error("MiniMax failure, return value NULL.");

  // go up the tree to find the move just before the root
  // which is the move we will take
  while ( iter->GetParent() != root )
   iter = iter->GetParent();
  
  // Print out the move we will take
  cout << "\n-----------------\nBoard after move:\n-----------------\n";
  iter->Print();
  
  // Print out the eventual income we wish to achieve
  if ( iter != ret )
  {
    cout << "\n\nPossible outcome:\n";
    ret->Print();

    // And how far away it is
    cout << (ret->GetDepth()-iter->GetDepth()) << " moves away.\n";
  }

  // program ran successfully
  return EXIT_SUCCESS;
}

// Error reports come here
void Error( const char *str )
{
  // report error
  cout << endl << "*** ERROR ***   " << str << endl;
  
  // and terminate gracefully
  exit(EXIT_FAILURE);
}