-
Notifications
You must be signed in to change notification settings - Fork 1
/
blackjack.py
177 lines (144 loc) · 4.87 KB
/
blackjack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import random
class Deck():
'''
Represents a deck of 52 cards.
'''
def __init__(self):
class Card():
'''
Represents and individual card of a deck with attributes of a face (or number), suit, and value.
'''
def __init__(self, suit, value, face):
self.suit = suit
self.value = value
self.face = face
self.image_map = str(self.face) + "_of_" + self.suit + '.svg'
self.suits = ['clubs', 'spades', 'hearts', 'diamonds']
self.faces = ['jack', 'queen', 'king']
self.number_cards = [Card(suit, value, value) for value in range(2, 11) for suit in self.suits]
self.face_cards = [Card(suit, 10, face) for face in self.faces for suit in self.suits]
self.ace_cards = [Card(suit, 11, 'ace') for suit in self.suits]
self.cards = self.face_cards + self.number_cards + self.ace_cards
class Hand():
def __init__(self, id):
self.cards = []
self.id = id
self.total = 0
self.bust = False
self.door_value = None
self.bet = 0
self.active = False
self.can_double = True
def __check_bust(self):
'''
Updates the bust attribute to True if the total attribute exceeds 21
'''
if self.total > 21:
self.bust = True
def __update_door_value(self):
'''
Updates door value for the face value of the the first card in the hand.
This is the "door card" for the dealer in the first round
'''
self.door_value = self.cards[0].value
def __update_total(self):
'''
Recalculates the total attribute to include a new card. If the card is an ace it counts as 11 or 1 points,
whichever does not make the player bust
'''
if 'ace' in [card.face for card in self.cards]:
non_ace_total = sum([card.value for card in self.cards if card.face != 'ace'])
running_total = non_ace_total
for card in self.cards:
if card.face == 'ace':
if (running_total + card.value) > 21:
running_total += 1
else:
running_total += 11
self.total = running_total
else:
self.total = sum([card.value for card in self.cards])
def add_card(self, card):
'''
Adds a card to the hand
'''
self.cards.append(card)
self.__update_total()
self.__update_door_value()
self.__check_bust()
class Player:
'''
Represents a blackjack player
'''
def __init__(self):
self.hands = {}
self.total = 0
self.bust = False
self.bank = 100
def can_split(self):
'''
Determine if the first two cards dealt to the player are the same. If they are the same, the player
will be given the option to split
'''
return True if len(set([card.value for card in self.hands[0]])) == 1 else False
def split(self):
'''
Splits the players hand
'''
pass
def add_hand(self, hand_id):
'''
Adds a hand to the player object
'''
hand_key = hand_id
self.hands[hand_key] = Hand(hand_id)
def split_cards(self):
'''
Takes first card from first hand and moves it to the second hand
'''
hand_one = self.hands[1]
first_card = hand_one.cards[0]
second_card = hand_one.cards[1]
hand_one.total = first_card.value
hand_two = self.hands[2]
hand_two.cards.append(second_card)
hand_two.total = second_card.value
hand_two.bet = hand_one.bet
hand_one.cards.remove(second_card)
class Dealer(Player):
'''
Represents the dealer, inherits from the "Player" class.
'''
def __init__(self):
super().__init__()
self.hands = {1 : Hand(1)}
def get_hole_card(self):
'''
Returns the second card dealt to the dealers hand
'''
return self.hands[1].cards[1]
class Game():
'''
Represents the blackjack game.
'''
def __init__(self, Dealer, Deck, Player):
self.deck = Deck().cards
self.player = Player()
self.dealer = Dealer()
self.round = 1
def draw_card(self, target, hand_id):
'''
Draws a card from the deck and adds it to either the dealer or player (the target)
'''
card_draw = random.choice(self.deck)
self.deck.remove(card_draw)
if target == 'player':
self.player.hands[hand_id].add_card(card_draw)
elif target == 'dealer':
self.dealer.hands[hand_id].add_card(card_draw)
return card_draw
def new_deck(self):
'''
Adds a fresh deck to the game
'''
self.deck = Deck().cards