/////////////////////////////////////////////////////////////////////////
// Game Playing using Minimax                                          //
// By: Nick Cash                                                       //
//                                                                     //
// Fall 2007                                                           //
// 810:161 - Aritifical Intelligence                                   //
//                                                                     //
// game.h - Header file for class declarations and function prototypes //
/////////////////////////////////////////////////////////////////////////

// Start with our inclusion guard
#ifndef INCLUDE_GAME
#define INCLUDE_GAME

// Standard includes
#include <iostream>
#include <list>

// Set namespace
using namespace std;

// Defined cosntants
#define MAX_CELL        8
//#define PRINT_ALL

// Give our states some meaning
enum CellState { O, Neutral, X };
enum NodeType { Min, Max, Unknown };
enum NodeEndGameValue { Draw, Win, None };

// Class headers
class cBoard
{
   public:
          // constructors/desuctors
          cBoard();
          cBoard(const char *);
         ~cBoard();
         
          // data manipulators
          void SetCell( int, CellState );
          CellState GetCell( int );
          
          string GetBoard();
          
          void PrintBoard();

   protected:
          CellState board[9];
};

// cNode inherits cBoard
class cNode : public cBoard
{
   public:
           cNode(cNode*, short, short, const char * );
          ~cNode();

           // data manipulators
           void SetType( NodeType x ) { type = x; }
           NodeType GetType( void ) { return type; }
          
           void SetEGValue( NodeEndGameValue x ) { end_game_value = x; }
           NodeEndGameValue GetEGValue( void ) { return end_game_value; }
           
           void SetValue( short x ) { value = x; }
           short GetValue( void ) { return value; }
           
           short GetMove( void ) { return move; }
           short GetDepth( void ) { return depth; }
           cNode* GetParent( void ) { return parent; }
          
           void Print();
           NodeEndGameValue CheckEndGame();

           // public data
           list<cNode*>        children;           // keep track of the kids
   private:
           NodeType            type;               // Min or Max
           NodeEndGameValue    end_game_value;     // value assigned to the node
           short               value;              // number value determined by heuristic
           short               move;               // which space was taken, 0 - 8
           short               depth;              // depth in the tree
           cNode*              parent;             // keep track of our parent
};

// Setup new types
typedef list<cNode*> ChildList;

// Function Protoypes

// main.cpp
void   Error( const char * ); 

// minimax.cpp
cNode* MiniMax( cNode* node );
cNode* BuildGameTree( string );
short  EvaluateNode( cNode* );
void GenerateChildren( cNode* node );

#endif // INCLUDE_GAME