Beispiel #1
0
 def check(m):
     p = game.get_player(m.author)
     verify_context = p is not None and m.channel == p.channel and p in game.turn
     command = m.content.split()
     verify_message = len(command) == 3 and command[0] == "$declare"
     if verify_context and verify_message:
         # make sure the number is equal to submission amount
         verify_numbers = True
         try:
             command[1] = int(command[1])
             if command[1] != len(p.submit):
                 verify_numbers = False
         except ValueError:
             verify_numbers = False
         # check that the card exists and is legal
         verify_cards = False
         global cards
         if command[2] in cards:
             if cards[command[2]]["type"] == "legal":
                 verify_cards = True
         if verify_numbers and verify_cards:
             game.turn.remove(p)
             for i in range(command[1]):
                 p.declare.append(
                     Card(cards[command[2]]["name"],
                          cards[command[2]]["value"],
                          cards[command[2]]["penalty"],
                          cards[command[2]]["type"]))
     return len(game.turn) == 0
Beispiel #2
0
def build_deck(con, deck_list, deck):
    for card in deck_list:
        card_record = db_utils.find_card(con, card[0])
        if card_record is not None:
            card_data = {
                'name': card_record[0],
                'cmc': card_record[1],
                'mana_cost': card_record[2],
                'type_line': card_record[3]
            }
            my_card = Card(card_data)
        else:
            card_data = requests.get(
                'https://api.scryfall.com/cards/named?fuzzy=' +
                card[0]).json()
            my_card = Card(card_data)
            db_utils.insert_card(con, Card(card_data))

        for _ in range(int(card[1])):
            deck.add_card(my_card)
        sleep(0.1)  # scryfall wants api requests limited to 10/sec
Beispiel #3
0
def test_two_trips():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('H', 12)
    sesh.players[0].hand[1] = Card('C', 12)
    sesh.players[1].hand[0] = Card('H', 2)
    sesh.players[1].hand[1] = Card('D', 13)
    sesh.community_cards[0] = Card('D', 12)
    sesh.community_cards[1] = Card('D', 8)
    sesh.community_cards[2] = Card('C', 8)
    sesh.community_cards[3] = Card('S', 8)
    sesh.community_cards[4] = Card('C', 11)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.FULL_HOUSE
    assert res[sesh.players[0]][1] == [12, 12, 12, 8, 8]
Beispiel #4
0
def test_royal_flush_2():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('D', 10)
    sesh.players[0].hand[1] = Card('D', 12)
    sesh.players[1].hand[0] = Card('C', 8)
    sesh.players[1].hand[1] = Card('C', 9)
    sesh.community_cards[0] = Card('D', 14)
    sesh.community_cards[1] = Card('D', 11)
    sesh.community_cards[2] = Card('C', 10)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('D', 13)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.ROYAL_FLUSH
    assert res[sesh.players[0]][1] == [14, 13, 12, 11, 10]
    assert res[sesh.players[1]][0] == HandVal.STRAIGHT
    assert res[sesh.players[1]][1] == [11, 10, 9, 8, 7]
Beispiel #5
0
def test_straight_flush_2():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('D', 10)
    sesh.players[0].hand[1] = Card('D', 8)
    sesh.players[1].hand[0] = Card('C', 6)
    sesh.players[1].hand[1] = Card('C', 2)
    sesh.community_cards[0] = Card('C', 3)
    sesh.community_cards[1] = Card('C', 4)
    sesh.community_cards[2] = Card('C', 5)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('C', 10)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.PAIR
    assert res[sesh.players[0]][1] == [10, 10, 8, 7, 5]
    assert res[sesh.players[1]][0] == HandVal.STRAIGHT_FLUSH
    assert res[sesh.players[1]][1] == [6, 5, 4, 3, 2]
Beispiel #6
0
def test_ace_high_straight():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('S', 14)
    sesh.players[0].hand[1] = Card('C', 2)
    sesh.players[1].hand[0] = Card('D', 10)
    sesh.players[1].hand[1] = Card('D', 8)
    sesh.community_cards[0] = Card('S', 13)
    sesh.community_cards[1] = Card('D', 12)
    sesh.community_cards[2] = Card('C', 11)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('C', 10)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.STRAIGHT
    assert res[sesh.players[0]][1] == [14, 13, 12, 11, 10]
    assert res[sesh.players[1]][0] == HandVal.PAIR
    assert res[sesh.players[1]][1] == [10, 10, 13, 12, 11]
Beispiel #7
0
def test_three_pairs2():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('H', 12)
    sesh.players[0].hand[1] = Card('C', 13)
    sesh.players[1].hand[0] = Card('C', 10)
    sesh.players[1].hand[1] = Card('S', 10)
    sesh.community_cards[0] = Card('H', 8)
    sesh.community_cards[1] = Card('S', 13)
    sesh.community_cards[2] = Card('C', 8)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('C', 11)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.TWO_PAIR
    assert res[sesh.players[0]][1] == [13, 13, 8, 8, 12]
    assert res[sesh.players[1]][0] == HandVal.TWO_PAIR
    assert res[sesh.players[1]][1] == [10, 10, 8, 8, 13]
Beispiel #8
0
def test_pockets():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('H', 12)
    sesh.players[0].hand[1] = Card('S', 12)
    sesh.players[1].hand[0] = Card('C', 10)
    sesh.players[1].hand[1] = Card('S', 10)
    sesh.community_cards[0] = Card('H', 9)
    sesh.community_cards[1] = Card('S', 4)
    sesh.community_cards[2] = Card('C', 8)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('C', 13)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.PAIR
    assert res[sesh.players[0]][1] == [12, 12, 13, 9, 8]
    assert res[sesh.players[1]][0] == HandVal.PAIR
    assert res[sesh.players[1]][1] == [10, 10, 13, 9, 8]
Beispiel #9
0
def test_flush_1():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('H', 12)
    sesh.players[0].hand[1] = Card('S', 13)
    sesh.players[1].hand[0] = Card('D', 3)
    sesh.players[1].hand[1] = Card('D', 2)

    sesh.community_cards[0] = Card('H', 10)
    sesh.community_cards[1] = Card('C', 10)
    sesh.community_cards[2] = Card('D', 5)
    sesh.community_cards[3] = Card('D', 7)
    sesh.community_cards[4] = Card('D', 12)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.TWO_PAIR
    assert res[sesh.players[0]][1] == [12, 12, 10, 10, 13]
    assert res[sesh.players[1]][0] == HandVal.FLUSH
    assert res[sesh.players[1]][1] == [12, 7, 5, 3, 2]
Beispiel #10
0
    def _compute_streak_frequency(self, handcounts, kickers,
                                  sorted_cards) -> None:
        if sorted_cards[-1].value == 14:  #count ace as lowest and highest
            sorted_cards.insert(0, Card(sorted_cards[-1].suit, 1))
            self.log.debug(f'sorted cards post ace insert: {sorted_cards}')
        prev_num = -1
        suit_streak = 0
        streak = 1
        prev_suit = [sorted_cards[0].suit]
        for card in sorted_cards:
            self.log.debug(f'\ncard: {card}')
            if prev_num + 1 == card.value:
                streak += 1
                for suit in prev_suit:
                    if suit == card.suit:
                        suit_streak = suit_streak + 1
                        prev_suit = [suit]
                        break
                    suit_streak = 1
            elif prev_num == card.value:
                streak = streak
                suit_streak = suit_streak
                prev_suit.append(card.suit)
            else:
                streak = 1
                suit_streak = 1
                prev_suit = [card.suit]

            self.log.debug(f'value streak: {streak} ')
            self.log.debug(f'suit streak: {suit_streak}')
            self.log.debug(f'prev suit: {prev_suit}')
            prev_num = card.value
            if streak >= 5 and suit_streak >= 5:
                if card.value == 14:
                    self.log.info(f'{card.suit} royal flush!')
                    kickers[HandVal.ROYAL_FLUSH] = [14, 13, 12, 11, 10]
                    handcounts[HandVal.ROYAL_FLUSH] = 1
                else:
                    self.log.info(f'{card}-high straight flush!')
                range_ = reversed(range(card.value - 4, card.value + 1))
                kickers[HandVal.STRAIGHT_FLUSH] = [i for i in range_]
                handcounts[HandVal.STRAIGHT_FLUSH] = 1
            elif streak >= 5:
                self.log.debug(f'{card}-high straight!')
                handcounts[HandVal.STRAIGHT] = 1
                range_ = reversed(range(card.value - 4, card.value + 1))
                kickers[HandVal.STRAIGHT] = [i for i in range_]
Beispiel #11
0
def test_high_card():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('H', 12)
    sesh.players[0].hand[1] = Card('S', 14)

    sesh.players[1].hand[0] = Card('C', 2)
    sesh.players[1].hand[1] = Card('D', 6)

    sesh.community_cards[0] = Card('D', 10)
    sesh.community_cards[1] = Card('S', 9)
    sesh.community_cards[2] = Card('C', 5)
    sesh.community_cards[3] = Card('D', 3)
    sesh.community_cards[4] = Card('C', 13)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.HIGH_CARD
    assert res[sesh.players[0]][1] == [14, 13, 12, 10, 9]
    assert res[sesh.players[1]][0] == HandVal.HIGH_CARD
    assert res[sesh.players[1]][1] == [13, 10, 9, 6, 5]
Beispiel #12
0
def test_ace_low_straight():
    sesh = Session(LOGGER, player_count=2)
    players = ['player1', 'player2']
    for i, player in enumerate(players):
        sesh.players[i].name = player
    sesh.setup_game()
    sesh.players[0].hand[0] = Card('S', 14)
    sesh.players[0].hand[1] = Card('C', 2)
    sesh.players[1].hand[0] = Card('D', 10)
    sesh.players[1].hand[1] = Card('D', 8)
    sesh.community_cards[0] = Card('S', 3)
    sesh.community_cards[1] = Card('D', 4)
    sesh.community_cards[2] = Card('C', 5)
    sesh.community_cards[3] = Card('D', 9)
    sesh.community_cards[4] = Card('C', 10)
    res = sesh.get_best_hands()
    assert res[sesh.players[0]][0] == HandVal.STRAIGHT
    for i in reversed(range(2, 6)):
        assert res[sesh.players[0]][1][5 - i] == i
    assert res[sesh.players[0]][1][-1] == 1  #ace
    assert res[sesh.players[1]][0] == HandVal.PAIR
    assert res[sesh.players[1]][1] == [10, 10, 9, 8, 5]
Beispiel #13
0
def find_deck_cards(con, deck):
    sql = """
        SELECT ac.name, ac.cmc, ac.mc, ac.type, dc.count FROM deck_cards dc
        JOIN all_cards ac ON dc.card_name = ac.name
        WHERE dc.deck_id = ?
    """
    cur = con.cursor()
    cur.execute(sql, [deck.id])
    res = cur.fetchall()
    for r in res:
        card_data = {
            'name': r[0],
            'cmc': r[1],
            'mana_cost': r[2],
            'type_line': r[3]
        }
        my_card = Card(card_data)
        for _ in range(r[4]):
            deck.add_card(my_card)
def main():
    print("Cards - Tester")
    print()

    #test sorting of the cards
    testcardsList = [
        Card("Spades", "Ace"),
        Card("Hearts", "Queen"),
        Card("Clubs", "10"),
        Card("Diamonds", "3"),
        Card("Hearts", "Jack"),
        Card("Spades", "7")
    ]
    testcardsList.sort()
    print("TEST CARDS LIST AFTER SORTING.")
    for c in testcardsList:
        print(c)
    print()

    # test deck
    print("DECK")
    deck = Deck()
    print("Deck created.")
    deck.shuffle()
    print("Deck shuffled.")
    print("Deck count:", len(deck))
    print()

    # test hand
    hand = Hand()
    for i in range(10):
        hand.addCard(deck.dealCard())

    print("SORTED HAND")
    for c in sorted(hand):
        print(c)

    print()
    print("Hand points:", hand.points)
    print("Hand count:", len(hand))
    print("Deck count:", len(deck))
Beispiel #15
0
class Session:
    """
    The Session class of a poker game.
    The Session is responsible for encapsulating the logic and rules of the game.

    === Attributes ===
    log: logger object used to record various session debugging information.
    community_cards: list holding the comunity cards of a given game.
        community cards are 5 cards that every player can use in conjunction
        with their hole cards (hand) to make the best possible combination.
    deck: standard deck of 52 cards stored in a deque.
    players: list of Player objects taking part in the session.

    === Representation Invariants ===
    len(deck) == 52
    len(players) > 1
    """
    ALL_CARDS = []
    for i in range(1, 14):
        for suit in SUITS:
            ALL_CARDS.append(Card(suit, i))
    POSSIBLE_TABLES = list(itertools.combinations(ALL_CARDS, 5))

    def __init__(self, log, player_count=2):
        self.log = log
        self.log.info('New session started.')
        self.community_cards = []
        self.deck = deque(self.ALL_CARDS)
        self.players = []
        for i in range(player_count):
            self.players.append(Player(position=i))

    def compute_game_outcome(self):
        """returns the player who won the current game."""
        pass

    def log_state(self) -> None:
        """Logs the current game state (player hands and community cards)."""
        for player in self.players:
            self.log.info(f"{player.name}'s hand: {player.hand}")
        self.log.info(f"Community Cards: {self.community_cards}")

    def setup_game(self):
        """starts a new game by resetting appropriate Session attributes."""
        self.community_cards = []
        self.log.info('shuffling...')
        self.deck = deque(self.ALL_CARDS)
        shuffle(self.deck)
        for player in self.players:
            player.hand = []
            player.hand.append(self.deck.pop())
            player.hand.append(self.deck.pop())
        for _ in range(5):
            self.community_cards.append(self.deck.pop())

    def _compute_flush_frequency(self, handcounts, suitcounts, kickers,
                                 sorted_cards) -> None:
        for suit, freq in suitcounts.items():
            if freq >= 5:
                handcounts[HandVal.FLUSH] += 1
                self.log.info(f'flush!')
                inc = 0
                self.log.debug(sorted_cards[::-1])
                for card_ in sorted_cards[::-1]:
                    if card_.suit == suit:
                        kickers[HandVal.FLUSH][inc] = card_.value
                        inc += 1
                    if inc == 5:
                        break

    def _compute_pair_frequency(self, handcounts, suitcounts, kickers,
                                sorted_cards) -> None:
        """Computes the frequencies of pairs, trips, quads and full houses.
           Categorizes kickers based on hand-appropriate logic.
        """
        # check for pair, trips and quads
        counted = []
        for base_card in sorted_cards:
            suitcounts[base_card.suit] += 1
            val_count = 1
            #create copy of list with base card removed
            without_base = [x for x in sorted_cards if x != base_card]
            for card in without_base:
                if base_card.value == card.value and base_card not in counted:
                    val_count += 1
                    counted.append(card)

            if val_count == 2:
                start = handcounts[HandVal.PAIR] * 2
                end = start + 2
                kickers[HandVal.PAIR][start:end] = [base_card.value] * 2
                handcounts[HandVal.PAIR] += 1
                self.log.debug(f'pair kickers: {kickers[HandVal.PAIR]}')
                self.log.info(f"pair!")
            elif val_count == 3:
                start = handcounts[HandVal.TRIPS] * 3
                end = start + 3
                handcounts[HandVal.TRIPS] += 1
                kickers[HandVal.TRIPS][start:end] = [base_card.value] * 3
                self.log.info(f'trips!')
            elif val_count == 4:
                kickers[HandVal.QUADS][0:4] = base_card.value
                handcounts[HandVal.QUADS] += 1
                self.log.info(f'quads!')

        if handcounts[HandVal.PAIR] > 1:
            handcounts[HandVal.TWO_PAIR] += 1
            kickers[HandVal.TWO_PAIR] = sorted(kickers[HandVal.PAIR])[::-1]
            if handcounts[HandVal.PAIR] > 2:
                self.log.debug(f'more than two pairs.')
                self.log.debug(
                    f'kickers pre-insertion: {kickers[HandVal.TWO_PAIR]}')
                kickers[HandVal.TWO_PAIR] = kickers[HandVal.TWO_PAIR][:4] + [0]
                self.log.debug(
                    f'kickers post-insertion: {kickers[HandVal.TWO_PAIR]}')
            self.log.info(f'two pair!')
            self.log.debug(f'two pair kickers: {kickers[HandVal.TWO_PAIR]}')

    def _compute_full_house_frequency(self, handcounts, kickers):
        if handcounts[HandVal.PAIR] >= 1 and handcounts[HandVal.TRIPS] >= 1:
            handcounts[HandVal.FULL_HOUSE] += 1
            kickers[HandVal.FULL_HOUSE][:3] = kickers[HandVal.TRIPS][:3]
            kickers[HandVal.FULL_HOUSE][3:] = kickers[HandVal.PAIR][:2]
            self.log.info(f'full house!')
        if handcounts[HandVal.TRIPS] >= 2:
            handcounts[HandVal.FULL_HOUSE] += 1
            kickers[HandVal.FULL_HOUSE] = sorted(
                kickers[HandVal.TRIPS])[:-6:-1]
            self.log.info(f'two trips and full house!')

    def _compute_streak_frequency(self, handcounts, kickers,
                                  sorted_cards) -> None:
        if sorted_cards[-1].value == 14:  #count ace as lowest and highest
            sorted_cards.insert(0, Card(sorted_cards[-1].suit, 1))
            self.log.debug(f'sorted cards post ace insert: {sorted_cards}')
        prev_num = -1
        suit_streak = 0
        streak = 1
        prev_suit = [sorted_cards[0].suit]
        for card in sorted_cards:
            self.log.debug(f'\ncard: {card}')
            if prev_num + 1 == card.value:
                streak += 1
                for suit in prev_suit:
                    if suit == card.suit:
                        suit_streak = suit_streak + 1
                        prev_suit = [suit]
                        break
                    suit_streak = 1
            elif prev_num == card.value:
                streak = streak
                suit_streak = suit_streak
                prev_suit.append(card.suit)
            else:
                streak = 1
                suit_streak = 1
                prev_suit = [card.suit]

            self.log.debug(f'value streak: {streak} ')
            self.log.debug(f'suit streak: {suit_streak}')
            self.log.debug(f'prev suit: {prev_suit}')
            prev_num = card.value
            if streak >= 5 and suit_streak >= 5:
                if card.value == 14:
                    self.log.info(f'{card.suit} royal flush!')
                    kickers[HandVal.ROYAL_FLUSH] = [14, 13, 12, 11, 10]
                    handcounts[HandVal.ROYAL_FLUSH] = 1
                else:
                    self.log.info(f'{card}-high straight flush!')
                range_ = reversed(range(card.value - 4, card.value + 1))
                kickers[HandVal.STRAIGHT_FLUSH] = [i for i in range_]
                handcounts[HandVal.STRAIGHT_FLUSH] = 1
            elif streak >= 5:
                self.log.debug(f'{card}-high straight!')
                handcounts[HandVal.STRAIGHT] = 1
                range_ = reversed(range(card.value - 4, card.value + 1))
                kickers[HandVal.STRAIGHT] = [i for i in range_]

    def _compute_result(self, player) -> Tuple[HandVal, List[int]]:
        empties = [[0 for _ in range(5)] for k in enumerate(HandVal)]
        kickers = dict(zip(HandVal, empties))
        cards = player.hand + self.community_cards
        handcounts = dict(zip(HandVal, [0 for i in enumerate(HandVal)]))
        suitcounts = dict(zip(SUITS, [0 for i in enumerate(SUITS)]))

        sorted_cards = sorted(cards, key=lambda card: card.value)
        self.log.debug(f'sorted cards: {sorted_cards}')
        self._compute_pair_frequency(handcounts, suitcounts, kickers,
                                     sorted_cards)
        self._compute_flush_frequency(handcounts, suitcounts, kickers,
                                      sorted_cards)
        self._compute_full_house_frequency(handcounts, kickers)
        self._compute_streak_frequency(handcounts, kickers, sorted_cards)

        handcounts[HandVal.HIGH_CARD] = 1
        for hand, freq in handcounts.items():
            self.log.debug(f"{hand}:{freq}")
            if freq > 0:
                #fill  kicker with highcards as required
                num_needed = kickers[hand].count(0)
                if num_needed > 0:
                    high_cards = copy(sorted_cards[::-1])
                    high_cards = [
                        card.value for card in high_cards
                        if card.value not in kickers[hand]
                    ]
                    kickers[hand][-num_needed:] = high_cards[:num_needed]
                return (hand, kickers[hand])
            return None  #never happens, makes linter happy

    def get_best_hands(self):
        """returns the best hand each player holds.
           the kickers sorted from most to least relevant.
        """
        results = {}
        for player in self.players:
            results[player] = self._compute_result(player)

        return results
Beispiel #16
0
def main():
    print("Blackjack\n")
    print("Blackjack payout is 3:2\n")
    money = 0.0
    start = datetime.now()
    print("Start time: " + start.strftime("%I:%M:%S %p"))
    result = lc.setlocale(lc.LC_ALL, "")
    if result == "C":
        lc.setlocale(lc.LC_ALL, "en_US")

    while True:
        player = 0
        dealer = 0
        dealerHand = []
        playerHand = []

        card = Card()
        deck = Deck(card.getSuits(), card.getRanks())
        deck.shuffle()

        d = deck.getDeck()

        number = random.randint(0, len(d))

        # shows player money, lets them bet and ends if no money
        money = Money()
        money = money.getMoney()
        if money < 5:
            choice = input("Buy more chips? (y/n): ")
            if choice == "y":
                chips = float(input("Enter amount: "))
            elif choice == "n":
                break
        localeMoney = Decimal(money)
        localeMoney = localeMoney.quantize(Decimal("1.00"))
        print("Money: " + lc.currency(localeMoney, grouping=True))
        bet = float(input("Bet amount: "))
        if bet < 5:
            print("Bet must be greater than $5")
            break
        elif bet > 1000:
            print("Bet must be less than $1000")
            break

        # shows dealer card and adds it to dealerHand
        print("DEALER'S SHOW CARD:")
        print(str(d[number][0]) + " of " + d[number][1])
        dealer += cardCount(d[number][0])
        dealerHand.append(d[number])
        d.pop(number)
        print()

        # shows player's cards and adds them to playerHand
        print("YOUR CARDS:")
        for x in range(2):
            number = random.randint(0, len(d))
            print(str(d[number][0]) + " of " + d[number][1])
            player += cardCount(d[number][0])
            playerHand.append(d[number])
            d.pop(number)
        print()

        # determines if blackjack, if not, then player has a chance to hit or stand before dealer
        if dealer == 21:
            print("Dealer blackjack!")
        elif player == 21:
            print("Player blackjack")
        elif player < 21:
            choice = input("Hit or stand? (hit/stand): ")
            print()
            while player < 21 and choice == "hit":
                number = random.randint(0, len(d))
                playerHand.append(d[number])
                player += cardCount(d[number][0])
                d.pop(number)
                print("YOUR CARDS:")
                for x in playerHand:
                    print(str(x[0]) + " of " + x[1])
                print()
                if player > 21:
                    break

                choice = input("Hit or stand? (hit/stand): ")

            # Makes dealer draw cards until they have 17 points or until dealer has more points
            while dealer < 17:
                number = random.randint(0, len(d))
                dealerHand.append(d[number])
                dealer += cardCount(d[number][0])

            while dealer < player:
                number = random.randint(0, len(d))
                dealerHand.append(d[number])
                dealer += cardCount(d[number][0])

            # displays both hands and results
            print("DEALER'S CARDS:")
            for x in dealerHand:
                print(str(x[0]) + " of " + x[1])

            print()
            print("YOUR POINTS:\t  " + str(player))
            print("DEALER'S POINTS:  " + str(dealer))
        print()
        with open("money.txt", "w", newline="") as file:
            end = datetime.now()
            if player > 21:
                print("Player busted! House always wins!")
                diff = money - bet
                ph = money
                money = round(money - bet, 2)
                localeMoney = Decimal(money)
                localeMoney = localeMoney.quantize(Decimal("1.00"))
                print("Money: " + lc.currency(localeMoney, grouping=True))
                file.write(str(money))
            elif dealer > 21:
                print("Dealer busted! Cash out, you're done at my tables")
                diff = money - bet
                ph = money
                money = round((bet * 1.5) + money, 2)
                localeMoney = Decimal(money)
                localeMoney = localeMoney.quantize(Decimal("1.00"))
                print("Money: " + lc.currency(localeMoney, grouping=True))
                file.write(str(money))
            elif player <= dealer:
                print("Player lost! Better luck next time, pal!")
                ph = money
                diff = money - bet
                money = round(money - bet, 2)
                localeMoney = Decimal(money)
                localeMoney = localeMoney.quantize(Decimal("1.00"))
                print("Money: " + lc.currency(localeMoney, grouping=True))
                file.write(str(money))

        print()
        choice = input("Play again? (y/n): ")
        if choice == "n":
            end = datetime.now()
            print("Stop time: " + end.strftime("%I:%M:%S %p"))
            hour = end.hour - start.hour
            minute = end.minute - start.minute
            second = end.second - start.second
            print("Elapsed time: " + str(hour) + ":" + str(minute) + ":" +
                  str(second))
            break