//choose best five cards for all players
int SevenCardStud::best_five_forall(){
	for (size_t i = 0; i < num_players_in_game(); ++i){
		if ((*players[i]).player_hand.size() != VALID_SEVEN_CARDSTUD_HAND_SIZE){
			continue;
		}
		(*players[i]).player_original_hand = (*players[i]).getPlayerHand();
		Hand bestfive = best_five((*players[i]));
		(*players[i]).player_hand.sethand(bestfive.getCards());
	}

	return 0;
}
int PokerHandEvaluator::evaluate(Hand hand){
    //logic and some code taken from here: http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/10/pokerValue.html
    std::vector<Card*> cards = hand.getCards();
    std::sort(cards.begin(), cards.end(), Compare());

    if (isFlush(cards) && isStraight(cards)) return valueStraightFlush(cards);
    else if (is4s(cards)) return valueFourOfAKind(cards);
    else if (isFullHouse(cards)) return valueFullHouse(cards);
    else if (isFlush(cards)) return valueFlush(cards);
    else if (isStraight(cards)) return valueStraight(cards);
    else if (is3s(cards)) return valueSet(cards);
    else if (is22s(cards)) return valueTwoPairs(cards);
    else if (is2s(cards)) return valueOnePair(cards);
    else return valueHighCard(cards);   // Lowest Poker hand;


}
//choose best five cards
Hand TexasHoldEm::best_five(Player & player){
	Hand hand = player.getPlayerHand();

	vector<Hand>allhands;
	for (size_t i = 0; i < VALID_SEVEN_CARDSTUD_HAND_SIZE; i++){


		for (size_t j = i + 1; j < VALID_SEVEN_CARDSTUD_HAND_SIZE; j++){

			for (size_t k = j + 1; k < VALID_SEVEN_CARDSTUD_HAND_SIZE; k++){

				for (size_t m = k + 1; m < VALID_SEVEN_CARDSTUD_HAND_SIZE; m++){

					for (size_t n = m + 1; n < VALID_SEVEN_CARDSTUD_HAND_SIZE; n++){
						Hand temphand;
						temphand.add_card(hand[i]);
						temphand.add_card(hand[j]);
						temphand.add_card(hand[k]);
						temphand.add_card(hand[m]);
						temphand.add_card(hand[n]);
						vector<Card> temp_cards = temphand.getCards();
						sort(temp_cards.begin(), temp_cards.end());
						temphand.sethand(temp_cards);
						temphand.setHandRank();
						allhands.push_back(temphand);

					}
				}
			}

		}

	}


	sort(allhands.begin(), allhands.end(), poker_rank);

	return allhands[0];
}
//choose five five cards
Hand SevenCardStud::best_five(Player & player){
	Hand hand = player.getPlayerHand();

	vector<Hand>allhands;

	//generate all posible combinations
	for (size_t i = 0; i < VALID_SEVEN_CARDSTUD_HAND_SIZE; i++){
		for (size_t j = i + 1; j < VALID_SEVEN_CARDSTUD_HAND_SIZE; j++){
			for (size_t k = j + 1; k < VALID_SEVEN_CARDSTUD_HAND_SIZE; k++){
				for (size_t m = k + 1; m < VALID_SEVEN_CARDSTUD_HAND_SIZE; m++){
					for (size_t n = m + 1; n < VALID_SEVEN_CARDSTUD_HAND_SIZE; n++){
						Hand temphand;
						temphand.add_card(hand[i]);
						temphand.add_card(hand[j]);
						temphand.add_card(hand[k]);
						temphand.add_card(hand[m]);
						temphand.add_card(hand[n]);
						vector<Card> temp_cards = temphand.getCards();
						sort(temp_cards.begin(), temp_cards.end());
						temphand.sethand(temp_cards);
						temphand.setHandRank();
						allhands.push_back(temphand);

					}
				}
			}

		}

	}

	//sort combinations
	sort(allhands.begin(), allhands.end(), poker_rank);

	//choose the best one
	return allhands[0];
}
HandType PokerHandEvaluator::evaluate(Hand hand) {
    cards = hand.getCards();
    if (isFlush()) {
        return FLUSH;
    }
    if (hasFourOfKind() != NORANK) {
        return FOUROFAKIND;
    }
    if (hasTriple() != NORANK && pairCount() >= 2) {
        return HOUSE;
    }
    if (hasTriple() != NORANK) {
        return THREEOFAKIND;
    }
    if (pairCount() == 2) {
        return TWOPAIR;
    }
    if (pairCount() == 1) {
        return ONEPAIR;
    }


    return HIGHCARD;
}