Пример #1
0
        new protected string decide_tell()
        {
            string tell_candidate = "";

            if (bluff &&
                hand.best_hand_value < Hand_Values.END)
            {
                Hand_Values bluff_hand_value = (Hand_Values)(rand.Next((int)Hand_Values.END - (int)hand.best_hand_value - 1) + (int)hand.best_hand_value) + 1;
                tell_candidate = base.decide_tell(bluff_hand_value);
            }
            else
            {
                tell_candidate = base.decide_tell();
            }

            return(tell_candidate);
        }
Пример #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;
                }
            }
        }
Пример #3
0
        protected string decide_tell(Hand_Values best_hand_value)
        {
            string[] tell_arr = get_tell_array(tell_type);

            int tier = 0;

            if (best_hand_value > Hand_Values.FULL_HOUSE)
            {
                tier = 3;
            }
            else if (best_hand_value > Hand_Values.ONE_PAIR)
            {
                tier = 2;
            }
            else if (best_hand_value > Hand_Values.HIGH_CARD)
            {
                tier = 1;
            }

            return(tell_arr[tier]);
        }
Пример #4
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;
             }
        }
Пример #5
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;
        }
Пример #6
0
        protected string decide_tell(Hand_Values best_hand_value)
        {
            string[] tell_arr = get_tell_array(tell_type);

             int tier = 0;
             if (best_hand_value > Hand_Values.FULL_HOUSE)
             {
            tier = 3;
             }
             else if (best_hand_value > Hand_Values.ONE_PAIR)
             {
            tier = 2;
             }
             else if (best_hand_value > Hand_Values.HIGH_CARD)
             {
            tier = 1;
             }

             return tell_arr[tier];
        }
Пример #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);
        }
Пример #8
0
        public Hand(Card[] cards, Deck deck, int max_size)
        {
            cards_p = cards;
             max_size_p = max_size;
             n_held_p = 0;
             for (int i = 0; i < cards.Length; i++)
             {
            if (cards_p[i] == null)
            {
               break;
            }
            else
            {
               ++n_held_p;
            }
             }
             deck_p = deck;
             the_best_p = new Card[max_size_p];
             the_rest_p = new Card[0];
             best_hand_value_p = Hand_Values.END;

             organize();
        }
Пример #9
0
        private Card[] get_multi_card_best(Hand_Values hand_value)
        {
            Card_Value val1 = cards_p[0].value;
             int n_val_1 = 1;
             Card_Value val2 = (Card_Value)0;
             int n_val_2 = 0;

             // full house
             // two pair

             // four of a kind
             // three of a kind
             // one pair
             // high card
             for(int i = 1; i < n_held; i++){
            Card_Value current_val = cards_p[i].value;
            Card_Value previous_val = cards_p[i - 1].value;

            if(n_val_2 == 0){
               val2 = current_val;
               n_val_2 = 1;
            }
            else if(current_val == previous_val){
               if(current_val == val1){
                  ++n_val_1;
               }
               else if(current_val == val2){
                  ++n_val_2;
               }
               else{
                  if(n_val_1 < 2){
                     val1 = current_val;
                     n_val_1 = 2;
                  }
                  else if(n_val_2 < 2){
                     val2 = current_val;
                     n_val_2 = 2;
                  }
               }
            }
             }

             Card[] best = null;
             Card_Value primary_val = val1;
             Card_Value secondary_val = val2;
             if(n_val_2 > n_val_1){
            secondary_val = val1;
            primary_val = val2;
             }
             else if (n_val_1 == n_val_2
            && secondary_val > primary_val)
             {
            secondary_val = val1;
            primary_val = val2;
             }

             int primary_index;
             int secondary_index;

             switch(hand_value){
            case(Hand_Values.FULL_HOUSE):
               const int FULL_HOUSE_LENGTH = 5;
               best = new Card[FULL_HOUSE_LENGTH];
               primary_index = 0;
               secondary_index = 3;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value == primary_val){
                     best[primary_index++] = cards_p[i];
                  }
                  else if(cards_p[i].value == secondary_val){
                     best[secondary_index++] = cards_p[i];
                  }
               }
               break;
            case(Hand_Values.TWO_PAIR):
               const int TWO_PAIR_LENGTH = 4;
               best = new Card[TWO_PAIR_LENGTH];
               primary_index = 0;
               secondary_index = 2;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value == primary_val){
                     best[primary_index++] = cards_p[i];
                  }
                  else if(cards_p[i].value == secondary_val){
                     best[secondary_index++] = cards_p[i];
                  }
               }
               break;
            case(Hand_Values.FOUR_OF_A_KIND):
               best = new Card[4];
               primary_index = 0;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value == primary_val){
                     best[primary_index++] = cards_p[i];
                  }
               }
               break;
            case(Hand_Values.THREE_OF_A_KIND):
               best = new Card[3];
               primary_index = 0;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value == primary_val){
                     best[primary_index++] = cards_p[i];
                  }
               }
               break;
            case(Hand_Values.ONE_PAIR):
               best = new Card[2];
               primary_index = 0;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value == primary_val){
                     best[primary_index++] = cards_p[i];
                  }
               }
               break;
            case(Hand_Values.HIGH_CARD):
               best = new Card[1];
               Card_Value high_card_val = (Card_Value)0;
               for(int i = 0; i < n_held; i++){
                  if(cards_p[i].value > high_card_val){
                     high_card_val = cards_p[i].value;
                     best[0] = cards_p[i];
                  }
               }
               break;
             }

             return best;
        }
Пример #10
0
 // Constructors
 public Hand(Hand other)
 {
     this.cards_p = other.cards;
      this.max_size_p = other.max_size;
      this.n_held_p = other.n_held;
      this.deck_p = other.deck;
      this.the_best_p = other.the_best;
      this.the_rest_p = other.the_rest;
      this.best_hand_value_p = other.best_hand_value;
 }
Пример #11
0
        public void organize()
        {
            Card_Value straight_starting_value;
             Card_Suite flush_suite;

             best_hand_value_p = calculate_best_hand_value(out straight_starting_value, out flush_suite);

             bool straight = false;
             bool flush = false;

             switch(best_hand_value){
            case(Hand_Values.ROYAL_FLUSH):
            case(Hand_Values.STRAIGHT_FLUSH):
               flush = true;
               straight = true;
               break;
            case(Hand_Values.FLUSH):
               flush = true;
               break;
            case(Hand_Values.ROYAL_STRAIGHT):
            case(Hand_Values.STRAIGHT):
               straight = true;
               break;
            default:
               break;
             }

             fill_best(straight, flush, straight_starting_value, flush_suite);
             fill_rest();
             organize_hand();
        }
Пример #12
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);
        }
Пример #13
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;
            }
        }
Пример #14
0
        private int calculated_bet(Method_Data data)
        {
            // convert data items to normal item
            bool        bluff               = data.bluff;
            bool        first_turn          = data.first_turn;
            bool        is_call             = data.is_call;
            int         bet                 = data.bet;
            int         total_money         = data.total_money;
            int         available_funds     = data.available_funds;
            int         personal_investment = data.personal_investment;
            double      CALL_THRESHHOLD_MIN = data.CALL_THRESHHOLD_MIN;
            double      CALL_THRESHHOLD_MAX = data.CALL_THRESHHOLD_MAX;
            Hand_Values hand_value          = data.hand_value;

            double amount;                                                         // return value in double form
            double investment     = (double)personal_investment / total_money * 8; // 0 to 1
            double potential_loss = (double)bet / total_money * 4;                 // 0 to 1

            if (potential_loss == 0)
            {
                potential_loss = (double)personal_investment / total_money * 4;
            }

            // calculate wealth_factor
            double money_tier = 0;

            if (wealth_type == Wealth_Types.POOR)
            {
                money_tier  = (int)Wealth_Values.POOR;
                money_tier *= 1.6;
            }
            else if (wealth_type == Wealth_Types.ALRIGHT)
            {
                money_tier  = (int)Wealth_Values.ALRIGHT;
                money_tier /= 5;
            }
            else if (wealth_type == Wealth_Types.WELL_OFF)
            {
                money_tier  = (int)Wealth_Values.WELL_OFF;
                money_tier /= 15;
            }
            else if (wealth_type == Wealth_Types.RICH)
            {
                money_tier  = (int)Wealth_Values.RICH;
                money_tier /= 50;
            }

            int capper   = 1;
            int bet_temp = bet;

            while (bet_temp > 0)
            {
                bet_temp /= 10;
                ++capper;
            }
            capper *= 3;

            double wealth_factor = 1.8 / (((int)wealth_type + 5) / (double)2 / ((int)wealth_type + 1));

            //double max_amount = potential_loss * chances * money_tier * investment * wealth_factor; // $ willing to bet
            double max_amount = .482 * Math.Sqrt(3 * (double)bet) + (0.0184 * (chances - 0.70) / .35) * money_tier + 5; // ERROR TESTING adjust bit in front of chances once chances gets fixed

            //max_amount /= capper;

            int[] hand_value_factors = { 1, 3, 6, 8, 9, 10, 11, 13, 15, 17, 20, 24, 30 };

            /*
             * Console.WriteLine("Stats:");
             * Console.WriteLine("\tfirst_turn: {0}", first_turn);
             * Console.WriteLine("\tis_call: {0}", is_call);
             * Console.WriteLine("\tbet: {0}", bet);
             * Console.WriteLine("\ttotal_money: {0}", total_money);
             * Console.WriteLine("\tavailable_funds: {0}", available_funds);
             * Console.WriteLine("\t\tpotential_loss: {0}", potential_loss);
             * Console.WriteLine("\t\tchances: {0}", chances);
             * Console.WriteLine("\t\tmoney_tier: {0}", money_tier);
             * Console.WriteLine("\t\tinvestment: {0}", investment);
             * Console.WriteLine("\t\twealth_factor: {0}", wealth_factor);
             * Console.WriteLine();
             * Console.WriteLine("max_amount: {0}", max_amount);
             */

            //double max_amount = 1 / potential_loss / 10 * available_funds;
            // anywhere from 1/250 to 1/4

            // max raising of x10
            // max raising first turn of x3

            double adjusted_max = max_amount;

            if (bluff &&
                hand_value == Hand_Values.HIGH_CARD)
            {
                adjusted_max *= hand_value_factors[rand.Next((int)Hand_Values.ROYAL_FLUSH - (int)Hand_Values.TWO_PAIR) + (int)Hand_Values.TWO_PAIR] / 3 + 1;
            }
            else
            {
                adjusted_max *= hand_value_factors[(int)hand_value] / 3 + 1;
            }

            // willingness to raise instead of call
            if (adjusted_max > bet &&
                adjusted_max >= 1.6 * CALL_THRESHHOLD_MAX)
            {
                CALL_THRESHHOLD_MAX *= 2;
            }

            // Console.WriteLine(adjusted_max);

            if (bet < 0 ||
                adjusted_max < 0)
            {
                amount = 0;
            }
            else if (is_call)
            {
                if (adjusted_max >= CALL_THRESHHOLD_MIN &&
                    adjusted_max <= CALL_THRESHHOLD_MAX)
                {
                    amount = bet;
                }
                else if (adjusted_max > CALL_THRESHHOLD_MAX)
                {
                    amount = adjusted_max;
                }
                else
                {
                    amount = 0;
                }
            }
            else
            {
                double random_factor = rand.NextDouble() * rand.NextDouble() * (rand.Next(8) + 1) % 1;
                while (random_factor < .85)
                {
                    random_factor *= rand.Next(3) + 2;
                    if (random_factor > 1)
                    {
                        random_factor = 1;
                    }
                }

                double recklessness_factor = ((int)wealth_type + 5) / (double)7;

                // Console.WriteLine("random_factor: {0}\nrecklessness: {1}", random_factor, recklessness_factor);

                amount = adjusted_max * random_factor * recklessness_factor;

                // Console.WriteLine("adjusted amount: {0}", amount);

                double investment_factor = 1;

                if (personal_investment > .9 * total_money)
                {
                    investment_factor = 2000;
                }
                else if (personal_investment > .7 * total_money)
                {
                    investment_factor = 3.5;
                }
                else if (personal_investment > .6 * total_money)
                {
                    investment_factor = 2.5;
                }
                else if (personal_investment > .5 * total_money)
                {
                    investment_factor = 2;
                }
                else
                {
                    investment_factor  = 1.1;
                    investment_factor += ((double)personal_investment / total_money);
                }

                // Console.WriteLine("investment_factor: {0}", investment_factor);

                amount *= investment_factor;
            }

            if (amount < bet &&
                amount != 0)
            {
                Console.WriteLine("final amount: {0}", amount);
            }

            return((int)amount);
        }
Пример #15
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);
        }