//V 0.0.5
#include <ctime>
#include <iostream>
#include <vector>
using namespace std;

//function prototypes
void clearScreen();
bool searchHumanHand(vector<int> temp, int value, int num);
char valueToChar(int value);
int charToValue(char character);

//define Cards class and have a inheritance class of Players
class Cards
{
      public:
             vector<int> deck;  //the entire deck
             vector<int> hand;  //consists of 13 cards
             
             void makeDeck();
             void shuffleDeck();
             void sortHand();
             void showHand(int whichplayer);
             
};


class Player : public Cards
{
      public:
             bool pass;
             bool turn;
             Player();
      
             //Player(); //constructor
};


Player::Player()
{
    /*
    int i;
    
    for(i=deck.size(); i>deck.size()-13; i--)
    {
       hand.push_back(deck[i]);
       deck.pop_back();
    }
    */
    pass=false;
}



void Cards::makeDeck()
{
     int t=1;
     for(int i=0; i<52; i++)
     {
        deck.push_back(t);
        if((i+1)%4==0)
        t++;
     }
     //cout << "Deck made.\n";
}

void Cards::shuffleDeck()
{
     srand(time(NULL));
    
     random_shuffle(deck.begin(), deck.end());
     
     //cout << "Deck shuffled.\n";
}

void Cards::showHand(int whichplayer)
{
     if(whichplayer==1)
     {
         cout << "Your hand:  ";
     }
     if(whichplayer==2)
     {
         cout << "Bot 1's hand:  ";
     }
     for(int i=0; i<13; i++)
     {
         cout << valueToChar(hand[i]) << " ";
     }
}


int main()
{
    Player human; Player bot1; Player bot2; Player bot3; Cards setup;
    
    int i;
    int cardValueInPlay;
    int numOfCardsInPlay;
    
    char cardCharPlayed;
    int numOfCardsPlayed;
    
    bool gameover=false;
    bool newround=true;
    
    
    srand(time(NULL));
    
    //set turns
    int mod=0; //(rand() % 4);
    switch(mod)
    {
         case 0:  human.turn=true;
                  bot1.turn=false;
                  bot2.turn=false;
                  bot3.turn=false;
                  break;
         
         case 1:  human.turn=false;
                  bot1.turn=true;
                  bot2.turn=false;
                  bot3.turn=false;
                  break;
                  
         case 2:  human.turn=false;
                  bot1.turn=false;
                  bot2.turn=true;
                  bot3.turn=false;
                  break;
                  
         case 3:  human.turn=false;
                  bot1.turn=false;
                  bot2.turn=false;
                  bot3.turn=true;
                  break;
    }
    
    
    clearScreen();
    
    //make and shuffle deck
    setup.makeDeck();
    setup.shuffleDeck();
    
    //deal each players hand
    for(i=0; i<13; i++)
    {
       human.hand.push_back(setup.deck[i]);
    }
    for(i=0; i<13; i++)
    {
       bot1.hand.push_back(setup.deck[(i+13)]);
    }
    for(i=0; i<13; i++)
    {
       bot2.hand.push_back(setup.deck[(i+26)]);
    }
    for(i=0; i<13; i++)
    {
       bot3.hand.push_back(setup.deck[(i+39)]);
    }
    
    
    //sort player's hand
    sort(human.hand.begin(), human.hand.end());
    sort(bot1.hand.begin(), bot1.hand.end());
    
    //for(i=0; i<13; i++)
    //{
       //cout << human.hand[i] << endl;
    //}
    
    human.showHand(1);
    
    //cout << endl << human.turn << " " << bot1.turn << " " << bot2.turn << " " << bot3.turn;
    
    human.pass=false;
    bool haveCards;
    
    char bot1lastplayed;
    char bot2lastplayed;
    char bot3lastplayed;
    
    while(!gameover)
    {
         while(!newround)
         {
             if(human.turn && !human.pass)
             {
                  clearScreen();
                  
                  if(!bot1.pass)
                  {
                      cout << "Bot 1 played: " << bot1lastplayed << endl << endl;
                  }
                  else
                  {
                      cout << "Bot 1 has passed." << endl << endl;
                  }
                  if(!bot2.pass)
                  {
                      cout << "Bot 2 played: " << bot2lastplayed << endl << endl;
                  }
                  else
                  {
                      cout << "Bot 2 has passed." << endl << endl;
                  }
                  if(!bot3.pass)
                  {
                      cout << "Bot 3 played: " << bot3lastplayed << endl << endl;
                  }
                  else
                  {
                      cout << "Bot 3 has passed." << endl << endl;
                  }
                  
                  
                  
                  human.showHand(1);
                  cout << "\n\nCard value in play is:  " << valueToChar(cardValueInPlay) << endl;
                  cout << "Each play is:  " << numOfCardsInPlay << endl;     
                      
                  do
                  {
                      cout << endl << "Which card value will you play?  ";
                      cin >> cardCharPlayed;
                      
                      if(cardCharPlayed == 'P')
                      {
                          human.pass=true;
                          cout << "You passed." << endl;
                          break;
                      }
                      
                      cout << endl << "How many cards of this value will you play?  ";
                      do
                      {
                          cin >> numOfCardsPlayed;
                      }
                      while(numOfCardsPlayed < 1 && numOfCardsPlayed > 4);
                      
                      if(numOfCardsPlayed!=numOfCardsInPlay)
                      {
                          cout << endl << "You must play the correct number of cards.\n";
                      }
                      //cout << "Test 1" << endl;
                      if(charToValue(cardCharPlayed)<cardValueInPlay)
                      {
                          cout << endl << "You must play a equal or higher card.\n";
                      }
                      if(searchHumanHand(human.hand,charToValue(cardCharPlayed),numOfCardsInPlay))
                      {    
                          haveCards=false; 
                          cout << endl << "You don't have those cards in your hand\n";
                      }
                      else
                      {
                          haveCards=true;
                      }
                  }
                  while((charToValue(cardCharPlayed)<cardValueInPlay) || (numOfCardsPlayed!=numOfCardsInPlay) || !haveCards);
                  
                  if(!human.pass)
                  {
                      //cout << "Test 3" << endl;
                      cardValueInPlay=charToValue(cardCharPlayed);
                      numOfCardsInPlay=numOfCardsPlayed;
                  
                      //remove cards from hand
                      int numberOfCardsRemoved=0;
                      for(i=0; i<13; i++)
                      {
                          if(human.hand[i]==cardValueInPlay)
                          {
                              if(numberOfCardsRemoved!=numOfCardsInPlay)
                              {
                                  human.hand[i]=0;
                                  numberOfCardsRemoved++;
                              }
                          }
                      }
                  
                      
                  
                      
                  }
                  
                  human.turn=false;
                  bot1.turn=true;
                  
                  //check for newround
                  if(human.pass && bot1.pass && bot2.pass && bot3.pass)
                  {
                      newround=true;
                      human.turn=true;
                      bot1.turn=false;
                  }
                  
                  //check for gameover
                  int zerosInDeck=0;
                  for(i=0; i<13; i++)
                  {
                      if(human.hand[i]==0)
                      {
                          zerosInDeck++;
                      }
                  }
                  if(zerosInDeck==13)
                  {
                      gameover=true;
                      bot1.turn=false;
                      bot2.turn=false;
                      bot3.turn=false;
                      newround=true;
                      cout << "Human wins!" << endl;
                  }
             }
             else
             {
                 bot1.turn=true;
             }
             
             //Bot 1
             if(bot1.turn && !bot1.pass)
             {
                 bool playedthisturn=false;
                 
                 for(i=0; i<13; i++)
                 {
                     if((bot1.hand[i] >= cardValueInPlay) && numOfCardsInPlay==1)
                     {
                         playedthisturn=true;
                         cardValueInPlay=bot1.hand[i];
                         bot1.hand[i]=0;
                         bot1lastplayed=valueToChar(cardValueInPlay);
                         break;
                     }
                     
                     if((bot1.hand[i] >= cardValueInPlay) && numOfCardsInPlay>1)
                     {
                         int targetCard=bot1.hand[i];
                         int tempcardcount=0;
                         for(int j=0; j<13; j++)
                         {
                             if(bot1.hand[j]==targetCard)
                             {
                                 tempcardcount++;
                             }
                         }
                         if(tempcardcount>=numOfCardsInPlay)
                         {
                             playedthisturn=true;
                             cardValueInPlay=targetCard;
                             int numberOfCardsRemoved=0;
                             for(i=0; i<13; i++)
                             {
                                 if(bot1.hand[i]==cardValueInPlay)
                                 {
                                     if(numberOfCardsRemoved!=numOfCardsInPlay)
                                     {
                                         bot1.hand[i]=0;
                                         numberOfCardsRemoved++;
                                     }
                                 }
                             }
                             bot1lastplayed=valueToChar(cardValueInPlay);
                             break;
                         }
                     }
                 }
                 
                 if(!playedthisturn)
                 {
                     bot1.pass=true;
                 
                 }
                       
                 bot1.turn=false;
                 bot2.turn=true;
                       
                 //check for newround
                 if(human.pass && bot1.pass)
                 {
                     newround=true;
                     human.turn=true;
                 }
                       
                 //check for gameover
                 int zerosInDeck=0;
                 for(i=0; i<13; i++)
                 {
                     if(bot1.hand[i]==0)
                     {
                         zerosInDeck++;
                     }
                 }
                 if(zerosInDeck==13)
                 {
                     gameover=true;
                     human.turn=false;
                     bot2.turn=false;
                     bot3.turn=false;
                     newround=true;
                     cout << "Bot 1 wins!" << endl;
                 }
             }
             else
             {
                 bot2.turn=true;
             }
             
             //Bot 2
             if(bot2.turn && !bot2.pass)
             {
                 bool playedthisturn=false;
             
                 for(i=0; i<13; i++)
                 {
                     if((bot2.hand[i] >= cardValueInPlay) && numOfCardsInPlay==1)
                     {
                         playedthisturn=true;
                         cardValueInPlay=bot2.hand[i];
                         bot2.hand[i]=0;
                         bot2lastplayed=valueToChar(cardValueInPlay);
                         break;
                     }
                     
                     if((bot2.hand[i] >= cardValueInPlay) && numOfCardsInPlay>1)
                     {
                         int targetCard=bot2.hand[i];
                         int tempcardcount=0;
                         for(int j=0; j<13; j++)
                         {
                             if(bot2.hand[j]==targetCard)
                             {
                                 tempcardcount++;
                             }
                         }
                         if(tempcardcount>=numOfCardsInPlay)
                         {
                             playedthisturn=true;
                             cardValueInPlay=targetCard;
                             int numberOfCardsRemoved=0;
                             for(i=0; i<13; i++)
                             {
                                 if(bot2.hand[i]==cardValueInPlay)
                                 {
                                     if(numberOfCardsRemoved!=numOfCardsInPlay)
                                     {
                                         bot2.hand[i]=0;
                                         numberOfCardsRemoved++;
                                     }
                                 }
                             }
                             bot2lastplayed=valueToChar(cardValueInPlay);
                             break;
                         }
                     }
                 }
                 
                 
                 if(!playedthisturn)
                 {
                     bot2.pass=true;
                 }
                       
                 bot2.turn=false;
                 bot3.turn=true;
                       
                 //check for newround
                 if(human.pass && bot1.pass && bot2.pass && bot3.pass)
                 {
                     newround=true;
                     human.turn=true;
                 }
                       
                 //check for gameover
                 int zerosInDeck=0;
                 for(i=0; i<13; i++)
                 {
                     if(bot2.hand[i]==0)
                     {
                         zerosInDeck++;
                     }
                 }
                 if(zerosInDeck==13)
                 {
                     gameover=true;
                     human.turn=false;
                     bot1.turn=false;
                     bot3.turn=false;
                     newround=true;
                     cout << "Bot 2 wins!" << endl;
                 }
             }
             else
             {
                 bot3.turn=true;
             }
             
             
             //Bot 3
             if(bot3.turn && !bot3.pass)
             {
                 bool playedthisturn=false;
             
                 for(i=0; i<13; i++)
                 {
                     if((bot3.hand[i] >= cardValueInPlay) && numOfCardsInPlay==1)
                     {
                         playedthisturn=true;
                         cardValueInPlay=bot3.hand[i];
                         bot3.hand[i]=0;
                         bot3lastplayed=valueToChar(cardValueInPlay);
                         break;
                     }
                     
                     if((bot3.hand[i] >= cardValueInPlay) && numOfCardsInPlay>1)
                     {
                         int targetCard=bot3.hand[i];
                         int tempcardcount=0;
                         for(int j=0; j<13; j++)
                         {
                             if(bot3.hand[j]==targetCard)
                             {
                                 tempcardcount++;
                             }
                         }
                         if(tempcardcount>=numOfCardsInPlay)
                         {
                             playedthisturn=true;
                             cardValueInPlay=targetCard;
                             int numberOfCardsRemoved=0;
                             for(i=0; i<13; i++)
                             {
                                 if(bot3.hand[i]==cardValueInPlay)
                                 {
                                     if(numberOfCardsRemoved!=numOfCardsInPlay)
                                     {
                                         bot3.hand[i]=0;
                                         numberOfCardsRemoved++;
                                     }
                                 }
                             }
                             bot3lastplayed=valueToChar(cardValueInPlay);
                             break;
                         }
                     }
                 }
                 
                 
                 if(!playedthisturn)
                 {
                     bot3.pass=true;
                 }
                       
                 bot3.turn=false;
                 human.turn=true;
                       
                 //check for newround
                 if(human.pass && bot1.pass && bot2.pass && bot3.pass)
                 {
                     newround=true;
                     human.turn=true;
                 }
                       
                 //check for gameover
                 int zerosInDeck=0;
                 for(i=0; i<13; i++)
                 {
                     if(bot3.hand[i]==0)
                     {
                         zerosInDeck++;
                     }
                 }
                 if(zerosInDeck==13)
                 {
                     gameover=true;
                     human.turn=false;
                     bot1.turn=false;
                     bot2.turn=false;
                     newround=true;
                     cout << "Bot 3 wins!" << endl;
                 }
             }
             else
             {
                 human.turn=true;
             }
         }
         
         if(newround && human.turn==true && !gameover)
         {
            clearScreen();
            cout << "New round!\n\n";
            bool haveCards=false;
            human.showHand(1);
            
            //cout << "\n\nCard value in play is:  " << valueToChar(cardValueInPlay) << endl;
            //cout << "Each play is:  " << numOfCardsInPlay << endl;
            
            do
            {
                cout << endl << "Which card value will you play?  ";
                cin >> cardCharPlayed;
                      
                do
                {
                    cout << "How many cards of this value will you play?  ";
                    cin >> numOfCardsPlayed;
                }
                while(numOfCardsPlayed < 1 || numOfCardsPlayed > 4);
                
                if(searchHumanHand(human.hand,charToValue(cardCharPlayed),numOfCardsPlayed))
                {    
                     haveCards=false; 
                     cout << endl << "You don't have those cards in your hand\n";
                }
                else
                {
                    haveCards=true;
                }
            }
            while(!haveCards);
            
            newround=false;
            
            cardValueInPlay=charToValue(cardCharPlayed);
            numOfCardsInPlay=numOfCardsPlayed;
                  
            int numberOfCardsRemoved=0;
                  
            for(i=0; i<13; i++)
            {
                if(human.hand[i]==cardValueInPlay)
                {
                    if(numberOfCardsRemoved!=numOfCardsInPlay)
                    {
                        human.hand[i]=0;
                        numberOfCardsRemoved++;
                    }
                }
            }
            
            human.turn=false;
            bot1.turn=true;
            
            human.pass=false;
            bot1.pass=false;
            bot2.pass=false;
            bot3.pass=false;
         }
    } //gameover    
    return 0;
}



/*
FUNCTIONS
*/

//clear screen
void clearScreen()
{
     system("cls");
}

//converts deck integer value into char value for user
char valueToChar(int value)
{
     char card;

     switch(value)
     {
         case 0: card=' '; break;
         case 1: card='3'; break;
         case 2: card='4'; break;
         case 3: card='5'; break;
         case 4: card='6'; break;
         case 5: card='7'; break;
         case 6: card='8'; break;
         case 7: card='9'; break;
         case 8: card='T'; break;
         case 9: card='J'; break;
         case 10: card='Q'; break;
         case 11: card='K'; break;
         case 12: card='A'; break;
         case 13: card='2'; break;
     }
     
     return card;        
}

int charToValue(char character)
{
     int card;

     do
     {
         switch(character)
         {
             case '3': card=1; break;
             case '4': card=2; break;
             case '5': card=3; break;
             case '6': card=4; break;
             case '7': card=5; break;
             case '8': card=6; break;
             case '9': card=7; break;
             case 'T': card=8; break;
             case 'J': card=9; break;
             case 'Q': card=10; break;
             case 'K': card=11; break;
             case 'A': card=12; break;
             case '2': card=13; break;
             default: cout << "Please enter a correct value.";
         }
     }
     while(false);
     
     return card;        
}

bool searchHumanHand(vector<int> temp, int value, int num)
{             
     int tempcardcount=0;
     for(int j=0; j<13; j++)
     {
         if(temp[j]==value)
         {
             tempcardcount++;
         }
     }
     if(tempcardcount<num)
     {
         return true;
     }
     return false;
}