class Game: def __init__(self): pass BET = '0' CALL = '1' CHECK = '2' FOLD = '3' DECK = gen_deck() @staticmethod def deal_cards(): sample = random.sample(Game.DECK.deck, 4) player_one_cards = sample[0:2] player_two_cards = sample[2:4] # print "P1 Card 1: %s " % player_one_cards[0] # print "P1 Card 2: %s " % player_one_cards[1] # print "P2 Card 3: %s" % player_two_cards[0] # print "P2 Card 4: %s" % player_two_cards[1] return player_one_cards, player_two_cards @staticmethod def get_higher_rank(card1, card2): if card1.rank > card2.rank: return card1 return card2
def eval(self): """ Generates and checks only 1 card per meaningful outcome. Returns expected utility. i.e. Given a set of cards, get all the cards that have not been drawn. Check the outcome of the hand given the additional card. Outcomes can be ONEPAIR, FLUSH, etc. Only 1 permutation that gives that outcome is checked. """ # TODO: Optimise gen_hand_rank_info as there are currently alot of useless steps remaining_cards = gen_deck(exclude_cards=self.hole_cards + self.community_cards) n = remaining_cards.size() #Store the utility value given for that outcome memo = {} #Number of counts that generates the OUTCOME count = defaultdict(int) while remaining_cards.size() > 0: new_card = remaining_cards.draw_card() strength = HandEvaluator.gen_hand_rank_info( self.hole_cards, self.community_cards + [new_card])["hand"]["strength"] if strength not in memo: memo[strength] = DecisionNode( self.our_player, 0, self.hole_cards, self.community_cards + [new_card], self.pot, self.heuristic_weights, self.is_flop).eval() count[strength] += 1 #Return expected value return sum( [count[strength] * memo[strength] for strength in memo.keys()]) / n
def train(self, iterations, show_progress=True): """Run CFR for given number of iterations. The trained tree can be found by retrieving the game_tree property from this object. The result strategy is stored in average_strategy of each ActionNode in game tree. This method can be called multiple times on one instance to train more. This can be used for evaluation during training and to make number of training iterations dynamic. Args: iterations (int): Number of iterations. show_progress (bool): Show training progress bar. """ if not show_progress: iterations_iterable = range(iterations) else: try: iterations_iterable = tqdm(range(iterations)) iterations_iterable.set_description('CFR training') except NameError: iterations_iterable = range(iterations) for i in iterations_iterable: current_deck = gen_deck() current_deck.shuffle() self._cfr([self.game_tree] * self.player_count, [1] * self.player_count, None, [], current_deck, [False] * self.player_count) Cfr._calculate_tree_average_strategy(self.game_tree)
def sim_nature(nodes): root = nodes[0][0] deck = gen_deck() deck.shuffle() #deal hole = deck.draw_cards(2) wr = estimate_hole_card_win_rate(nb_simulation=N_TESTS, nb_player=2, hole_card=hole) deal_node = get_node(wr, nodes[1]) root.adjust_for(deal_node) comm = [] curr = deal_node i = 2 for comm_deal in [3, 1, 1]: comm = comm + deck.draw_cards(comm_deal) wr = estimate_hole_card_win_rate(nb_simulation=N_TESTS, nb_player=2, hole_card=hole, community_card=comm) _next = get_node(wr, nodes[i]) curr.adjust_for(_next) curr = _next i += 1
def test_gen_deck_without_some_card(self): expected = Deck(deck_ids=range(2, 52)) exclude_obj = [Card.from_id(1), Card.from_id(52)] exclude_str = [str(card) for card in exclude_obj] self.eq(expected.serialize(), U.gen_deck(exclude_obj).serialize()) self.eq(expected.serialize(), U.gen_deck(exclude_str).serialize())
def test_gen_deck(self): deck = U.gen_deck() self.eq(list(range(1, 53)), [card.to_id() for card in deck.deck])