· 6 years ago · Jul 03, 2019, 02:50 PM
1from random import shuffle
2import os
3import cymysql
4from getpass import getpass
5import sys
6import re
7from bcrypt import hashpw, gensalt
8
9
10def shuffled_shoe():
11 shoe = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'J', 'Q', 'K']*4
12 shuffle(shoe)
13 return shoe
14
15
16def deal_card(shoe, person, number):
17 for _ in range(number):
18 person.append(shoe.pop())
19
20
21def deal_hand(shoe, player, dealer):
22 for _ in range(2):
23 deal_card(shoe, player, 1)
24 deal_card(shoe, dealer, 1)
25
26
27def score(person):
28 non_aces = [c for c in person if c != 'A']
29 aces = [c for c in person if c == 'A']
30 total = 0
31 for card in non_aces:
32 if card in 'JQK':
33 total += 10
34 else:
35 total += int(card)
36 for card in aces:
37 if total <= 10:
38 total += 11
39 else:
40 total += 1
41 return total
42
43
44def set_money(money, money_bet, win, push):
45 if win:
46 money += money_bet * 2
47 elif push:
48 money += money_bet
49 return money
50
51
52def clear_console():
53 os.system('cls' if os.name == 'nt' else 'clear')
54
55
56def display_info(still_playing, player, dealer, money, money_bet, player_stands):
57 win = False
58 push = False
59 clear_console()
60 print(f"Money: ${money}")
61 print(f"Money bet: ${money_bet}")
62 print("Your cards: [{}] ({})".format(']['.join(player), score(player)))
63 if player_stands:
64 print("Dealer cards: [{}] ({})".format(']['.join(dealer), score(dealer)))
65 else:
66 print("Dealer cards: [{}][?]".format(dealer[0]))
67 first_hand = len(dealer) == 2
68 if score(player) == 21:
69 print("Blackjack! You won")
70 still_playing = False
71 win = True
72 elif first_hand and score(dealer) == 21:
73 print("Dealer got a blackjack. You lost!")
74 still_playing = False
75 elif score(player) > 21:
76 print("Busted! You lost!")
77 still_playing = False
78 if player_stands:
79 if score(dealer) > 21:
80 print("Dealer busted! You won")
81 win = True
82 elif score(player) > score(dealer):
83 print("You beat the dealer! You won!")
84 win = True
85 elif score(player) < score(dealer):
86 print("Dealer has beaten you. You lost!")
87 else:
88 print("Push. Nobody wins or losses.")
89 push = True
90 still_playing = False
91 money = set_money(money, money_bet, win, push)
92 return still_playing, money
93
94
95def hit_or_stand():
96 while True:
97 print("What do you choose?")
98 print("[1] - Hit")
99 print("[2] - Stand")
100 ans = input('> ')
101 if ans in '12':
102 return ans
103
104
105def bet(money):
106 clear_console()
107 print(f"Money: ${money}")
108 print("How much money do you want to bet?")
109 while True:
110 money_bet = int(input('> '))
111 if money_bet <= money and not money_bet <= 0:
112 money -= money_bet
113 return money, money_bet
114 else:
115 print("Please enter a valid bet.")
116
117
118def player_play(shoe, player, dealer, money, money_bet, player_plays, player_stands):
119 while not player_stands:
120 if hit_or_stand() == '2':
121 player_stands = True
122 player_plays = False
123 elif not player_stands:
124 deal_card(shoe, player, 1)
125 display_info(True, player, dealer, money, money_bet, player_stands)
126 if score(player) >= 21:
127 player_plays = False
128 break
129 return player_plays, player_stands
130
131
132def dealer_play(shoe, dealer, dealer_minimum_score):
133 while score(dealer) <= dealer_minimum_score:
134 deal_card(shoe, dealer, 1)
135 return False
136
137
138def check_money(money):
139 if money == 0:
140 print("nUnfortunately you don't have any money.")
141 sys.exit()
142
143
144def update_db_money(cur, money, email):
145 cur.execute("UPDATE `users` SET `money`=%s WHERE `email`=%s", (money, email))
146 cur.close()
147
148
149def play_again(cur, money, email):
150 check_money(money)
151 while True:
152 print("nDo you want to play again? [Y]es/[N]o")
153 ans = input("> ").lower()
154 if ans == 'y':
155 return True
156 elif ans == 'n':
157 update_db_money(cur, money, email)
158 return False
159
160
161def get_user_info():
162 while True:
163 email = input("Email address (max. 255 chars.): ")
164 password = getpass("Password (max. 255 chars.): ").encode('utf-8')
165 hashed_pw = hashpw(password, gensalt())
166 if len(email) < 255 and len(password) < 255:
167 if re.match(r'[^@]+@[^@]+.[^@]+', email):
168 return email, password, hashed_pw
169 else:
170 print("Please enter a valid email address.")
171
172
173def register(cur, email, hashed_pw):
174 cur.execute("INSERT INTO `users` (`Email`, `Password`) VALUES (%s, %s)", (email, hashed_pw))
175
176
177def login(cur, email, password, hashed_pw):
178 cur.execute("SELECT * FROM `users` WHERE `Email`=%s LIMIT 1", (email,))
179 correct_credentials = cur.fetchone()
180 correct_hash = correct_credentials[2].encode('utf-8')
181 if hashpw(password, correct_hash) == correct_hash:
182 print("You've succesfully logged-in!")
183 else:
184 print("You failed logging-in!")
185 sys.exit()
186
187
188def check_account(cur, email):
189 cur.execute("SELECT * FROM `users` WHERE `Email`=%s LIMIT 1", (email,))
190 return bool(cur.fetchone())
191
192
193def start():
194 print("nDo you want to start playing? [Y]es/[N]o")
195 ans = input('> ').lower()
196 if ans == 'y':
197 return True
198 elif ans == 'n':
199 return False
200
201
202def db_conn():
203 conn = cymysql.connect(
204 host='127.0.0.1',
205 user='root',
206 passwd='',
207 db='blackjack'
208 )
209 with conn:
210 cur = conn.cursor()
211 email, password, hashed_pw = get_user_info()
212 checked = check_account(cur, email)
213 if checked:
214 login(cur, email, password, hashed_pw)
215 else:
216 register(cur, email, hashed_pw)
217 print("You've succesfully registered and recieved $1000 as a gift!")
218 cur.execute("SELECT `money` FROM `users` WHERE `email`=%s", (email,))
219 money_tuple = cur.fetchone()
220 money = money_tuple[0]
221 check_money(money)
222 return cur, money, email
223
224
225def main():
226 cur, money, email = db_conn()
227 keeps_playing = start()
228 while keeps_playing:
229 shoe = shuffled_shoe()
230 player = []
231 dealer = []
232 still_playing = True
233 player_plays = True
234 player_stands = False
235 money, money_bet = bet(money)
236 deal_hand(shoe, player, dealer)
237 still_playing, money = display_info(still_playing, player, dealer, money, money_bet, player_stands)
238 while still_playing:
239 while player_plays:
240 player_plays, player_stands = player_play(shoe, player, dealer, money, money_bet, player_plays, player_stands)
241 still_playing = dealer_play(shoe, dealer, 17)
242 still_playing, money = display_info(still_playing, player, dealer, money, money_bet, player_stands)
243 keeps_playing = play_again(cur, money, email)
244
245
246if __name__ == '__main__':
247 main()
248
249SET NAMES utf8;
250SET time_zone = '+00:00';
251SET foreign_key_checks = 0;
252SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
253
254DROP TABLE IF EXISTS `users`;
255CREATE TABLE `users` (
256 `id` int(11) NOT NULL AUTO_INCREMENT,
257 `email` varchar(255) COLLATE utf8_bin NOT NULL,
258 `password` varchar(255) COLLATE utf8_bin NOT NULL,
259 `money` int(11) NOT NULL DEFAULT '1000',
260 PRIMARY KEY (`id`)
261) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;