def _shorten_pieces(self, pieces): if not pieces: return [] str_pieces = [] first = last = pieces[0] for current in pieces[1:]: if isinstance(last, Combo): str_pieces.append(str(last)) first = last = current elif isinstance(current, Combo): str_pieces.append(self._get_format(first, last)) first = last = current elif ( current.is_pair and Rank.difference(last.first, current.first) == 1 ) or ( last.first == current.first and Rank.difference(last.second, current.second) == 1 ): last = current else: str_pieces.append(self._get_format(first, last)) first = last = current # write out any remaining pieces str_pieces.append(self._get_format(first, last)) return str_pieces
def calc_hard_strategy(decks): shoe = Shoe(decks) rows = 10 cols = 10 bs_hard = [ [0] * cols for _ in range(rows)] #Hard table for row in range(0, rows): for col in range(0, cols): d_rank = Rank(col+1) if d_rank == 10: d_rank = Rank.Ace # player values 8 - 11 if row < 4: p1 = Card(Rank.Six, Suit.Spade) p2 = Card(Rank(row+1), Suit.Spade) # Player values 12 - 18 elif row >= 4: p1 = Card(Rank.Ten, Suit.Spade) p2 = Card(Rank(row-3), Suit.Spade) upcard = Card(d_rank, Suit.Spade) p_hand = Hand([p1,p2]) game = Game(p_hand, upcard, shoe) optimal = optimal_action(game) bs_hard[row][col] = optimal shoe.reset_shoe() print(DataFrame(bs_hard))
def calc_split_strategy(decks): # Split Table shoe = Shoe(8) rows = 9 cols = 10 bs_split = [ [0] * cols for _ in range(rows)] for row in range(0, rows): for col in range(0, cols): assert(shoe.cards_in_shoe == 52*shoe.DECKS) d_rank = Rank(col+1) p_rank = Rank(row+1) if d_rank == 10: d_rank = Rank.Ace if p_rank == 10: p_rank = Rank.Ace p1 = Card(p_rank, Suit.Spade) p2 = Card(p_rank, Suit.Spade) p_hand = Hand([p1,p2]) upcard = Card(d_rank, Suit.Spade) game = Game(p_hand, upcard, shoe) optimal = optimal_action(game) shoe.reset_shoe() bs_split[row][col] = optimal print(DataFrame(bs_split))
def calc_soft_strategy(decks): shoe = Shoe(decks) rows = 7 # S13 - S19 cols = 10 bs_soft = [ [0] * cols for _ in range(rows)] #Soft Table for row in range(0, rows): for col in range(0, cols): assert(shoe.cards_in_shoe == 52*shoe.DECKS) d_rank = Rank(col+1) # dealer's up card rank if d_rank == 10: d_rank = Rank.Ace upcard = Card(d_rank, Suit.Spade) p1 = Card(Rank.Ace, Suit.Spade) p2 = Card(Rank(row+1), Suit.Spade) p_hand = Hand([p1,p2]) game = Game(p_hand, upcard, shoe) optimal = optimal_action(game) bs_soft[row][col] = optimal shoe.reset_shoe() print(DataFrame(bs_soft))
def make_random(cls): obj = object.__new__(cls) first = Rank.make_random() second = Rank.make_random() obj._set_ranks_in_order(first, second) if first == second: obj._shape = "" else: obj._shape = random.choice(["s", "o"]) return obj
def run(self): for x in range(10000): print(f"*** Hand {self.sims+1}***") self.sims += 1 print(self.p1) print(self.p2) self.p1.bet() self.p2.bet() self.deal_cards() while not self.p1.is_done() or not self.p2.is_done(): card = Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade) action_b = strategy.infinite_basic_action( self.p1.hand, self.dealer) action_c = strategy.infinite_complete_action( self.p2.hand, self.dealer) self.p1.process_action(action_b, card) self.p2.process_action(action_c, card) self.dealer.playout_hand() self.p1.payout(self.dealer.hand) self.p2.payout(self.dealer.hand) self.dealer.reset() self.shoe.reset_shoe( ) # why am I reseting shoe everytime yet still calculating deal probs every hand? print("\n")
def playout_dealer(self): # Assumes infinite deck while self.hand.sum < self.stand_min: card = Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade) self.hand.add_card(card) return self.hand.sum
def random_hand(self, size): cards = [] for _ in range(size): card = Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade) cards.append(card) self.shoe.draw(card) return Hand(cards)
def _get_format(self, first, last): if first == last: return str(first) elif ( first.is_pair and first.first.val == "A" or Rank.difference(first.first, first.second) == 1 ): return f"{last}+" elif last.second.val == "2": return f"{first}-" else: return f"{first}-{last}"
def Flush_Collection(self): Flush_dict = self.Flush() Flush_Collection_tail = { 'suit_c': [], 'suit_d': [], 'suit_h': [], 'suit_s': [] } for c in ['c', 'd', 'h', 's']: color_num = self.color_dict['suit_' + c] if (color_num >= 5): item_sum = 1 for item in range(1, color_num): if (Rank.difference(Flush_dict['suit_' + c][item], Flush_dict['suit_' + c][item - 1])) == 1: item_sum += 1 else: item_sum = 0 if (item_sum >= 5): Flush_Collection_tail['suit_' + c].append( Flush_dict['suit_' + c][item]) return Flush_Collection_tail
def test_get_notation_3(): card = Card(Suit('♠'), Rank('2'))
def deal_cards(self): players_hand = self.random_hand(2) self.p1.add_hand(players_hand) self.p2.add_hand(deepcopy(players_hand)) self.dealer.deal_card( Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade))
def test_invalid_rank(self): self.assertRaises(RuntimeError, Card, Suit.clubs, -1) self.assertRaises(RuntimeError, Card, Suit.clubs, Rank.count())
def _create_deck(self): for i in range(0, 4): for j in range(2, 15): self.cards.append(Card(Suit(i), Rank(j)))
def judge_right(res_one, res_two, res_three, shape_1, shape_2, shape_3): if (shape_1 == str(2) or shape_1 == str(3)): return False if (shape_3 == str(0)): for i in range(5): for j in range(5): if (i != j and res_three[i].rank == res_three[j].rank): return False if (shape_2 == str(0)): for i in range(5): for j in range(5): if (i != j and res_two[i].rank == res_two[j].rank): return False if (shape_1 == str(0)): for i in range(3): for j in range(3): if (i != j and res_one[i].rank == res_one[j].rank): return False if (shape_3 == str(1)): pair_num = 0 for i in res_three: for j in res_three: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 2): return False if (shape_2 == str(1)): pair_num = 0 for i in res_two: for j in res_two: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 2): return False if (shape_1 == str(1)): pair_num = 0 for i in res_one: for j in res_one: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 2): return False if (shape_3 == str(2) or shape_3 == str(3)): pair_num = 0 for i in res_three: for j in res_three: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 4): return False pair_one = '' pair_two = '' for i in res_three: for j in res_three: if (pair_one == '' and i != j and i.rank == j.rank): pair_one = i.rank elif (pair_one != '' and i != j and i.rank == j.rank and i.rank != pair_one): pair_two = i.rank if (shape_3 == str(2) and Rank.difference(pair_one, pair_two) == 1): return False if (shape_2 == str(2) or shape_2 == str(3)): pair_num = 0 for i in res_two: for j in res_two: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 4): return False pair_one = '' pair_two = '' for i in res_two: for j in res_two: if (pair_one == '' and i != j and i.rank == j.rank): pair_one = i.rank elif (pair_one != '' and i != j and i.rank == j.rank and i.rank != pair_one): pair_two = i.rank if (shape_2 == str(2) and Rank.difference(pair_one, pair_two) == 1): return False if (shape_3 == str(4)): pair_num = 0 for i in res_three: for j in res_three: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 6): return False if (shape_2 == str(4)): pair_num = 0 for i in res_two: for j in res_two: if (i != j and i.rank == j.rank): pair_num += 1 if (pair_num != 6): return False if (shape_1 == str(4)): if (res_one[0].rank != res_one[1].rank or res_one[1].rank != res_one[2].rank or res_one[1].rank != res_one[0].rank): return False flag_reward = Compare_up(3, res_three, res_two, shape_3, shape_2) if (flag_reward < 0): return False flag_reward = Compare_gap(res_two, res_one, shape_2, shape_1) if (flag_reward < 0): return False return True
def choose_step_sb(choose_): Collection_tail = choose_['Collection_tail'] Flush_dict = choose_['Flush_dict'] Flush_Collection_tail = choose_['Flush_Collection_tail'] Three_dict = choose_['Three_dict'] Gourd_dict = choose_['Gourd_dict'] Bomb_dict = choose_['Bomb_dict'] Pair_dict = choose_['Pair_dict'] shape_dict = { '0': [0, []], '1': [0, []], '2': [0, []], '3': [0, []], '4': [0, []], '5': [0, []], '6': [0, []], '7': [0, []], '8': [0, []], '9': [0, []] } for i in Flush_Collection_tail: if (Flush_Collection_tail[i] != []): for j in Flush_Collection_tail[i]: shape_dict[str(9)][0] = 1 shape_dict[str(9)][1].append((str(j), str(i))) for i in reversed(rank_list): if (Bomb_dict[str(i)] != 0): shape_dict[str(8)][0] = 1 shape_dict[str(8)][1].append((str(i), '')) for i in reversed(rank_list): if (Gourd_dict[str(i)] != []): shape_dict[str(7)][0] = 1 shape_dict[str(7)][1].append((str(i), str(Gourd_dict[str(i)][0]))) for i in Flush_dict: if (Flush_dict[i] != []): for j in Flush_dict[i]: shape_dict[str(6)][0] = 1 shape_dict[str(6)][1].append((str(j), str(i))) if (Collection_tail != []): shape_dict[str(5)][0] = 1 shape_dict[str(5)][1].append((str(Collection_tail[-1]), '')) for i in reversed(rank_list): if (Three_dict[str(i)] != 0): shape_dict[str(4)][0] = 1 shape_dict[str(4)][1].append((str(i), '')) pair_num = 0 for i in reversed(rank_list): if (Pair_dict[str(i)] != 0): if (pair_num == 0): pair_one = str(i) pair_num += 1 elif ( pair_num == 1 and (rank_list.index(i) - rank_list.index(Rank(pair_one)) == -1)): pair_two = str(i) shape_dict[str(3)][0] = 1 shape_dict[str(3)][1].append((str(pair_one), str(pair_two))) pair_num = 0 for i in reversed(rank_list): if (Pair_dict[str(i)] != 0): if (pair_num == 0): pair_one = str(i) pair_num += 1 continue elif (pair_num == 1): pair_two = str(i) shape_dict[str(2)][0] = 1 shape_dict[str(2)][1].append((str(pair_one), str(pair_two))) for i in reversed(rank_list): if (Pair_dict[str(i)] != 0): shape_dict[str(1)][0] = 1 shape_dict[str(1)][1].append((str(i), '')) shape_dict[str(0)][0] = 1 shape_dict[str(0)][1].append(('', '')) return shape_dict
def _set_ranks_in_order(self, first, second): # set as Rank objects. self.first, self.second = Rank(first), Rank(second) if self.first < self.second: self.first, self.second = self.second, self.first
def rank_difference(self): """The difference between the first and second rank of the Combo.""" # self.first >= self.second return Rank.difference(self.first.rank, self.second.rank)
def _get_rank_in_order(token, first_part, second_part): first, second = Rank(token[first_part]), Rank(token[second_part]) smaller, bigger = min(first, second), max(first, second) return smaller, bigger
def test_rank_count(self): self.assertEqual(Rank.count(), 13, 'A card must have 13 ranks')
def __init__(self, range=""): self._hands = set() self._combos = set() for name, value in _RegexRangeLexer(range): if name == "ALL": for card in itertools.combinations("AKQJT98765432", 2): self._add_offsuit(card) self._add_suited(card) for rank in "AKQJT98765432": self._add_pair(rank) # full range, no need to parse any more name break elif name == "PAIR": self._add_pair(value) elif name == "PAIR_PLUS": smallest = Rank(value) for rank in (rank.val for rank in Rank if rank >= smallest): self._add_pair(rank) elif name == "PAIR_MINUS": biggest = Rank(value) for rank in (rank.val for rank in Rank if rank <= biggest): self._add_pair(rank) elif name == "PAIR_DASH": first, second = Rank(value[0]), Rank(value[1]) ranks = (rank.val for rank in Rank if first <= rank <= second) for rank in ranks: self._add_pair(rank) elif name == "BOTH": self._add_offsuit(value[0] + value[1]) self._add_suited(value[0] + value[1]) elif name == "X_BOTH": for rank in (r.val for r in Rank if r < Rank(value)): self._add_suited(value + rank) self._add_offsuit(value + rank) elif name == "OFFSUIT": self._add_offsuit(value[0] + value[1]) elif name == "SUITED": self._add_suited(value[0] + value[1]) elif name == "X_OFFSUIT": biggest = Rank(value) for rank in (rank.val for rank in Rank if rank < biggest): self._add_offsuit(value + rank) elif name == "X_SUITED": biggest = Rank(value) for rank in (rank.val for rank in Rank if rank < biggest): self._add_suited(value + rank) elif name == "BOTH_PLUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if smaller <= rank < bigger): self._add_suited(value[1] + rank) self._add_offsuit(value[1] + rank) elif name == "BOTH_MINUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if rank <= smaller): self._add_suited(value[1] + rank) self._add_offsuit(value[1] + rank) elif name in ("X_PLUS", "X_SUITED_PLUS", "X_OFFSUIT_PLUS"): smallest = Rank(value) first_ranks = (rank for rank in Rank if rank >= smallest) for rank1 in first_ranks: second_ranks = (rank for rank in Rank if rank < rank1) for rank2 in second_ranks: if name != "X_OFFSUIT_PLUS": self._add_suited(rank1.val + rank2.val) if name != "X_SUITED_PLUS": self._add_offsuit(rank1.val + rank2.val) elif name in ("X_MINUS", "X_SUITED_MINUS", "X_OFFSUIT_MINUS"): biggest = Rank(value) first_ranks = (rank for rank in Rank if rank <= biggest) for rank1 in first_ranks: second_ranks = (rank for rank in Rank if rank < rank1) for rank2 in second_ranks: if name != "X_OFFSUIT_MINUS": self._add_suited(rank1.val + rank2.val) if name != "X_SUITED_MINUS": self._add_offsuit(rank1.val + rank2.val) elif name == "COMBO": self._combos.add(Combo(value)) elif name == "OFFSUIT_PLUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if smaller <= rank < bigger): self._add_offsuit(value[1] + rank) elif name == "OFFSUIT_MINUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if rank <= smaller): self._add_offsuit(value[1] + rank) elif name == "SUITED_PLUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if smaller <= rank < bigger): self._add_suited(value[1] + rank) elif name == "SUITED_MINUS": smaller, bigger = Rank(value[0]), Rank(value[1]) for rank in (rank.val for rank in Rank if rank <= smaller): self._add_suited(value[1] + rank) elif name == "BOTH_DASH": smaller, bigger = Rank(value[1]), Rank(value[2]) for rank in (rank.val for rank in Rank if smaller <= rank <= bigger): self._add_offsuit(value[0] + rank) self._add_suited(value[0] + rank) elif name == "OFFSUIT_DASH": smaller, bigger = Rank(value[1]), Rank(value[2]) for rank in (rank.val for rank in Rank if smaller <= rank <= bigger): self._add_offsuit(value[0] + rank) elif name == "SUITED_DASH": smaller, bigger = Rank(value[1]), Rank(value[2]) for rank in (rank.val for rank in Rank if smaller <= rank <= bigger): self._add_suited(value[0] + rank)