/*------------------------------------------------------------------------------
Projekt: ICP - game Othello
Authors: Michal Schorm (xschor02)
Date: FIT VUTBR 2016                                                

File content: class Board
-------------------------------------------------------------------------------*/

#include <random>
#include "./Board.cpp"
using namespace std;


//!  Class Player - represents player with his color and methods to play
/*!
An AI can be add by creating new class and a else-if option to make it accessible
*/
#ifndef PLAYER_CLASS_FULL
#define PLAYER_CLASS_FULL
class Player
{
 private:
   //! name of the Player. Special names makes AI players
   string name;
   //! color of the disks that Player play.
   DiskColor color;



 public:
   //! Constuctor only assign name and color for the Player
   Player(string name, DiskColor color)
     {
      this->name = name;
      this->color = color;
     }
   
   //! returns color of the Player
   DiskColor getColor()
     {
      return this->color;
     }

   //! returns name of the Player
   string getName()
     {
      return this->name;
     }

   //! Method to write out available AIs. Can be called without object.
   static void writePlayers()
     {
      cout << "AI_1 | AI_2";
      //cout << " | AI_3"         // place to update for new AI
      //cout << " | YOUR_AI";     // place to update for new AI
     }
     
   //! Method to choose player input
   void play(Board * board)
     {
      int row, col;

      if( this->name.compare("AI_1") == 0) this->AI_1(board);
      else if( this->name.compare("AI_2") == 0 ) this->AI_2(board);
      // else if( this->name.compare("AI_3") == 0 ) this->AI_3(board);    // place to update for new AI
      // else if( this->name.compare("YOUR_AI") ) this->YOUR_AI(board);   // place to update for new AI
      else this->HUMAN(board); // human player
     }
   
   //! Human player. This method get valid coordinates and put disk on them. Input via cnsole.
   void HUMAN(Board * board)
     {
      int row, col;
      while(1)
        {
         cout << "Zadejte pozici na kterou chcete vložit váš kámen [řádek | sloupec][1-" << board->getBoardSize() <<  "]: ";
         cin >> row >> col;
         if(row>0 && row < (board->getBoardSize()) && col>0 && col < (board->getBoardSize()) && (board->getField(row, col)->canPutDisk(this->color)) ) break;
         cout << "Neplatné umístění\n";
        }
      board->getField(row, col)->putDisk(new Disk(this->color));        
     }
   
   //! No console input needed. Place disk on the first possible Field form the begiining of coordinates.    
   void AI_1(Board * board)
     {
      int row, col;
      for(row = 1; row<=board->getBoardSize(); row++)
         {
          for(col = 1; col<=board->getBoardSize(); col++)
            {
             if( (board->getField(row, col)->canPutDisk(this->color)) )
               {
                board->getField(row, col)->putDisk(new Disk(this->color));
                return;
               }
            }
         }                
     }  
     
   //! No console input needed.    
   void AI_2(Board * board)
     {
      int row, col;
      
      random_device rd;  // obtain a random number from hardware
      mt19937 eng(rd()); // seed the generator
      uniform_int_distribution<> distr(1, board->getBoardSize()); // define the range
 
      do{
         row = distr(eng);
         col = distr(eng);
        } while( !(board->getField(row, col)->canPutDisk(this->color)) );
      board->getField(row, col)->putDisk(new Disk(this->color));        
     }  
     
     
   //void YOUR_AI(Board * board){}  // place to update for new AI
     
     
       

};

#endif