Exemple #1
0
        public Card_Info[] extract_cards(string raw_input)
        {
            Card_Info[] info_arr  = new Card_Info[10];
            int         arr_index = 0;

            string[] raw_choices = raw_input.Split(new char[] { ',', ';' });
            foreach (string raw_choice in raw_choices)
            {
                string[] split_raw = raw_choice.Split(new char[] { ' ' });
                for (int i = 0; i < split_raw.Length; i++)
                {
                    Card_Value val = text_to_value(split_raw[i]);
                    if (val != Card_Value.END)
                    {
                        // found the card value of the split
                        Card_Info card_info = new Card_Info();
                        card_info.value = val;
                        card_info.suite = text_to_suite(split_raw[i + 2]);

                        info_arr[arr_index++] = card_info;
                    }
                }
            }

            return(info_arr);
        }
Exemple #2
0
        private void set_call_threshholds(ref Method_Data data, int n_folds, Card_Value high_card_value)
        {
            int         bet        = data.bet;
            Hand_Values hand_value = data.hand_value;

            if (bet == 0)
            {
                data.CALL_THRESHHOLD_MIN = Money.DEFAULT_ANTE - 4;
                data.CALL_THRESHHOLD_MAX = Money.DEFAULT_ANTE + 4;
            }
            else if (wealth_type == Wealth_Types.ALRIGHT)
            {
                data.CALL_THRESHHOLD_MIN = (double)bet * .85;
                data.CALL_THRESHHOLD_MAX = (double)bet * 1.15;
            }
            else if (wealth_type == Wealth_Types.WELL_OFF)
            {
                data.CALL_THRESHHOLD_MIN = (double)bet * .82;
                data.CALL_THRESHHOLD_MAX = (double)bet * 1.18;
            }
            else if (wealth_type == Wealth_Types.RICH)
            {
                data.CALL_THRESHHOLD_MIN = (double)bet * .73;
                data.CALL_THRESHHOLD_MAX = (double)bet * 1.27;
            }
            else
            {
                data.CALL_THRESHHOLD_MIN = (double)bet * .9;
                data.CALL_THRESHHOLD_MAX = (double)bet * 1.1;
            }

            // determines when the AI are going to call a player on bullcrap bluffs
            if (n_folds > 6 - (int)perception_type)
            {
                if (hand_value > Hand_Values.HIGH_CARD)
                {
                    data.CALL_THRESHHOLD_MIN = (double)5;
                }
                else if (high_card_value > Card_Value.JACK)
                {
                    data.CALL_THRESHHOLD_MIN = (double)25;
                }
            }
        }
Exemple #3
0
        static private void display(Card_Suite suite, Card_Value value)
        {
            string val_str = value.ToString().ToLower();

            val_str = val_str.ElementAt(0).ToString().ToUpper() + val_str.Substring(1);
            string sui_str = suite.ToString().ToLower();

            sui_str = sui_str.ElementAt(0).ToString().ToUpper() + sui_str.Substring(1);

            // guard conditions
            if (value == Card_Value.JOKER)
            {
                Console.WriteLine("{0}", val_str);
            }
            else if (suite == Card_Suite.END || value == Card_Value.END)
            {
                Console.WriteLine("Invalid card passed");
            }
            else
            {
                Console.WriteLine("{0} of {1}", val_str, sui_str);
            }
        }
        private void set_call_threshholds(ref Method_Data data, int n_folds, Card_Value high_card_value)
        {
            int bet = data.bet;
             Hand_Values hand_value = data.hand_value;

             if (bet == 0)
             {
            data.CALL_THRESHHOLD_MIN = Money.DEFAULT_ANTE - 4;
            data.CALL_THRESHHOLD_MAX = Money.DEFAULT_ANTE + 4;
             }
             else if (wealth_type == Wealth_Types.ALRIGHT)
             {
            data.CALL_THRESHHOLD_MIN = (double)bet * .85;
            data.CALL_THRESHHOLD_MAX = (double)bet * 1.15;
             }
             else if (wealth_type == Wealth_Types.WELL_OFF)
             {
            data.CALL_THRESHHOLD_MIN = (double)bet * .82;
            data.CALL_THRESHHOLD_MAX = (double)bet * 1.18;
             }
             else if (wealth_type == Wealth_Types.RICH)
             {
            data.CALL_THRESHHOLD_MIN = (double)bet * .73;
            data.CALL_THRESHHOLD_MAX = (double)bet * 1.27;
             }
             else
             {
            data.CALL_THRESHHOLD_MIN = (double)bet * .9;
            data.CALL_THRESHHOLD_MAX = (double)bet * 1.1;
             }

             // determines when the AI are going to call a player on bullcrap bluffs
             if (n_folds > 6 - (int)perception_type)
             {
            if (hand_value > Hand_Values.HIGH_CARD)
            {
               data.CALL_THRESHHOLD_MIN = (double)5;
            }
            else if (high_card_value > Card_Value.JACK)
            {
               data.CALL_THRESHHOLD_MIN = (double)25;
            }
             }
        }
        private void modify_chances(Hand_Values hand_value, Card_Value card_value)
        {
            // establish base chance off of hand value
             //chances = .09 * ((int)(hand_value) + 1);

             double[] chance_arr = new double[10];

             /*
             double total_cards = 52 * 51 * 50 * 49 * 48;
             const int N_SUITES = 4;
             const int N_STRAIGHTS = 10;
             const int N_IN_SUITE = 13;
             const int N_CARDS = 52;
             const int MAX = 5;
             double DENOM = combination(N_CARDS, MAX);
             double any_suites = Math.Pow(combination(N_SUITES, 1), MAX);

             double royal_flush_chance = (double)N_SUITES * combination(5, MAX) / DENOM;
             double royal_straight_chance = (double)any_suites * combination(5, MAX)
            - N_SUITES * combination(5, MAX) // exclude royal flush chance
            / DENOM;
             double straight_flush_chance = (double)N_SUITES * N_STRAIGHTS * combination(5, MAX)
            - N_SUITES * combination(5, MAX) // exclude royal flush chance
            / DENOM;
             double four_of_a_kind_chance = (double)N_IN_SUITE * combination(4, 4) * combination((N_IN_SUITE - 1) * N_SUITES, MAX) / DENOM;
             double full_house_chance = (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) / DENOM;
             double flush_chance = (double)N_SUITES * combination(N_IN_SUITE, MAX)
            - (double)N_SUITES * N_STRAIGHTS * combination(5, MAX) // exclude straight flushes and royal flush
            / DENOM;
             double straight_chance = (double)any_suites * N_STRAIGHTS * combination(5, MAX)
            - (double)N_SUITES * N_STRAIGHTS * combination(5, MAX) // exclude royal straight and straight flushes
            / DENOM;
             double three_of_a_kind_chance = (double)N_IN_SUITE * combination(4, 3) * combination((int)(N_SUITES * (N_IN_SUITE - 1)), 2)
            - (double)N_IN_SUITE * combination(4, 4) * combination ((N_IN_SUITE - 1) * N_SUITES, MAX) // exclude four of a kind
            - (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) // exclude full house
            / DENOM;
             double two_pair_chance = (double)N_IN_SUITE * combination(4, 2) * (N_IN_SUITE - 1) * combination(4, 2)
            - (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) // exclude full house chances
            / DENOM;
             double one_pair_chance = (double)N_IN_SUITE * combination(4, 2) / DENOM
            - full_house_chance - three_of_a_kind_chance - two_pair_chance - full_house_chance - four_of_a_kind_chance;
             double remaining_chance = 0;

             // fill chance_arr
             chance_arr[0] = one_pair_chance;
             chance_arr[1] = two_pair_chance;
             chance_arr[2] = three_of_a_kind_chance;
             chance_arr[3] = straight_chance;
             chance_arr[4] = flush_chance;
             chance_arr[5] = full_house_chance;
             chance_arr[6] = four_of_a_kind_chance;
             chance_arr[7] = straight_flush_chance;
             chance_arr[8] = royal_straight_chance;
             chance_arr[9] = royal_flush_chance;

             // calculate remaining_chance
             for(int i = 0; i < chance_arr.Length; i++){
            remaining_chance -= chance_arr[i];
            if((int)hand_value == i){
               break;
            }
             }

             // adjust remaining chances based off of card value
             if(hand_value == Hand_Values.HIGH_CARD){
            if((int)card_value == 0){
               ++card_value;
            }
            remaining_chance /= (int)card_value;
             }

             double royal_flush_chance = (double)N_SUITES * (5 * 4 * 3 * 2 * 1) / total_cards;
             double royal_straight_chance = (double)(Math.Pow(N_SUITES, (double)5) * (5 * 4 * 3 * 2 * 1) / total_cards;
             double straight_flush_chance = ((double)N_SUITES * (N_STRAIGHTS) * (5 * 4 * 3 * 2 * 1) - (N_SUITES * N_STRAIGHTS))/ total_cards; // account for royal flush chance at end
             double four_of_a_kind_chance = (double)N_IN_SUITE * (4 * 3 * 2 * 1 * (N_IN_SUITE - 1) * N_SUITES) / total_cards;
             double full_house_chance = (double)N_IN_SUITE * (52 * 3 * 2) * (double)(N_IN_SUITE - 1) * (49 * 3) / total_cards;
             double flush_chance = ((double)N_SUITES * (N_IN_SUITE * (N_IN_SUITE - 1) * (N_IN_SUITE - 2) * (N_IN_SUITE - 3) * (N_IN_SUITE - 4)) - (N_SUITES * N_STRAIGHTS)) / total_cards; // account for the straight flushes at the end
             double straight_chance = ((double)N_STRAIGHTS * Math.Pow(N_SUITES, (double)5) - N_SUITES * N_STRAIGHTS) * (5 * 4 * 3 * 2 * 1) / total_cards; // account for straight flushes (n_suites * n_straights)
             */

             double one_pair_chance = (double)3 / 51 * 48 / 50 * 47 / 49 * 46 / 48;
             chance_arr[0] = one_pair_chance;
             double two_pair_chance = (double)6 / 50 * 5 / 49 * 44 / 48;
             chance_arr[1] = two_pair_chance;
             double three_of_a_kind_chance = (double)3 / 51 * 2 / 50 * 48 / 49 * 47 / 48;
             chance_arr[2] = three_of_a_kind_chance;
             double flush_chance = (double)12 / 51 * 11 / 50 * 10 / 49 * 9 / 48;
             chance_arr[3] = flush_chance;
             double full_house_chance = (double)6 / 50 * 5 / 49 * 4 / 48;
             chance_arr[4] = full_house_chance;
             double royal_straight_chance = (double)20 / 52 * 16 / 51 * 12 / 50 * 8 / 49 * 4 / 48;
             double straight_chance = royal_straight_chance * 5;
             chance_arr[5] = straight_chance;
             chance_arr[6] = royal_straight_chance;
             double four_of_a_kind_chance = (double)3 / 51 * 2 / 50 * 1 / 49;
             chance_arr[7] = four_of_a_kind_chance;
             double straight_flush_chance = straight_chance / 13;
             chance_arr[8] = straight_flush_chance;
             double royal_flush_chance = (double)20 / 52 * 4 / 51 * 3 / 50 * 2 / 49 * 1 / 48;
             chance_arr[9] = royal_flush_chance;

             double chance_of_better_hand = 0;

             if(hand_value == Hand_Values.HIGH_CARD){
            for(int i = 0; i < chance_arr.Length; i++){
               chance_of_better_hand += (1 - (1 - chance_arr[i]) * (1 - chance_arr[i]));
            }
             }
             else{
            for(int i = chance_arr.Length - 1; i >= (int)hand_value; i--){
               chance_of_better_hand += (1 - (1 - chance_arr[i]) * (1 - chance_arr[i]));
            }
             }

             // adjust chances based off of how good the deciding card value of your hand is
             double card_value_modifier = 0;
             switch(hand_value){
            case(Hand_Values.HIGH_CARD):
               card_value_modifier = 0;
               break;
            case(Hand_Values.ONE_PAIR):
               card_value_modifier = (one_pair_chance - one_pair_chance / (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.TWO_PAIR):
               card_value_modifier = (two_pair_chance - two_pair_chance / (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.THREE_OF_A_KIND):
               card_value_modifier = (three_of_a_kind_chance - three_of_a_kind_chance / (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.FLUSH):
               card_value_modifier = flush_chance;
               break;
            case(Hand_Values.FULL_HOUSE):
               card_value_modifier = (full_house_chance - full_house_chance/ (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.STRAIGHT):
               card_value_modifier = (straight_chance - straight_chance / (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.ROYAL_STRAIGHT):
               card_value_modifier = royal_straight_chance;
               break;
            case(Hand_Values.FOUR_OF_A_KIND):
               card_value_modifier = (four_of_a_kind_chance - four_of_a_kind_chance / (int)Card_Value.KING * (int)card_value);
               break;
            case(Hand_Values.ROYAL_FLUSH):
               card_value_modifier = royal_flush_chance;
               break;
            default:
               break;
             }

             // calculate and set chances
             if (hand_value == Hand_Values.HIGH_CARD)
             {
            chances = 1 - chance_of_better_hand;
            chances /= (int)Card_Value.KING;
            chances *= (int)card_value;
            return;
             }
             else{
            chances = 1 - chance_of_better_hand - card_value_modifier;
             }

             // modify estimated chance of winning by everyone's tells
             chances *= tell_chance_modifier;

             // adjust chances to be less than 1 if overdid it
             if (chances > MAX_CHANCE)
             {
            chances = MAX_CHANCE;
             }
        }
        // Methods
        public int calculate_bet(bool bluff, bool first_turn, bool is_call, int n_folds, int bet, int total_money, int available_funds, int personal_investment, Hand_Values hand_value, Card_Value high_card_value)
        {
            // calculate chances based off of checking other players cards/current_bets, and how much they just raised

             // based off of hand value and chances of winning,
             //    bet amount is based off of personality and remaining money
             // every chance level based off hand value is .09

             update_wealth_type(available_funds);
             modify_chances(hand_value, high_card_value);

             // fill out method data to pass around
             Method_Data data = new Method_Data();
             data.bluff = bluff;
             data.first_turn = first_turn;
             data.is_call = is_call;
             data.bet = bet;
             data.total_money = total_money;
             data.available_funds = available_funds;
             data.personal_investment = personal_investment;
             data.hand_value = hand_value;
             set_call_threshholds(ref data, n_folds, high_card_value);

             // pass off to personality determiner
             bet_method method_choice;
             switch (betting_type)
             {
            case (Betting_Types.STINGY):
               method_choice = stingy_bet;
               break;
            case(Betting_Types.RECKLESS):
               method_choice = reckless_bet;
               break;
            case(Betting_Types.CALCULATED):
               method_choice = calculated_bet;
               break;
            case(Betting_Types.ALL_IN):
               method_choice = all_in_bet;
               break;
            case(Betting_Types.EXTREME):
               method_choice = extreme_bet;
               break;
            case(Betting_Types.RANDOM):
               method_choice = random_bet;
               break;
            default:
               // Betting_Types.END chosen
               return 0;
             }

             double raw_amount = (double)method_choice(data);
             int amount = (int)raw_amount;

             // account for terribly inadequate hands returning a negative value
             if (raw_amount <= 0)
             {
            if (first_turn
               && data.bet < 40
               && data.bet < .1 * available_funds)
            {
               return data.bet;
            }
            else
            {
               return 0;
            }
             }

             // adjust for tricking opponents on the first turn
             if (first_turn
            && raw_amount > data.bet){
               if (data.bet == 0)
               {
                  amount = (int)raw_amount;
               }
               else if ( raw_amount > data.bet * (1 + (raw_amount - data.bet)/raw_amount) ){
                  amount = (int)(data.bet * (1 + (raw_amount - data.bet) / raw_amount));
               }
               else
               {
                  amount = (int)raw_amount;
               }

               if (amount < data.bet)
               {
                  amount = data.bet;
               }
            // amount /= 1.34;
             }
             else if (!first_turn
            && hand_value >= Hand_Values.TWO_PAIR)
             {
            amount = (int)(raw_amount * (2 + rand.NextDouble() / 2));//2.16);
             }
             else if (!first_turn)
             {
            amount = (int)(raw_amount * (1 + rand.NextDouble())); // 1.34);
             }

             // round off bet to make it look good if other bets have been rounded off
             if (round_off(bet) == bet)
             {
            int new_amount = round_off(amount);
            if(!(new_amount == 0
               && amount != 0))
            {
               if (new_amount >= data.bet)
               {
                  amount = new_amount;
               }
            }
             }

             return amount;
        }
Exemple #7
0
        private Player[] determine_winners()
        {
            // guard conditions
            if (player_queue.Count < 1)
            {
                return(new Player[0]);
            }

            Player[] winners = new Player[player_queue.Count];
            int      index   = 0;

            Hand_Values best_hand_value = (Hand_Values)0;
            Card_Value  best_card_value = (Card_Value)0;

            // get best hand/card combo
            foreach (Player player in player_queue)
            {
                if (player != null &&
                    player.hand != null &&
                    !player.folded &&
                    !player.is_out)
                {
                    if (player.hand.best_hand_value > best_hand_value)
                    {
                        best_hand_value = player.hand.best_hand_value;
                        if (player.hand.cards[0] != null)
                        {
                            best_card_value = player.hand.cards[0].value;
                        }
                        else
                        {
                            Console.WriteLine("ERROR: Null card existing in hand when determining round winner.");
                        }
                    }
                    else if (player.hand.best_hand_value == best_hand_value)
                    {
                        if (player.hand.cards[0] != null &&
                            player.hand.cards[0].value > best_card_value)
                        {
                            best_card_value = player.hand.cards[0].value;
                        }
                    }
                }
                else if (player == null ||
                         player.hand == null)
                {
                    Console.WriteLine("ERROR: Null player or hand possessed by player when determining round winner.");
                }
            }

            foreach (Player player in player_queue)
            {
                if (player == null ||
                    player.hand == null ||
                    player.hand.cards[0] == null)
                {
                    Console.WriteLine("ERROR: Null exception when determining round winner.");
                }
                else if (!player.folded &&
                         !player.is_out &&
                         player.hand.best_hand_value == best_hand_value &&
                         player.hand.cards[0].value == best_card_value)
                {
                    winners[index++] = player;
                }
            }

            // use tiebreaker to determine the best of the winners
            Hand[] hands = new Hand[index];
            for (int i = 0; i < index; i++)
            {
                hands[i] = winners[i].hand;
            }
            Card_Value tie_breaking_card = Hand.tie_breaker(hands);

            // use tie breaking card to figure out who the winner of winners is
            Player[]   winners_of_winners  = new Player[winners.Length];
            Card_Value best_tie_card_value = Hand.get_best_tie_card(winners[0].hand).value;

            // find the best tie card value
            for (int i = 0; i < winners.Length; i++)
            {
                if (winners[i] == null)
                {
                    break;
                }
                else
                {
                    Card best_tie_card = Hand.get_best_tie_card(winners[i].hand);
                    if (best_tie_card.value > best_tie_card_value)
                    {
                        best_tie_card_value = best_tie_card.value;
                    }
                }
            }
            // select the winners of the winners using the tie breaking card value
            index = 0;
            for (int i = 0; i < winners.Length; i++)
            {
                if (winners[i] == null)
                {
                    break;
                }
                else if (Hand.get_best_tie_card(winners[i].hand).value == best_tie_card_value)
                {
                    winners_of_winners[index++] = winners[i];
                }
            }

            // condense
            Player[] winners_no_nulls = new Player[index];
            for (int i = 0; i < index; i++)
            {
                winners_no_nulls[i] = winners_of_winners[i];
            }

            return(winners_no_nulls);
        }
Exemple #8
0
        // Methods
        public int calculate_bet(bool bluff, bool first_turn, bool is_call, int n_folds, int bet, int total_money, int available_funds, int personal_investment, Hand_Values hand_value, Card_Value high_card_value)
        {
            // calculate chances based off of checking other players cards/current_bets, and how much they just raised

            // based off of hand value and chances of winning,
            //    bet amount is based off of personality and remaining money
            // every chance level based off hand value is .09

            update_wealth_type(available_funds);
            modify_chances(hand_value, high_card_value);

            // fill out method data to pass around
            Method_Data data = new Method_Data();

            data.bluff               = bluff;
            data.first_turn          = first_turn;
            data.is_call             = is_call;
            data.bet                 = bet;
            data.total_money         = total_money;
            data.available_funds     = available_funds;
            data.personal_investment = personal_investment;
            data.hand_value          = hand_value;
            set_call_threshholds(ref data, n_folds, high_card_value);

            // pass off to personality determiner
            bet_method method_choice;

            switch (betting_type)
            {
            case (Betting_Types.STINGY):
                method_choice = stingy_bet;
                break;

            case (Betting_Types.RECKLESS):
                method_choice = reckless_bet;
                break;

            case (Betting_Types.CALCULATED):
                method_choice = calculated_bet;
                break;

            case (Betting_Types.ALL_IN):
                method_choice = all_in_bet;
                break;

            case (Betting_Types.EXTREME):
                method_choice = extreme_bet;
                break;

            case (Betting_Types.RANDOM):
                method_choice = random_bet;
                break;

            default:
                // Betting_Types.END chosen
                return(0);
            }

            double raw_amount = (double)method_choice(data);
            int    amount     = (int)raw_amount;

            // account for terribly inadequate hands returning a negative value
            if (raw_amount <= 0)
            {
                if (first_turn &&
                    data.bet < 40 &&
                    data.bet < .1 * available_funds)
                {
                    return(data.bet);
                }
                else
                {
                    return(0);
                }
            }

            // adjust for tricking opponents on the first turn
            if (first_turn &&
                raw_amount > data.bet)
            {
                if (data.bet == 0)
                {
                    amount = (int)raw_amount;
                }
                else if (raw_amount > data.bet * (1 + (raw_amount - data.bet) / raw_amount))
                {
                    amount = (int)(data.bet * (1 + (raw_amount - data.bet) / raw_amount));
                }
                else
                {
                    amount = (int)raw_amount;
                }

                if (amount < data.bet)
                {
                    amount = data.bet;
                }
                // amount /= 1.34;
            }
            else if (!first_turn &&
                     hand_value >= Hand_Values.TWO_PAIR)
            {
                amount = (int)(raw_amount * (2 + rand.NextDouble() / 2));//2.16);
            }
            else if (!first_turn)
            {
                amount = (int)(raw_amount * (1 + rand.NextDouble())); // 1.34);
            }

            // round off bet to make it look good if other bets have been rounded off
            if (round_off(bet) == bet)
            {
                int new_amount = round_off(amount);
                if (!(new_amount == 0 &&
                      amount != 0))
                {
                    if (new_amount >= data.bet)
                    {
                        amount = new_amount;
                    }
                }
            }

            return(amount);
        }
Exemple #9
0
        // Test mainframe
        /*
          public static void Main(string[] args)
          {
         uint card_id = 0;
         Card card = new Card("8; diamonds; what is this garbage?", card_id++);
         Card card2 = new Card("13; club; what IS this??", card_id++);
         Card card3 = new Card("what; WHAT; huh?", card_id++);

         card.display();
         card2.display();
         card3.display();

         Console.Read();
          }
           * */
        public Card(Card other)
        {
            this.suite_p = other.suite_p;
             this.value_p = other.value_p;
             this.ID_p = other.ID_p;
             this.mark_p = other.mark_p;
             this.discarded_p = other.discarded_p;
             this.unavailable_p = other.unavailable_p;
        }
Exemple #10
0
 public Card()
 {
     suite_p = Card_Suite.END;
      value_p = Card_Value.END;
      ID_p = 0;
      mark_p = "";
      discarded_p = false;
 }
Exemple #11
0
        private Card[] get_straight_best(Card_Value starting_value)
        {
            Card[] best = new Card[5];

             for(int i = 0; i < n_held; i++){
            if(cards_p[i].value >= starting_value
               && cards_p[i].value < (Card_Value)((int)starting_value + 5)){
               best[4 - (int)cards_p[i].value + (int)starting_value] = cards_p[i];
            }
             }

             return best;
        }
Exemple #12
0
 private void fill_best(bool straight, bool flush, Card_Value straight_starting_value, Card_Suite flush_suite)
 {
     if(straight && flush){
     if(best_hand_value_p == Hand_Values.ROYAL_FLUSH){
        the_best_p = get_royal_straight_best();
     }
     else{
        the_best_p = get_straight_flush_best(straight_starting_value);
     }
      }
      else if(straight){
     if(best_hand_value_p == Hand_Values.ROYAL_STRAIGHT){
        the_best_p = get_royal_straight_best();
     }
     else{
        the_best_p = get_straight_best(straight_starting_value);
     }
      }
      else if(flush){
     the_best_p = get_flush_best(flush_suite);
      }
      else{
     organize_by_value();
     the_best_p = get_multi_card_best(best_hand_value_p);
      }
 }
Exemple #13
0
        private bool check_for_straight_flush(Card_Value starting_value, Card_Suite[] flush_suites)
        {
            if(check_for_royal_flush(flush_suites)){
            return true;
             }

             if(starting_value > (Card_Value)((int)Card_Value.END - 5)){
            return false;
             }

             return get_straight_flush_suite(starting_value, flush_suites) != Card_Suite.END;
        }
Exemple #14
0
        // assumed to be organized by value
        private bool check_for_straight(out Card_Value starting_value)
        {
            organize_by_value();
             const int STRAIGHT_LENGTH = 5;
             starting_value = Card_Value.END;

             if(n_held < STRAIGHT_LENGTH){
            return false;
             }

             Card_Value current_card_value = Card_Value.END;
             int n_in_a_row = 1;
             bool potential_royal_flush = false;
             // handle royal flush cases
             for(int i = 1; i < n_held; i++){
            current_card_value = cards_p[i].value;
            Card_Value previous_card_value = cards_p[i - 1].value;
            if(current_card_value == previous_card_value){
               continue;
            }
            else if(current_card_value == previous_card_value - 1){
               ++n_in_a_row;
               starting_value = current_card_value;
               if(starting_value == Card_Value.TEN
                  && n_in_a_row >= STRAIGHT_LENGTH - 1){
                  potential_royal_flush = true;
               }
            }
            else if(current_card_value == Card_Value.ACE){
               if(potential_royal_flush){
                  starting_value = Card_Value.TEN;
                  return true;
               }
            }
            else{
               n_in_a_row = 1;
               starting_value = current_card_value;
            }
             }

             if(n_in_a_row >= STRAIGHT_LENGTH){
            return true;
             }
             else{
            return false;
             }
        }
Exemple #15
0
        // Methods

        // bet
        // ante_up
        // end_turn
        // fold
        // pay_big_blind
        // pay_small_blind
        // pay_up
        // raise
        // should skip
        // status_refresh

        private int calculate_bet(bool first_turn, bool is_call, int call_amount, int actions_so_far_this_turn)
        {
            if (hand.cards.Length < 1 ||
                hand.cards[0] == null)
            {
                return(0);
            }

            Hand_Values hand_value          = hand.best_hand_value;
            int         personal_investment = money.current_bet;
            Card_Value  high_card_value     = hand.cards[0].value;

            int amount = personality.calculate_bet(
                bluff,                // determines whether AI will bluff
                first_turn,           // whether a round of discards/betting has occurred
                is_call,              // whether someone has already bet
                n_folds,              // # of rounds ending in a fold -> pushes AI to bet or call bluffs
                call_amount,          // the current amount AI will have to match to stay in
                money.current_amount, // money in possession (including what's been bet)
                available_funds,      // money allowed to bet
                personal_investment,  // money already placed up for bet
                hand_value,           // value of the hand
                high_card_value);     // determining card value of the hand

            // prevent from looping
            // also another factor determining if you should call instead of raise
            const double PERCENTAGE_GATE      = .13;
            double       loop_flag_percentage = 0;

            if (personal_investment == 0 ||
                call_amount == 0)
            {
                loop_flag_percentage = PERCENTAGE_GATE + 1; // 100 call_amount, 5000 starting funds; 2% flag_percentage
            }
            else
            {
                loop_flag_percentage = (double)call_amount / personal_investment; // 100 call_amount / 300 personal_investment = 30%
            }

            // determine if raise instead of call
            if (amount > call_amount)
            {
                if (loop_flag_percentage < PERCENTAGE_GATE)
                {
                    // if raise, and in danger of having looped, just call instead of raise
                    amount = call_amount;
                }
                else if (actions_so_far_this_turn > 1 &&
                         first_turn)
                {
                    amount = call_amount;
                }
                else if (actions_so_far_this_turn > 4 &&
                         !first_turn)
                {
                    amount = call_amount;
                }
            }

            // ERROR TESTING
            if (amount > 0 &&
                amount < 5)
            {
                amount = 5;
            }

            return(amount);
        }
Exemple #16
0
        private void modify_chances(Hand_Values hand_value, Card_Value card_value)
        {
            // establish base chance off of hand value
            //chances = .09 * ((int)(hand_value) + 1);


            double[] chance_arr = new double[10];

            /*
             * double total_cards = 52 * 51 * 50 * 49 * 48;
             * const int N_SUITES = 4;
             * const int N_STRAIGHTS = 10;
             * const int N_IN_SUITE = 13;
             * const int N_CARDS = 52;
             * const int MAX = 5;
             * double DENOM = combination(N_CARDS, MAX);
             * double any_suites = Math.Pow(combination(N_SUITES, 1), MAX);
             *
             * double royal_flush_chance = (double)N_SUITES * combination(5, MAX) / DENOM;
             * double royal_straight_chance = (double)any_suites * combination(5, MAX)
             * - N_SUITES * combination(5, MAX) // exclude royal flush chance
             * / DENOM;
             * double straight_flush_chance = (double)N_SUITES * N_STRAIGHTS * combination(5, MAX)
             * - N_SUITES * combination(5, MAX) // exclude royal flush chance
             * / DENOM;
             * double four_of_a_kind_chance = (double)N_IN_SUITE * combination(4, 4) * combination((N_IN_SUITE - 1) * N_SUITES, MAX) / DENOM;
             * double full_house_chance = (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) / DENOM;
             * double flush_chance = (double)N_SUITES * combination(N_IN_SUITE, MAX)
             * - (double)N_SUITES * N_STRAIGHTS * combination(5, MAX) // exclude straight flushes and royal flush
             * / DENOM;
             * double straight_chance = (double)any_suites * N_STRAIGHTS * combination(5, MAX)
             * - (double)N_SUITES * N_STRAIGHTS * combination(5, MAX) // exclude royal straight and straight flushes
             * / DENOM;
             * double three_of_a_kind_chance = (double)N_IN_SUITE * combination(4, 3) * combination((int)(N_SUITES * (N_IN_SUITE - 1)), 2)
             * - (double)N_IN_SUITE * combination(4, 4) * combination ((N_IN_SUITE - 1) * N_SUITES, MAX) // exclude four of a kind
             * - (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) // exclude full house
             * / DENOM;
             * double two_pair_chance = (double)N_IN_SUITE * combination(4, 2) * (N_IN_SUITE - 1) * combination(4, 2)
             * - (double)N_IN_SUITE * combination(4, 3) * (N_IN_SUITE - 1) * combination(4, 2) // exclude full house chances
             * / DENOM;
             * double one_pair_chance = (double)N_IN_SUITE * combination(4, 2) / DENOM
             * - full_house_chance - three_of_a_kind_chance - two_pair_chance - full_house_chance - four_of_a_kind_chance;
             * double remaining_chance = 0;
             *
             * // fill chance_arr
             * chance_arr[0] = one_pair_chance;
             * chance_arr[1] = two_pair_chance;
             * chance_arr[2] = three_of_a_kind_chance;
             * chance_arr[3] = straight_chance;
             * chance_arr[4] = flush_chance;
             * chance_arr[5] = full_house_chance;
             * chance_arr[6] = four_of_a_kind_chance;
             * chance_arr[7] = straight_flush_chance;
             * chance_arr[8] = royal_straight_chance;
             * chance_arr[9] = royal_flush_chance;
             *
             * // calculate remaining_chance
             * for(int i = 0; i < chance_arr.Length; i++){
             * remaining_chance -= chance_arr[i];
             * if((int)hand_value == i){
             *    break;
             * }
             * }
             *
             * // adjust remaining chances based off of card value
             * if(hand_value == Hand_Values.HIGH_CARD){
             * if((int)card_value == 0){
             ++card_value;
             * }
             * remaining_chance /= (int)card_value;
             * }
             *
             *
             * double royal_flush_chance = (double)N_SUITES * (5 * 4 * 3 * 2 * 1) / total_cards;
             * double royal_straight_chance = (double)(Math.Pow(N_SUITES, (double)5) * (5 * 4 * 3 * 2 * 1) / total_cards;
             * double straight_flush_chance = ((double)N_SUITES * (N_STRAIGHTS) * (5 * 4 * 3 * 2 * 1) - (N_SUITES * N_STRAIGHTS))/ total_cards; // account for royal flush chance at end
             * double four_of_a_kind_chance = (double)N_IN_SUITE * (4 * 3 * 2 * 1 * (N_IN_SUITE - 1) * N_SUITES) / total_cards;
             * double full_house_chance = (double)N_IN_SUITE * (52 * 3 * 2) * (double)(N_IN_SUITE - 1) * (49 * 3) / total_cards;
             * double flush_chance = ((double)N_SUITES * (N_IN_SUITE * (N_IN_SUITE - 1) * (N_IN_SUITE - 2) * (N_IN_SUITE - 3) * (N_IN_SUITE - 4)) - (N_SUITES * N_STRAIGHTS)) / total_cards; // account for the straight flushes at the end
             * double straight_chance = ((double)N_STRAIGHTS * Math.Pow(N_SUITES, (double)5) - N_SUITES * N_STRAIGHTS) * (5 * 4 * 3 * 2 * 1) / total_cards; // account for straight flushes (n_suites * n_straights)
             */

            double one_pair_chance = (double)3 / 51 * 48 / 50 * 47 / 49 * 46 / 48;

            chance_arr[0] = one_pair_chance;
            double two_pair_chance = (double)6 / 50 * 5 / 49 * 44 / 48;

            chance_arr[1] = two_pair_chance;
            double three_of_a_kind_chance = (double)3 / 51 * 2 / 50 * 48 / 49 * 47 / 48;

            chance_arr[2] = three_of_a_kind_chance;
            double flush_chance = (double)12 / 51 * 11 / 50 * 10 / 49 * 9 / 48;

            chance_arr[3] = flush_chance;
            double full_house_chance = (double)6 / 50 * 5 / 49 * 4 / 48;

            chance_arr[4] = full_house_chance;
            double royal_straight_chance = (double)20 / 52 * 16 / 51 * 12 / 50 * 8 / 49 * 4 / 48;
            double straight_chance       = royal_straight_chance * 5;

            chance_arr[5] = straight_chance;
            chance_arr[6] = royal_straight_chance;
            double four_of_a_kind_chance = (double)3 / 51 * 2 / 50 * 1 / 49;

            chance_arr[7] = four_of_a_kind_chance;
            double straight_flush_chance = straight_chance / 13;

            chance_arr[8] = straight_flush_chance;
            double royal_flush_chance = (double)20 / 52 * 4 / 51 * 3 / 50 * 2 / 49 * 1 / 48;

            chance_arr[9] = royal_flush_chance;

            double chance_of_better_hand = 0;

            if (hand_value == Hand_Values.HIGH_CARD)
            {
                for (int i = 0; i < chance_arr.Length; i++)
                {
                    chance_of_better_hand += (1 - (1 - chance_arr[i]) * (1 - chance_arr[i]));
                }
            }
            else
            {
                for (int i = chance_arr.Length - 1; i >= (int)hand_value; i--)
                {
                    chance_of_better_hand += (1 - (1 - chance_arr[i]) * (1 - chance_arr[i]));
                }
            }

            // adjust chances based off of how good the deciding card value of your hand is
            double card_value_modifier = 0;

            switch (hand_value)
            {
            case (Hand_Values.HIGH_CARD):
                card_value_modifier = 0;
                break;

            case (Hand_Values.ONE_PAIR):
                card_value_modifier = (one_pair_chance - one_pair_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.TWO_PAIR):
                card_value_modifier = (two_pair_chance - two_pair_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.THREE_OF_A_KIND):
                card_value_modifier = (three_of_a_kind_chance - three_of_a_kind_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.FLUSH):
                card_value_modifier = flush_chance;
                break;

            case (Hand_Values.FULL_HOUSE):
                card_value_modifier = (full_house_chance - full_house_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.STRAIGHT):
                card_value_modifier = (straight_chance - straight_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.ROYAL_STRAIGHT):
                card_value_modifier = royal_straight_chance;
                break;

            case (Hand_Values.FOUR_OF_A_KIND):
                card_value_modifier = (four_of_a_kind_chance - four_of_a_kind_chance / (int)Card_Value.KING * (int)card_value);
                break;

            case (Hand_Values.ROYAL_FLUSH):
                card_value_modifier = royal_flush_chance;
                break;

            default:
                break;
            }

            // calculate and set chances
            if (hand_value == Hand_Values.HIGH_CARD)
            {
                chances  = 1 - chance_of_better_hand;
                chances /= (int)Card_Value.KING;
                chances *= (int)card_value;
                return;
            }
            else
            {
                chances = 1 - chance_of_better_hand - card_value_modifier;
            }

            // modify estimated chance of winning by everyone's tells
            chances *= tell_chance_modifier;

            // adjust chances to be less than 1 if overdid it
            if (chances > MAX_CHANCE)
            {
                chances = MAX_CHANCE;
            }
        }
Exemple #17
0
 public Card(string card_info, uint ID)
 {
     Card_Info info = interpret(card_info);
      suite_p = info.suite;
      value_p = info.value;
      ID_p = ID;
      mark_p = info.mark;
      discarded_p = false;
 }
Exemple #18
0
        // assumes that only 5 cards are held
        private Card[] get_straight_flush_best(Card_Value starting_value)
        {
            Card[] best = get_straight_best(starting_value);
             int[] n_of_suite = new int[5];

             for(int i = 0; i < n_held; i++){
            n_of_suite[(int)cards_p[i].suite]++;
             }

             Card_Suite most_suite = (Card_Suite)0;
             int highest_n_of_suite = 0;
             for(int i = 0; i < n_of_suite.Length; i++){
            if(n_of_suite[i] >= 5){
               return best;
            }
            else if(n_of_suite[i] > highest_n_of_suite){
               highest_n_of_suite = n_of_suite[i];
               most_suite = (Card_Suite)i;
            }
             }

             // replace incorrect cards
             for(int i = 0; i < n_held; i++){
            if(best[i].suite != most_suite){
               for(int j = 0; j < n_held; j++){
                  if(cards_p[j].suite == most_suite
                     && cards_p[j].value == best[i].value){
                     best[i] = cards_p[j];
                  }
               }
            }
             }

             return best;
        }
Exemple #19
0
        private static void display(Card_Suite suite, Card_Value value)
        {
            string val_str = value.ToString().ToLower();
             val_str = val_str.ElementAt(0).ToString().ToUpper() + val_str.Substring(1);
             string sui_str = suite.ToString().ToLower();
             sui_str = sui_str.ElementAt(0).ToString().ToUpper() + sui_str.Substring(1);

             // guard conditions
             if (value == Card_Value.JOKER)
             {
            Console.WriteLine("{0}", val_str);
             }
             else if (suite == Card_Suite.END || value == Card_Value.END)
             {
            Console.WriteLine("Invalid card passed");
             }
             else
             {
            Console.WriteLine("{0} of {1}", val_str, sui_str);
             }
        }
Exemple #20
0
        private Card_Suite get_straight_flush_suite(Card_Value starting_value, Card_Suite[] flush_suites)
        {
            Card_Suite royal_flush_suite = get_royal_flush_suite(flush_suites);
             if(royal_flush_suite != Card_Suite.END){
            return royal_flush_suite;
             }

             int[] n_in_suite = new int[flush_suites.Length];

             for(int i = 0; i < n_held; i++){
            Card current_card = cards_p[i];
            if(current_card.value < (Card_Value)((int)starting_value + 5)
               && current_card.value >= starting_value){
               // if it's the right value
               for(int suite_index = 0; suite_index < flush_suites.Length; suite_index++){
                  if(current_card.suite == flush_suites[suite_index]){
                     n_in_suite[suite_index]++;
                     if(n_in_suite[suite_index] >= STRAIGHT_LENGTH){
                        return flush_suites[suite_index];
                     }
                  }
               }
            }
             }

             return Card_Suite.END;
        }
Exemple #21
0
 public Card(Card_Info info, uint ID)
 {
     suite_p = info.suite;
      value_p = info.value;
      ID_p = ID;
      mark_p = info.mark;
      discarded_p = false;
 }
Exemple #22
0
        public Hand_Values calculate_best_hand_value(out Card_Value straight_starting_value, out Card_Suite flush_suite)
        {
            // have to make sure that the best hand value is updated
             // need to make sure the best part of the hand (the pair, two pairs, etc.) are at the front
             // have to distinguish between hand values

             straight_starting_value = Card_Value.END;
             flush_suite = Card_Suite.END;

             // initialize hand value tracking array
             bool[] is_hand_value = new bool[(int)Hand_Values.END];
             for(int i = 0; i < is_hand_value.Length; i++){
            is_hand_value[i] = false;
             }

             // check for the possibility of a flush
             Card_Suite[] flush_suites = check_for_flushes();
             is_hand_value[(int)Hand_Values.FLUSH] = flush_suites.Length > 0; // record if it's possible for a flush
             if(flush_suites.Length > 0){
            flush_suite = flush_suites[0];
             }

             // check for a normal straight
             is_hand_value[(int)Hand_Values.STRAIGHT] = check_for_straight(out straight_starting_value); // verify this will appropriately return TEN if royal straight present

             // check for a normal straight flush
             if(is_hand_value[(int)Hand_Values.FLUSH]
            && is_hand_value[(int)Hand_Values.STRAIGHT]){
            is_hand_value[(int)Hand_Values.STRAIGHT_FLUSH] = check_for_straight_flush(straight_starting_value, flush_suites);
            flush_suite = get_straight_flush_suite(straight_starting_value, flush_suites);
             }
             else{
            is_hand_value[(int)Hand_Values.STRAIGHT_FLUSH] = false;
             }

             // check for royal_straights/flushes
             if(is_hand_value[(int)Hand_Values.STRAIGHT]){
            is_hand_value[(int)Hand_Values.ROYAL_STRAIGHT] = check_for_royal_straight();
            if(is_hand_value[(int)Hand_Values.ROYAL_STRAIGHT]
               && is_hand_value[(int)Hand_Values.FLUSH]){
               is_hand_value[(int)Hand_Values.ROYAL_FLUSH] = check_for_royal_flush(flush_suites);
               flush_suite = get_royal_flush_suite(flush_suites);
            }
            else{
               is_hand_value[(int)Hand_Values.ROYAL_FLUSH] = false;
            }
             }

             // check for other non-flush things
             // check for multi-card things
             Hand_Values multi_card_hand_value = check_for_multi_card_hands();
             switch(multi_card_hand_value){
            case(Hand_Values.FULL_HOUSE):
               is_hand_value[(int)Hand_Values.FULL_HOUSE] = true;
               is_hand_value[(int)Hand_Values.THREE_OF_A_KIND] = true;
               is_hand_value[(int)Hand_Values.TWO_PAIR] = true;
               is_hand_value[(int)Hand_Values.ONE_PAIR] = true;
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
            case(Hand_Values.TWO_PAIR):
               is_hand_value[(int)Hand_Values.TWO_PAIR] = true;
               is_hand_value[(int)Hand_Values.ONE_PAIR] = true;
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
            case(Hand_Values.FOUR_OF_A_KIND):
               is_hand_value[(int)Hand_Values.FOUR_OF_A_KIND] = true;
               is_hand_value[(int)Hand_Values.THREE_OF_A_KIND] = true;
               is_hand_value[(int)Hand_Values.ONE_PAIR] = true;
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
            case(Hand_Values.THREE_OF_A_KIND):
               is_hand_value[(int)Hand_Values.THREE_OF_A_KIND] = true;
               is_hand_value[(int)Hand_Values.ONE_PAIR] = true;
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
            case(Hand_Values.ONE_PAIR):
               is_hand_value[(int)Hand_Values.ONE_PAIR] = true;
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
            case(Hand_Values.HIGH_CARD):
               is_hand_value[(int)Hand_Values.HIGH_CARD] = true;
               break;
             }

             // find the best hand value
             for(int i = is_hand_value.Length - 1; i >= 0; i--){
            if(is_hand_value[i]){
               return (Hand_Values)i;
            }
             }

             return Hand_Values.HIGH_CARD;
        }