-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGame.py
300 lines (239 loc) · 9.55 KB
/
Game.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
from time import sleep
from subprocess import call
import Player
import shutil
import Deck
import sys
import os
class Game:
# constructor
def __init__(self):
# assign member variables
self.MAX_HIT_SCORE = 21
self.DEALER_STAND_SCORE = 17
# get and set game info
self.clear_screen()
self.deck = Deck.Deck()
self.player = Player.Player(
self.print_welcome_and_get_name(), self.MAX_HIT_SCORE)
self.dealer = Player.Player('Dealer', self.MAX_HIT_SCORE)
# start game
self.play_blackjack()
# handles entire game loop
def play_blackjack(self):
# clears screen before starting game
self.clear_screen()
# handles gameplay replay
end_game = False
# main game loop
while end_game == False:
# clear screen and print welcome message
self.clear_screen()
self.print_centre(
f'Hi {self.player.get_name()}! Welcome To Blackjack!')
print()
# set player and dealer hands
self.set_initial_hand()
# player turn loop
while True and end_game is False:
# print turn and points
self.print_turn('Your')
self.player_turn_print()
# get player input
player_input = input('Would you like to (H)it or (S)tand? ')
print()
sleep(1)
# evaluate hit input, add card to hand, and check for bust
if player_input == 'H' or player_input == 'h' or player_input == 'Hit' or player_input == 'hit':
# add card from deck to player hand
self.player.add_card(self.deck.get_top_card())
# if card is exactly MAX_HIT_SCORE
if self.player.get_score() == self.MAX_HIT_SCORE:
# announce player win and exit to replay
self.player_turn_print()
print('Blackjack! You Win!')
end_game = True
break
# if card is greater than MAX_HIT_SCORE (bust)
elif self.player.get_score() > self.MAX_HIT_SCORE:
# announce dealer loss and exit to replay
self.dealer_turn_print()
print('You busted! Dealer Wins!')
end_game = True
break
# if card is less than MAX_HIT_SCORE
else:
# continue game
self.player_turn_print()
# evaluate stand input, exit to dealer turn
elif player_input == 'S' or player_input == 's':
break
# wrong input
else:
print('Invalid input, please try again.')
# shuffle deck after each turn
self.shuffle_deck()
print('\n')
print()
# dealer turn loop
while True and end_game is False:
# print turn and points
self.print_turn('Dealer\'s')
# dealer turn animation and score board
self.load_animation('_', 20, False)
print()
self.dealer_turn_print()
sleep(1)
# if dealer score is less than dealer stand score
if self.dealer.get_score() < self.DEALER_STAND_SCORE:
# add card to dealers hand
self.dealer.add_card(self.deck.get_top_card())
sleep(1)
# if dealer score is greater than dealer stand score
else:
# compare dealer and player scores
if self.dealer.get_score() > self.player.get_score() and self.dealer.get_score() <= self.MAX_HIT_SCORE:
# dealer wins
self.clear_screen()
print('Dealer Wins!')
self.dealer_turn_print()
end_game = True
break
elif self.player.get_score() == self.dealer.get_score():
# player and dealer tie
self.clear_screen()
print('It\'s a tie!')
self.dealer_turn_print()
end_game = True
break
else:
# dealers score is lower than player score
self.clear_screen()
print('You Win! Dealer Busted!')
self.dealer_turn_print()
end_game = True
break
self.shuffle_deck()
print('\n'*2)
# replay game
end_game = self.play_again()
self.reset_hand_and_deck() if end_game is False else None
self.print_centre('\n\n~Thanks for playing!~')
# prints the turn of the current player
def print_turn(self, player):
print(f'\n{player} turn...')
# adds two cards to each player and dealer
def set_initial_hand(self):
self.shuffle_deck()
self.deal_cards()
self.player.add_card(self.deck.get_top_card())
self.dealer.add_card(self.deck.get_top_card())
self.player.add_card(self.deck.get_top_card())
self.dealer.add_card(self.deck.get_top_card())
self.clear_screen()
print('Starting hands dealt...')
print()
# shuffles and randomizes deck
def shuffle_deck(self):
self.deck.shuffle()
self.load_animation('Shuffling deck...', 20, False)
sleep(1)
# dealing cards animation
def deal_cards(self):
self.load_animation('Dealing cards...', 20, False)
sleep(1)
# score print with dealer cards hidden
def player_turn_print(self):
print(self.bordered(self.dealer.hand_with_hidden_score() +
'\n' + self.player.hand_with_score()) + '\n')
# score print with dealer cards visible
def dealer_turn_print(self):
sleep(1)
print(self.bordered(self.dealer.hand_with_score() +
'\n' + self.player.hand_with_score()) + '\n')
# prints text with border around it
def bordered(self, text):
lines = text.splitlines()
width = max(len(s) for s in lines)
res = ['┌' + '─' * width + '┐']
for s in lines:
res.append('│' + (s + ' ' * width)[:width] + '│')
res.append('└' + '─' * width + '┘')
return '\n'.join(res)
# returns true if player wants to play again
def play_again(self):
print()
_ = input('Would you like to play again? Yes(Y) or No(N) ')
if _ == 'Y' or _ == 'y':
return False
return True
# clears the entire console
def clear_screen(self):
# clear screen for specific operating system
sleep(1)
_ = call('clear' if os.name == 'posix' else 'clear')
# prints welcome message and gets player name
def print_welcome_and_get_name(self):
# self.load_animation('~Welcome to Blackjack!~', 40)
self.print_centre('~Welcome to Blackjack!~')
sleep(1)
return input('Please enter your name: ')
# prints centered text
def print_centre(self, s, animation=False):
print(s.center(shutil.get_terminal_size().columns))
# resets the hand and deck
def reset_hand_and_deck(self):
self.player.reset_hand()
self.dealer.reset_hand()
self.deck.reset_deck()
# animation for loading
def load_animation(self, msg, relative_time, clear_screen=True):
# String to be displayed when the application is loading
load_str = msg
ls_len = len(load_str)
# String for creating the rotating line
animation = "|/-\\"
anicount = 0
# used to keep the track of the duration of animation
counttime = relative_time
# pointer for travelling the loading string
i = 0
while (counttime != 0):
# used to change the animation speed
# smaller the value, faster will be the animation
sleep(0.075)
# converting the string to list
# as string is immutable
load_str_list = list(load_str)
# x->obtaining the ASCII code
x = ord(load_str_list[i])
# y->for storing altered ASCII code
y = 0
# if the character is "." or " ", keep it unaltered
# switch uppercase to lowercase and vice-versa
if x != 32 and x != 46:
if x > 90:
y = x-32
else:
y = x + 32
load_str_list[i] = chr(y)
# for storing the resultant string
res = ''
for j in range(ls_len):
res = res + load_str_list[j]
# displaying the resultant string
sys.stdout.write("\r"+res + animation[anicount])
sys.stdout.flush()
# Assigning loading string
# to the resultant string
load_str = res
anicount = (anicount + 1) % 4
i = (i + 1) % ls_len
counttime -= 1
# for windows OS
if clear_screen == True:
if os.name == "nt":
os.system("cls")
# for linux / Mac OS
else:
os.system("clear")