Beispiel #1
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, pot: int, bb: int, **_) -> Tuple[Option, int]:

        evaluation = HoldemPoker.probability(self.cards, board)
        prediction = self.nn.predict(
            self.create_input(evaluation, self.money / pot, to_call / pot,
                              bb / pot, step is Step.Preflop,
                              step is Step.Flop, step is Step.Turn,
                              step is Step.River))

        answer: PokerDecisionAnswer2 = PokerDecisionAnswer2(prediction[0])
        raised_money = 0
        if answer is PokerDecisionAnswer2.AllIn:
            raised_money = self.remaining_money()
        elif answer is PokerDecisionAnswer2.Raise_10:
            raised_money = pot * 0.10
        elif answer is PokerDecisionAnswer2.Raise_25:
            raised_money = pot * 0.25
        elif answer is PokerDecisionAnswer2.Raise_40:
            raised_money = pot * 0.40
        elif answer is PokerDecisionAnswer2.Raise_55:
            raised_money = pot * 0.55
        elif answer is PokerDecisionAnswer2.Raise_70:
            raised_money = pot * 0.70
        elif answer is PokerDecisionAnswer2.Raise_85:
            raised_money = pot * 0.85
        elif answer is PokerDecisionAnswer2.Raise_100:
            raised_money = pot

        return answer.as_option(), raised_money
Beispiel #2
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, pot: int, bb: int, **_) -> Tuple[Option, int]:

        evaluation = HoldemPoker.probability(self.cards, board)
        prediction = self.nn.predict(
            self.create_input(evaluation, self.money / pot, to_call / pot,
                              bb / pot, step is Step.Preflop,
                              step is Step.Flop, step is Step.Turn,
                              step is Step.River))

        answer: PokerDecisionAnswer = PokerDecisionAnswer(prediction[0])

        raised_money: int = 0
        if answer is PokerDecisionAnswer.Raise:
            raised_money = evaluation * pot if random() > 0.4 else uniform(
                0.2, 1) * pot

        return answer.as_option(), raised_money
Beispiel #3
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, pot: int, bb: int, **_) -> Tuple[Option, int]:

        evaluation = HoldemPoker.probability(self.cards, board)
        prediction = self.nn.predict(
            self.create_input(evaluation, self.money / pot, to_call / pot,
                              bb / pot, step is Step.Preflop,
                              step is Step.Flop, step is Step.Turn,
                              step is Step.River))

        answer: PokerDecisionAnswer3 = PokerDecisionAnswer3(prediction[0])
        raise_amount = 0
        if answer is PokerDecisionAnswer3.AllIn:
            raise_amount = self.remaining_money()
        elif answer is PokerDecisionAnswer3.RaiseSmall:
            raise_amount = (0.1 + 0.25 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseMedium:
            raise_amount = (0.25 + 0.4 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseALot:
            raise_amount = (0.6 + 0.6 * random()) * pot

        return answer.as_option(), raise_amount
Beispiel #4
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, pot: int, bb: int, strength: Strength,
                **_) -> Tuple[Option, int]:

        evaluation = HoldemPoker.probability(self.cards, board)
        first: Rank = self.cards.first.rank
        second: Rank = self.cards.second.rank
        prediction = self.nn.predict(
            self.create_input(
                evaluation,
                self.money / pot,
                to_call / pot,
                bb / pot,
                step is Step.Preflop,
                step is Step.Flop,
                step is Step.Turn,
                step is Step.River,
                strength is Strength.Nothing,
                strength is Strength.Pair,
                strength is Strength.Pairs,
                strength is Strength.Set,
                strength is Strength.Straight,
                strength is Strength.Flush,
                strength is Strength.FullHouse,
                strength is Strength.Quad,
                strength is Strength.StraightFlush,
                strength is Strength.RoyalFlush,
                first is Rank.Two,
                first is Rank.Three,
                first is Rank.Four,
                first is Rank.Five,
                first is Rank.Six,
                first is Rank.Seven,
                first is Rank.Eight,
                first is Rank.Nine,
                first is Rank.Ten,
                first is Rank.Jack,
                first is Rank.Queen,
                first is Rank.King,
                first is Rank.Ace,
                second is Rank.Two,
                second is Rank.Three,
                second is Rank.Four,
                second is Rank.Five,
                second is Rank.Six,
                second is Rank.Seven,
                second is Rank.Eight,
                second is Rank.Nine,
                second is Rank.Ten,
                second is Rank.Jack,
                second is Rank.Queen,
                second is Rank.King,
                second is Rank.Ace,
                self.cards.suitability is Suitability.Suited,
            ))

        answer: PokerDecisionAnswer3 = PokerDecisionAnswer3(prediction[0])
        raise_amount = 0
        if answer is PokerDecisionAnswer3.AllIn:
            raise_amount = self.remaining_money()
        elif answer is PokerDecisionAnswer3.RaiseSmall:
            raise_amount = (0.1 + 0.25 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseMedium:
            raise_amount = (0.25 + 0.4 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseALot:
            raise_amount = (0.6 + 0.6 * random()) * pot

        return answer.as_option(), raise_amount
Beispiel #5
0
    def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int,
               bb: int, step: Step, cards: CardsPair, board: Cards,
               players_on_table: int, players_active: int,
               players_not_moved: int) -> PokerDecision6:

        if money < 0:
            raise ValueError(f'Money must be > 0, gived {money}')

        if pot < 0:
            raise ValueError(f'Pot must be > 0, gived {pot}')

        if call < 0:
            raise ValueError(f'Call must be > 0, gived {call}')

        if bb < 0:
            raise ValueError(f'Big blinds must be > 0, gived {bb}')

        if pot <= call and step != Step.Preflop:
            raise ValueError(
                f'Pot must be > call, gived call {call} pot {pot}')

        if type(res) is not PokerDecisionAnswer3:
            raise ValueError(
                f'Result must ne instance of PokerDecisionAnswer, gived {res}')

        pr = HoldemPoker.probability(cards, board)
        strength = HandStrength.get_strength(cards, board)
        outs: float = HoldemPoker.calculate_outs(
            cards, board)[0] / HoldemPoker.MAX_OUTS

        des = PokerDecision6()
        des.set_answer(res)
        des.probability_to_win = pr
        des.my_money = money
        des.money_in_pot = pot
        des.money_to_call = call
        des.big_blind = bb

        if step == Step.Preflop:
            des.is_preflop = 1
        elif step == Step.Flop:
            des.is_flop = 1
        elif step == Step.Turn:
            des.is_turn = 1
        elif step == Step.River:
            des.is_river = 1
        else:
            raise ValueError('bad step', step)

        int_strength: int = strength.value
        if int_strength < 0:
            raise ValueError('strength is < 0', int_strength, strength)
        des.strength[int_strength] = 1

        rank: int = cards.first.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.first.rank)
        des.first[rank] = 1

        rank: int = cards.second.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.second.rank)
        des.second[rank] = 1

        if cards.suitability == Suitability.Suited:
            des.have_suited_cards = 1

        if players_on_table < 2 or players_on_table > 10:
            raise ValueError('bad players on table:', players_active)

        if players_active < 2 or players_active > 10:
            raise ValueError('bad players active:', players_active)

        if players_active > players_on_table:
            raise ValueError('bad players active:', players_active,
                             'with players on table:', players_on_table)

        if players_not_moved < 0 or players_not_moved >= players_active:
            raise ValueError('bad players not moved:', players_not_moved,
                             'with players active:', players_active)

        des.players_on_table[players_on_table - 2] = 1
        des.players_playing[players_on_table - 2] = 1
        des.players_not_moved[players_not_moved] = 1

        des.outs = outs

        return des
    def create(res: BasePokerDecisionAnswer,
               money: int,
               pot: int,
               call: int,
               bb: int,
               step: Step,
               cards: CardsPair,
               board: Cards) -> PokerDecision5:

        if money < 0:
            raise ValueError(f'Money must be > 0, gived {money}')

        if pot < 0:
            raise ValueError(f'Pot must be > 0, gived {pot}')

        if call < 0:
            raise ValueError(f'Call must be > 0, gived {call}')

        if bb < 0:
            raise ValueError(f'Big blinds must be > 0, gived {bb}')

        if pot <= call and step != Step.Preflop:
            raise ValueError(f'Pot must be > call, gived call {call} pot {pot}')

        if type(res) is not PokerDecisionAnswer3:
            raise ValueError(f'Result must ne instance of PokerDecisionAnswer, gived {res}')

        pr = HoldemPoker.probability(cards, board)
        strength = HandStrength.get_strength(cards, board)

        des = PokerDecision5()
        des.set_answer(res)
        des.probability_to_win = pr
        des.my_money = money
        des.money_in_pot = pot
        des.money_to_call = call
        des.big_blind = bb

        if step == Step.Preflop:
            des.is_preflop = 1
        elif step == Step.Flop:
            des.is_flop = 1
        elif step == Step.Turn:
            des.is_turn = 1
        elif step == Step.River:
            des.is_river = 1
        else:
            raise ValueError('bad step', step)

        int_strength: int = strength.value
        if int_strength < 0:
            raise ValueError('strength is < 0', int_strength, strength)
        des.strength[int_strength] = 1

        rank: int = cards.first.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.first.rank)
        des.first[rank] = 1

        rank: int = cards.second.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.second.rank)
        des.second[rank] = 1

        if cards.suitability == Suitability.Suited:
            des.have_suited_cards = 1

        return des
Beispiel #7
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, online: bool, **_) -> Tuple[Option, int]:

        if step == Step.Preflop:
            curr_play: BasePlay = self.play.preflop

        elif step == Step.Flop:
            curr_play: BasePlay = self.play.flop

        elif step == Step.Turn:
            curr_play: BasePlay = self.play.turn

        elif step == Step.River:
            curr_play: BasePlay = self.play.river

        else:
            raise ValueError(f'Undefined step id {step}')

        if self.remaining_money() > min_raise * 3 and random(
        ) < curr_play.bluff:
            bluff = int(min_raise * (1 + random()))

            Debug.decision(
                f'609 {self.name} raise bluff {bluff}; bluff = {curr_play.bluff}'
            )

            if online:
                sleep(uniform(0.5, uniform(1, 2)))

            return Option.Raise, bluff

        probability = HoldemPoker.probability(self.cards, board)

        if probability < curr_play.min_probability_to_play:

            if to_call == 0 or to_call == self.gived:
                Debug.decision(
                    f'617 {self.name} check on low '
                    f'prob = {probability}; '
                    f'bet coefficient = {curr_play.bet} '
                    f'to call = {to_call} self.gived = {self.gived}')

                if online:
                    sleep(uniform(0.5, 1))

                return Option.CheckCall, 0

            else:
                Debug.decision(f'624 {self.name} fold low probability; '
                               f'prob = {probability}; '
                               f'min = {curr_play.min_probability_to_play}')

                if online:
                    sleep(uniform(0.5, 1))

                return Option.Fold, 0

        if probability > curr_play.min_probability_to_all_in and random(
        ) < curr_play.probability_to_all_in:

            if self.remaining_money() <= to_call:
                Debug.decision(
                    f'630 {self.name} call all in {self.gived} on high '
                    f'prob = {probability}; '
                    f'min = {curr_play.min_probability_to_all_in}')

                if online:
                    sleep(uniform(1, uniform(1.5, 3)))

            else:
                Debug.decision(f'631 {self.name} all in {self.gived} on high '
                               f'prob = {probability}; '
                               f'min = {curr_play.min_probability_to_all_in}')

                if online:
                    sleep(uniform(1, uniform(1.5, 3)))

            return Option.Raise, self.remaining_money()

        bet = int(
            min(probability * curr_play.bet_, 1) * self.remaining_money())

        if bet == self.remaining_money():

            if self.remaining_money() <= to_call:
                Debug.decision(
                    f'632 {self.name} call all in {self.gived} on high bet '
                    f'prob = {probability}; '
                    f'min = {curr_play.min_probability_to_all_in}')

                if online:
                    sleep(uniform(2, uniform(3, 5)))

            else:
                Debug.decision(
                    f'640 {self.name} all in {self.gived} on high bet '
                    f'prob = {probability}; '
                    f'bet coefficient = {curr_play.bet}')

                if online:
                    sleep(uniform(2, uniform(3, 5)))

            return Option.Raise, bet

        if to_call > bet:

            if to_call == 0 or self.gived == to_call:
                Debug.decision(
                    f'643 {self.name} check while can not raise bet = {bet}')

                if online:
                    sleep(uniform(0.5, uniform(1, 3)))

                return Option.CheckCall, 0

            else:
                Debug.decision(f'647 {self.name} fold on low bet '
                               f'prob = {probability}; '
                               f'bet coefficient = {curr_play.bet} '
                               f'bet = {bet}')

                if online:
                    sleep(uniform(1, uniform(2, 4)))

                return Option.Fold, 0

        if min_raise > bet:

            if to_call == 0 or self.gived == to_call:
                Debug.decision(f'656 {self.name} check on mid bet '
                               f'prob = {probability}; '
                               f'bet coefficient = {curr_play.bet} '
                               f'bet = {bet}')

                if online:
                    sleep(uniform(0.5, uniform(1, 2)))

                return Option.CheckCall, 0

            else:
                Debug.decision(f'666 {self.name} call {to_call} on mid bet '
                               f'prob = {probability}; '
                               f'bet coefficient = {curr_play.bet} '
                               f'bet = {bet}')

                if online:
                    sleep(uniform(2, uniform(4, 6)))

                return Option.CheckCall, to_call

        else:

            raise_bet = int(
                min(probability * curr_play.bet_ * curr_play.reduced_raise, 1)
                * self.remaining_money())

            if raise_bet <= self.gived:

                if to_call == 0 or self.gived == to_call:
                    Debug.decision(
                        f'670 {self.name} check while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(1, uniform(2, 3)))

                    return Option.CheckCall, 0

                else:
                    Debug.decision(
                        f'672 {self.name} fold while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                    return Option.Fold, 0

            if raise_bet < to_call:

                if to_call == 0 or self.gived == to_call:
                    Debug.decision(
                        f'673 {self.name} check while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(1, uniform(2, 3)))

                    return Option.CheckCall, 0

                else:
                    Debug.decision(
                        f'677 {self.name} fold while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                    return Option.Fold, 0

            if raise_bet < min_raise:

                if to_call == 0 or to_call == self.gived:
                    Debug.decision(
                        f'656 {self.name} check while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(0.5, uniform(1, 2)))

                    return Option.CheckCall, 0

                else:
                    Debug.decision(
                        f'682 {self.name} call {to_call} while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(3, uniform(6, 8)))

                    return Option.CheckCall, to_call

            if raise_bet == self.remaining_money():

                if raise_bet <= to_call:
                    Debug.decision(f'684 {self.name} call all in {self.gived}')

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                else:
                    Debug.decision(
                        f'687 {self.name} all in {self.gived} while thinks about raise {raise_bet}'
                    )

                    if online:
                        sleep(uniform(1, uniform(2, 3)))

                return Option.Raise, raise_bet

            if to_call == 0 and random() < curr_play.check_:
                Debug.decision(
                    f'690 {self.name} cold check wanted to raise {raise_bet} '
                    f'check probability {curr_play.check}')

                if online:
                    sleep(uniform(0.5, uniform(1, 2)))

                return Option.CheckCall, 0

            elif to_call != 0 and random() < curr_play.call:

                if self.remaining_money() <= to_call:
                    Debug.decision(
                        f'691 {self.name} cold call all in {self.gived}')

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                    return Option.CheckCall, self.remaining_money()

                else:
                    Debug.decision(
                        f'692 {self.name} cold call {to_call} while wanted to raise {raise_bet} '
                        f'call probability {curr_play.call}')

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                    return Option.CheckCall, to_call

            if self.remaining_money() <= raise_bet:

                if self.remaining_money() <= to_call:
                    Debug.decision(f'693 {self.name} call all in {self.gived}')

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                else:
                    Debug.decision(
                        f'694 {self.name} raise all in {self.gived}')

                    if online:
                        sleep(uniform(2, uniform(4, 6)))

                return Option.Raise, self.remaining_money()

            else:
                Debug.decision(
                    f'695 {self.name} raise {raise_bet} on high bet '
                    f'prob = {probability}; '
                    f'bet coefficient = {curr_play.bet} '
                    f'bet = {bet}')

                if online:
                    sleep(uniform(3, uniform(6, 9)))

                return Option.Raise, raise_bet
    def create(res: BasePokerDecisionAnswer,
               money: int,
               pot: int,
               call: int,
               bb: int,
               step: Step,
               cards: CardsPair,
               board: Cards) -> PokerDecision4:

        if money < 0:
            raise ValueError(f'Money must be > 0, gived {money}')

        if pot < 0:
            raise ValueError(f'Pot must be > 0, gived {pot}')

        if call < 0:
            raise ValueError(f'Call must be > 0, gived {call}')

        if bb < 0:
            raise ValueError(f'Big blinds must be > 0, gived {bb}')

        if pot <= call and step != Step.Preflop:
            raise ValueError(f'Pot must be > call, gived call {call} pot {pot}')

        if type(res) is not PokerDecisionAnswer3:
            raise ValueError(f'Result must ne instance of PokerDecisionAnswer, gived {res}')

        pr = HoldemPoker.probability(cards, board)
        strength = HandStrength.get_strength(cards, board)

        des = PokerDecision4()
        des.set_answer(res)
        des.probability_to_win = pr
        des.my_money = money
        des.money_in_pot = pot
        des.money_to_call = call
        des.big_blind = bb

        if step == Step.Preflop:
            des.is_preflop = 1
        elif step == Step.Flop:
            des.is_flop = 1
        elif step == Step.Turn:
            des.is_turn = 1
        elif step == Step.River:
            des.is_river = 1
        else:
            raise ValueError('bad step', step)

        if strength == Strength.RoyalFlush:
            des.have_royal_flush = 1
        elif strength == Strength.StraightFlush:
            des.have_straight_flush = 1
        elif strength == Strength.Quad:
            des.have_quad = 1
        elif strength == Strength.FullHouse:
            des.have_full_house = 1
        elif strength == Strength.Flush:
            des.have_flush = 1
        elif strength == Strength.Straight:
            des.have_straight = 1
        elif strength == Strength.Set:
            des.have_set = 1
        elif strength == Strength.Pairs:
            des.have_two_pairs = 1
        elif strength == Strength.Pair:
            des.have_pair = 1
        elif strength == Strength.Nothing:
            des.have_nothing = 1
        else:
            raise ValueError('bad hand strength', strength)

        return des
    def get_decisions(game: PokerGame,
                      hand: PokerHand) -> List[BasePokerDecision]:

        decisions: List[BasePokerDecision] = []

        pot_size = 0

        money: Dict[str, int] = {p.name: p.money for p in hand.players}
        bb: int = hand.big_blind

        Debug.datasets(')' * 20)
        for n, v in money.items():
            Debug.datasets(f'{n} - {v}')
        Debug.datasets('(' * 20)

        for step, stage in hand:
            Debug.datasets('NEW STEP', step)
            gived: Dict[str, int] = {p.name: 0 for p in hand.players}

            if step == Step.Preflop:
                raise_amount = hand.big_blind
            else:
                raise_amount = 0

            for act in stage:
                if act.event.is_statement():
                    continue

                Debug.datasets(act, raise_amount)

                if act.event == Event.Ante:
                    pot_size += act.money
                    money[act.player.name] -= act.money

                elif act.event == Event.SmallBlind:
                    pot_size += act.money
                    gived[act.player.name] = act.money
                    money[act.player.name] -= act.money

                elif act.event == Event.BigBlind:
                    pot_size += act.money
                    gived[act.player.name] = act.money
                    money[act.player.name] -= act.money

                elif act.event == Event.Fold:
                    if act.player.cards is not None and act.player.cards.initialized(
                    ) and not act.player.is_loser:
                        pr = HoldemPoker.probability(
                            act.player.cards, hand.board.get_from_step(step))
                        my_money = money[act.player.name]
                        to_call = raise_amount - gived[act.player.name]
                        des = PokerDecision.create(PokerDecisionAnswer.Fold,
                                                   pr, my_money, pot_size,
                                                   to_call, bb, step)
                        decisions += [des]

                elif act.event == Event.Check:
                    if act.player.cards is not None and act.player.cards.initialized(
                    ) and not act.player.is_loser:
                        pr = HoldemPoker.probability(
                            act.player.cards, hand.board.get_from_step(step))
                        my_money = money[act.player.name]
                        to_call = raise_amount - gived[act.player.name]
                        des = PokerDecision.create(
                            PokerDecisionAnswer.CheckCall, pr, my_money,
                            pot_size, to_call, bb, step)
                        decisions += [des]

                elif act.event == Event.Call:
                    if act.player.cards is not None and act.player.cards.initialized(
                    ) and not act.player.is_loser:
                        pr = HoldemPoker.probability(
                            act.player.cards, hand.board.get_from_step(step))
                        my_money = money[act.player.name]
                        if raise_amount > my_money + gived[act.player.name]:
                            to_call = my_money
                        else:
                            to_call = raise_amount - gived[act.player.name]
                        des = PokerDecision.create(
                            PokerDecisionAnswer.CheckCall, pr, my_money,
                            pot_size, to_call, bb, step)
                        decisions += [des]
                    pot_size += act.money - gived[act.player.name]
                    money[
                        act.player.name] -= act.money - gived[act.player.name]
                    gived[act.player.name] = act.money

                elif act.event == Event.Raise or act.event == Event.Allin:
                    if act.player.cards is not None and act.player.cards.initialized(
                    ) and not act.player.is_loser:
                        pr = HoldemPoker.probability(
                            act.player.cards, hand.board.get_from_step(step))
                        my_money = money[act.player.name]
                        to_call = raise_amount - gived[act.player.name]
                        des = PokerDecision.create(PokerDecisionAnswer.Raise,
                                                   pr, my_money, pot_size,
                                                   to_call, bb, step)
                        decisions += [des]
                    pot_size += act.money - gived[act.player.name]
                    money[
                        act.player.name] -= act.money - gived[act.player.name]
                    gived[act.player.name] = act.money
                    if raise_amount < act.money:
                        raise_amount = act.money

                elif act.event == Event.ReturnMoney:
                    pot_size -= act.money

                else:
                    raise ValueError('you forget about', act.event)

                Debug.datasets(')' * 20)
                for n, v in gived.items():
                    Debug.datasets(f'{n}: {money[n]} ({v})')
                Debug.datasets('(' * 20)

        Debug.datasets('*' * 20)

        for des in decisions:
            Debug.datasets(des)

        Debug.datasets('_' * 20)
        return decisions
Beispiel #10
0
    def _decide(self, *, step: Step, to_call: int, min_raise: int,
                board: Cards, pot: int, bb: int, strength: Strength,
                players_on_table: int, players_active: int,
                players_not_moved: int, **_) -> Tuple[Option, int]:
        if players_on_table < 2 or players_on_table > 10:
            raise ValueError('bad players on table:', players_active)

        if players_active < 2 or players_active > 10:
            raise ValueError('bad players active:', players_active)

        if players_active > players_on_table:
            raise ValueError('bad players active:', players_active,
                             'with players on table:', players_on_table)

        if players_not_moved < 0 or players_not_moved >= players_active:
            raise ValueError('bad players not moved:', players_not_moved,
                             'with players active:', players_active)

        evaluation = HoldemPoker.probability(self.cards, board)
        outs: float = HoldemPoker.calculate_outs(self.cards, board)[0]
        first: Rank = self.cards.first.rank
        second: Rank = self.cards.second.rank
        prediction = self.nn.predict(
            self.create_input(
                evaluation, self.money / pot, to_call / pot, bb / pot,
                step is Step.Preflop, step is Step.Flop, step is Step.Turn,
                step is Step.River, strength is Strength.Nothing,
                strength is Strength.Pair, strength is Strength.Pairs,
                strength is Strength.Set, strength is Strength.Straight,
                strength is Strength.Flush, strength is Strength.FullHouse,
                strength is Strength.Quad, strength is Strength.StraightFlush,
                strength is Strength.RoyalFlush, first is Rank.Two,
                first is Rank.Three, first is Rank.Four, first is Rank.Five,
                first is Rank.Six, first is Rank.Seven, first is Rank.Eight,
                first is Rank.Nine, first is Rank.Ten, first is Rank.Jack,
                first is Rank.Queen, first is Rank.King, first is Rank.Ace,
                second is Rank.Two, second is Rank.Three, second is Rank.Four,
                second is Rank.Five, second is Rank.Six, second is Rank.Seven,
                second is Rank.Eight, second is Rank.Nine, second is Rank.Ten,
                second is Rank.Jack, second is Rank.Queen, second is Rank.King,
                second is Rank.Ace,
                self.cards.suitability is Suitability.Suited,
                players_on_table == 2, players_on_table == 3,
                players_on_table == 4, players_on_table == 5,
                players_on_table == 6, players_on_table == 7,
                players_on_table == 8, players_on_table == 9,
                players_on_table == 10, players_active == 2,
                players_active == 3, players_active == 4, players_active == 5,
                players_active == 6, players_active == 7, players_active == 8,
                players_active == 9, players_active == 10,
                players_not_moved == 0, players_not_moved == 1,
                players_not_moved == 2, players_not_moved == 3,
                players_not_moved == 4, players_not_moved == 5,
                players_not_moved == 6, players_not_moved == 7,
                players_not_moved == 8, players_not_moved == 9,
                outs / HoldemPoker.MAX_OUTS))

        Debug.decision("NEURAL NETWORK 7 START THINK")
        Debug.decision('evaluation =', evaluation)
        Debug.decision('pot =', pot)
        Debug.decision('money =', self.money)
        Debug.decision('to_call =', to_call)
        Debug.decision('bb =', bb)
        Debug.decision('step =', step)
        Debug.decision('strength =', strength)
        Debug.decision('first =', first)
        Debug.decision('second =', second)
        Debug.decision('suited =', self.cards.suitability)
        Debug.decision('players_on_table =', players_on_table)
        Debug.decision('players_active =', players_active)
        Debug.decision('players_not_moved =', players_not_moved)
        Debug.decision('outs =', outs)

        answer: PokerDecisionAnswer3 = PokerDecisionAnswer3(prediction[0])

        Debug.decision('ANSWER =', answer)
        Debug.decision("NEURAL NETWORK 7 END THINK")

        raise_amount = 0
        if answer is PokerDecisionAnswer3.AllIn:
            raise_amount = self.remaining_money()
        elif answer is PokerDecisionAnswer3.RaiseSmall:
            raise_amount = (0.1 + 0.25 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseMedium:
            raise_amount = (0.25 + 0.4 * random()) * pot
        elif answer is PokerDecisionAnswer3.RaiseALot:
            raise_amount = (0.6 + 0.6 * random()) * pot

        return answer.as_option(), raise_amount
    def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int,
               bb: int, step: Step, cards: CardsPair, board: Cards,
               players_on_table: int, players_active: int,
               players_not_moved: int, max_playing_stack: int,
               average_stack_on_table: int, players: List[MockPlayer],
               folded_players: List[str],
               my_position: PokerPosition) -> PokerDecision10:

        if money < 0:
            raise ValueError(f'Money must be > 0, gived {money}')

        if pot < 0:
            raise ValueError(f'Pot must be > 0, gived {pot}')

        if call < 0:
            raise ValueError(f'Call must be > 0, gived {call}')

        if bb < 0:
            raise ValueError(f'Big blinds must be > 0, gived {bb}')

        if pot <= call and step != Step.Preflop:
            raise ValueError(
                f'Pot must be > call, gived call {call} pot {pot}')

        if type(res) is not PokerDecisionAnswer3:
            raise ValueError(
                f'Result must ne instance of PokerDecisionAnswer, gived {res}')

        pr = HoldemPoker.probability(cards, board)
        strength = HandStrength.get_strength(cards, board)
        outs: float = HoldemPoker.calculate_outs(
            cards, board)[0] / HoldemPoker.MAX_OUTS

        des = PokerDecision10()
        des.set_answer(res)
        des.probability_to_win = pr
        des.my_money = money
        des.money_in_pot = pot
        des.money_to_call = call
        des.big_blind = bb

        if step == Step.Preflop:
            des.is_preflop = 1
        elif step == Step.Flop:
            des.is_flop = 1
        elif step == Step.Turn:
            des.is_turn = 1
        elif step == Step.River:
            des.is_river = 1
        else:
            raise ValueError('bad step', step)

        int_strength: int = strength.value
        if int_strength < 0:
            raise ValueError('strength is < 0', int_strength, strength)
        des.strength[int_strength] = 1

        rank: int = cards.first.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.first.rank)
        des.first[rank] = 1

        rank: int = cards.second.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.second.rank)
        des.second[rank] = 1

        if cards.suitability == Suitability.Suited:
            des.have_suited_cards = 1

        if players_on_table < 2 or players_on_table > 10:
            raise ValueError('bad players on table:', players_active)

        if players_active < 2 or players_active > 10:
            raise ValueError('bad players active:', players_active)

        if players_active > players_on_table:
            raise ValueError('bad players active:', players_active,
                             'with players on table:', players_on_table)

        if players_not_moved < 0 or players_not_moved >= players_active:
            raise ValueError('bad players not moved:', players_not_moved,
                             'with players active:', players_active)

        des.players_on_table[players_on_table - 2] = 1
        des.players_playing[players_on_table - 2] = 1
        des.players_not_moved[players_not_moved] = 1

        des.outs = outs

        des.max_playing_stack = max_playing_stack
        des.average_stack_on_table = average_stack_on_table

        curr_raisers: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision10.CurrRaisers
        curr_callers: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision10.CurrCallers
        curr_folders: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision10.CurrFolders
        curr_checkers: Dict[Tuple[str, PokerPosition],
                            PlayerStatistics] = PokerDecision10.CurrCheckers

        raisers = []
        callers = []
        folders = []
        checkers = []
        for player in players:
            if player.name not in folded_players:
                raisers += [
                    curr_raisers[player.name, player.position].get_stats()
                ]
                callers += [
                    curr_callers[player.name, player.position].get_stats()
                ]
                folders += [
                    curr_folders[player.name, player.position].get_stats()
                ]
                checkers += [
                    curr_checkers[player.name, player.position].get_stats()
                ]

        des.max_raiser = max(raisers)
        des.min_raiser = min(raisers)
        des.avg_raiser = mean(raisers)

        des.max_caller = max(callers)
        des.min_caller = min(callers)
        des.avg_caller = mean(callers)

        des.max_folder = max(folders)
        des.min_folder = min(folders)
        des.avg_folder = mean(folders)

        des.max_checker = max(checkers)
        des.min_checker = min(checkers)
        des.avg_checker = mean(checkers)

        des.my_position_is_early = my_position is PokerPosition.Early
        des.my_position_is_middle = my_position is PokerPosition.Middle
        des.my_position_is_late = my_position is PokerPosition.Late
        des.my_position_is_blinds = my_position is PokerPosition.Blinds

        if step.value >= Step.Flop.value:
            cards_sorted = sorted(board[0:3], reverse=True)

            des.flop1[cards_sorted[0].rank.value - 2] = 1
            des.flop2[cards_sorted[1].rank.value - 2] = 1
            des.flop3[cards_sorted[2].rank.value - 2] = 1

            suits = sorted(board[0:3], key=lambda card: card.suit.value)

            if suits[0].suit == suits[1].suit == suits[2].suit:
                des.flop_3_suited = 1
            elif suits[0].suit == suits[1].suit or suits[1].suit == suits[
                    2].suit:
                des.flop_2_suited = 1
            elif suits[0].suit != suits[1].suit != suits[2].suit != suits[
                    0].suit:
                des.flop_rainbow = 1
            else:
                raise ValueError(f'bad sorted suits {suits}')

        if step.value >= Step.Turn.value:
            des.turn[board[3].rank.value - 2] = 1

            suits = sorted(board[0:4], key=lambda card: card.suit.value)

            if suits[0].suit == suits[1].suit == suits[2].suit == suits[3].suit:
                des.turn_4_suited = 1
            elif suits[0].suit == suits[1].suit == suits[2].suit:
                des.turn_3_suited = 1
            elif suits[1].suit == suits[2].suit == suits[3].suit:
                des.turn_3_suited = 1
            elif suits[0].suit == suits[1].suit and suits[2].suit == suits[
                    3].suit:
                des.turn_2_suited_and_other_2 = 1
            elif suits[0].suit == suits[
                    1].suit and suits[2].suit != suits[3].suit:
                des.turn_2_suited_2_not = 1
            elif suits[1].suit == suits[
                    2].suit and suits[0].suit != suits[3].suit:
                des.turn_2_suited_2_not = 1
            elif suits[2].suit == suits[
                    3].suit and suits[0].suit != suits[1].suit:
                des.turn_2_suited_2_not = 1
            elif len(set([suit.suit.value for suit in suits])) == 4:
                des.turn_rainbow = 1
            else:
                raise ValueError(f'bad suits {suits}')

        if step == Step.River:
            des.river[board[4].rank.value - 2] = 1

            suits = sorted(board, key=lambda card: card.suit.value)
            diff_suits = len(set([suit.suit.value for suit in suits]))

            if diff_suits == 1:
                des.river_5_suited = 1
            elif diff_suits == 2 and suits[0].suit == suits[1].suit == suits[
                    2].suit == suits[3].suit:
                des.river_4_suited = 1
            elif diff_suits == 2 and suits[1].suit == suits[2].suit == suits[
                    3].suit == suits[4].suit:
                des.river_4_suited = 1
            elif diff_suits == 2 and suits[0].suit == suits[1].suit == suits[
                    2].suit and suits[3].suit == suits[4].suit:
                des.river_3_suited_and_other_2 = 1
            elif diff_suits == 2 and suits[2].suit == suits[3].suit == suits[
                    4].suit and suits[0].suit == suits[1].suit:
                des.river_3_suited_and_other_2 = 1
            elif diff_suits == 3 and suits[0].suit == suits[1].suit == suits[
                    2].suit and suits[3].suit != suits[4].suit:
                des.river_3_suited_2_not = 1
            elif diff_suits == 3 and suits[1].suit == suits[2].suit == suits[
                    3].suit and suits[0].suit != suits[4].suit:
                des.river_3_suited_2_not = 1
            elif diff_suits == 3 and suits[2].suit == suits[3].suit == suits[
                    4].suit and suits[0].suit != suits[1].suit:
                des.river_3_suited_2_not = 1
            elif diff_suits == 3 and suits[0].suit == suits[1].suit and suits[
                    2].suit == suits[3].suit:
                des.river_2_suited_and_2_suited = 1
            elif diff_suits == 3 and suits[0].suit == suits[1].suit and suits[
                    3].suit == suits[4].suit:
                des.river_2_suited_and_2_suited = 1
            elif diff_suits == 3 and suits[1].suit == suits[2].suit and suits[
                    3].suit == suits[4].suit:
                des.river_2_suited_and_2_suited = 1
            elif diff_suits == 4:
                des.river_only_2_suited = 1
            else:
                raise ValueError(f'bad suits {diff_suits} {suits}')

        return des
    def create(res: BasePokerDecisionAnswer, money: int, pot: int, call: int,
               bb: int, step: Step, cards: CardsPair, board: Cards,
               players_on_table: int, players_active: int,
               players_not_moved: int, max_playing_stack: int,
               average_stack_on_table: int, players: List[MockPlayer],
               folded_players: List[str],
               my_position: PokerPosition) -> PokerDecision9:

        if money < 0:
            raise ValueError(f'Money must be > 0, gived {money}')

        if pot < 0:
            raise ValueError(f'Pot must be > 0, gived {pot}')

        if call < 0:
            raise ValueError(f'Call must be > 0, gived {call}')

        if bb < 0:
            raise ValueError(f'Big blinds must be > 0, gived {bb}')

        if pot <= call and step != Step.Preflop:
            raise ValueError(
                f'Pot must be > call, gived call {call} pot {pot}')

        if type(res) is not PokerDecisionAnswer3:
            raise ValueError(
                f'Result must ne instance of PokerDecisionAnswer, gived {res}')

        pr = HoldemPoker.probability(cards, board)
        strength = HandStrength.get_strength(cards, board)
        outs: float = HoldemPoker.calculate_outs(
            cards, board)[0] / HoldemPoker.MAX_OUTS

        des = PokerDecision9()
        des.set_answer(res)
        des.probability_to_win = pr
        des.my_money = money
        des.money_in_pot = pot
        des.money_to_call = call
        des.big_blind = bb

        if step == Step.Preflop:
            des.is_preflop = 1
        elif step == Step.Flop:
            des.is_flop = 1
        elif step == Step.Turn:
            des.is_turn = 1
        elif step == Step.River:
            des.is_river = 1
        else:
            raise ValueError('bad step', step)

        int_strength: int = strength.value
        if int_strength < 0:
            raise ValueError('strength is < 0', int_strength, strength)
        des.strength[int_strength] = 1

        rank: int = cards.first.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.first.rank)
        des.first[rank] = 1

        rank: int = cards.second.rank.value - 2
        if rank < 0:
            raise ValueError('rank is < 0', rank, cards.second.rank)
        des.second[rank] = 1

        if cards.suitability == Suitability.Suited:
            des.have_suited_cards = 1

        if players_on_table < 2 or players_on_table > 10:
            raise ValueError('bad players on table:', players_active)

        if players_active < 2 or players_active > 10:
            raise ValueError('bad players active:', players_active)

        if players_active > players_on_table:
            raise ValueError('bad players active:', players_active,
                             'with players on table:', players_on_table)

        if players_not_moved < 0 or players_not_moved >= players_active:
            raise ValueError('bad players not moved:', players_not_moved,
                             'with players active:', players_active)

        des.players_on_table[players_on_table - 2] = 1
        des.players_playing[players_on_table - 2] = 1
        des.players_not_moved[players_not_moved] = 1

        des.outs = outs

        des.max_playing_stack = max_playing_stack
        des.average_stack_on_table = average_stack_on_table

        curr_raisers: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision9.CurrRaisers
        curr_callers: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision9.CurrCallers
        curr_folders: Dict[Tuple[str, PokerPosition],
                           PlayerStatistics] = PokerDecision9.CurrFolders
        curr_checkers: Dict[Tuple[str, PokerPosition],
                            PlayerStatistics] = PokerDecision9.CurrCheckers

        raisers = []
        callers = []
        folders = []
        checkers = []
        for player in players:
            if player.name not in folded_players:
                raisers += [
                    curr_raisers[player.name, player.position].get_stats()
                ]
                callers += [
                    curr_callers[player.name, player.position].get_stats()
                ]
                folders += [
                    curr_folders[player.name, player.position].get_stats()
                ]
                checkers += [
                    curr_checkers[player.name, player.position].get_stats()
                ]

        des.max_raiser = max(raisers)
        des.min_raiser = min(raisers)
        des.avg_raiser = mean(raisers)

        des.max_caller = max(callers)
        des.min_caller = min(callers)
        des.avg_caller = mean(callers)

        des.max_folder = max(folders)
        des.min_folder = min(folders)
        des.avg_folder = mean(folders)

        des.max_checker = max(checkers)
        des.min_checker = min(checkers)
        des.avg_checker = mean(checkers)

        des.my_position_is_early = my_position is PokerPosition.Early
        des.my_position_is_middle = my_position is PokerPosition.Middle
        des.my_position_is_late = my_position is PokerPosition.Late
        des.my_position_is_blinds = my_position is PokerPosition.Blinds

        return des