Blackjack is now working. No double-down, split, or insurance
Showing
3 changed files
with
175 additions
and
44 deletions
1 | from random import randrange | 1 | from random import randrange |
2 | import pickle | ||
2 | 3 | ||
3 | SUITS = (':clubs:', ':spades:', ':hearts:', ':diamonds:') | 4 | SUITS = (':clubs:', ':spades:', ':hearts:', ':diamonds:') |
4 | CARDS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K') | 5 | CARDS = ('A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K') |
... | @@ -55,7 +56,7 @@ class Deck: | ... | @@ -55,7 +56,7 @@ class Deck: |
55 | def draw(self, number_of_cards=1): | 56 | def draw(self, number_of_cards=1): |
56 | drawn_cards = [] | 57 | drawn_cards = [] |
57 | for n in range(number_of_cards): | 58 | for n in range(number_of_cards): |
58 | print("CARDS LEFT: {}".format(self.cards_left())) | 59 | #print("CARDS LEFT: {}".format(self.cards_left())) |
59 | choice = randrange(0, len(self.draw_pile)) | 60 | choice = randrange(0, len(self.draw_pile)) |
60 | drawn_cards.append(self.draw_pile.pop(choice)) | 61 | drawn_cards.append(self.draw_pile.pop(choice)) |
61 | return drawn_cards | 62 | return drawn_cards |
... | @@ -64,8 +65,11 @@ class Deck: | ... | @@ -64,8 +65,11 @@ class Deck: |
64 | return len(self.draw_pile) | 65 | return len(self.draw_pile) |
65 | 66 | ||
66 | class Blackjack: | 67 | class Blackjack: |
67 | def __init__(self, bet): | 68 | def __init__(self, bet=0, state=None): |
68 | self.bet = bet | 69 | if state: |
70 | self.deserialize(state) | ||
71 | else: | ||
72 | self.bet = int(bet) | ||
69 | self.deck = Deck() | 73 | self.deck = Deck() |
70 | self.player_hand = Hand() | 74 | self.player_hand = Hand() |
71 | self.player_hand.add_cards(self.deck.draw(2)) | 75 | self.player_hand.add_cards(self.deck.draw(2)) |
... | @@ -87,6 +91,9 @@ class Blackjack: | ... | @@ -87,6 +91,9 @@ class Blackjack: |
87 | self.dealer_hand.add_cards(self.deck.draw(1)) | 91 | self.dealer_hand.add_cards(self.deck.draw(1)) |
88 | 92 | ||
89 | def is_busted(self): | 93 | def is_busted(self): |
94 | self.dealer_points = self.dealer_hand.get_points() | ||
95 | self.player_points = self.player_hand.get_points() | ||
96 | |||
90 | if self.player_points > 21: | 97 | if self.player_points > 21: |
91 | return 1 | 98 | return 1 |
92 | elif self.dealer_points > 21: | 99 | elif self.dealer_points > 21: |
... | @@ -95,6 +102,9 @@ class Blackjack: | ... | @@ -95,6 +102,9 @@ class Blackjack: |
95 | return 0 | 102 | return 0 |
96 | 103 | ||
97 | def is_win(self): | 104 | def is_win(self): |
105 | if self.player_hand.is_blackjack() and not self.dealer_hand.is_blackjack(): | ||
106 | return (int(self.bet + self.bet * 1.5), 'Blackjack! You win: {}') | ||
107 | # Resolve blackjack before dealer draws. | ||
98 | self.dealer_draw() | 108 | self.dealer_draw() |
99 | self.dealer_points = self.dealer_hand.get_points() | 109 | self.dealer_points = self.dealer_hand.get_points() |
100 | self.player_points = self.player_hand.get_points() | 110 | self.player_points = self.player_hand.get_points() |
... | @@ -102,29 +112,29 @@ class Blackjack: | ... | @@ -102,29 +112,29 @@ class Blackjack: |
102 | # TODO: Check for blackjack Ace + 10 pt | 112 | # TODO: Check for blackjack Ace + 10 pt |
103 | if self.player_points > 21: | 113 | if self.player_points > 21: |
104 | return (-self.bet, 'You Bust: {}') | 114 | return (-self.bet, 'You Bust: {}') |
105 | elif self.player_hand.is_blackjack() and not self.dealer_hand.is_blackjack(): | ||
106 | return (self.bet + self.bet * 1.5, 'Blackjack, you win: {}') | ||
107 | elif self.dealer_points > 21: | 115 | elif self.dealer_points > 21: |
108 | return (self.bet * 2, 'Dealer Busts: {}') | 116 | return (int(self.bet * 2), 'Dealer Busts: {}') |
109 | elif self.dealer_hand.is_blackjack(): | 117 | elif self.dealer_hand.is_blackjack(): |
110 | return (-self.bet, 'You lose: {}') | 118 | return (-self.bet, 'You lose: {}') |
111 | elif self.player_points > self.dealer_points: | 119 | elif self.player_points > self.dealer_points: |
112 | return (self.bet * 2, 'You win: {}') | 120 | return (int(self.bet * 2), 'You win: {}') |
113 | elif self.player_points == self.dealer_points: | 121 | elif self.player_points == self.dealer_points: |
114 | return (self.bet, 'push your bet is returned: {}') | 122 | return (self.bet, 'push your bet is returned: {}') |
115 | else: | 123 | else: |
116 | return (-self.bet, 'You lose: {}') | 124 | return (-self.bet, 'You lose: {}') |
117 | 125 | ||
118 | def print_hand(self, show_dealer=False): | 126 | def print_hand(self, show_dealer=False): |
127 | out_string = "" | ||
119 | if show_dealer: | 128 | if show_dealer: |
120 | dealers = ' '.join(self.dealer_hand.get_cards()) | 129 | dealers = ' '.join(self.dealer_hand.get_cards()) |
121 | print("Dealer's Hand: {} for {} points".format(dealers, self.dealer_hand.get_points())) | 130 | out_string += "Dealer's Hand: {} showing for {} points\n".format(dealers, self.dealer_hand.get_points()) |
122 | else: | 131 | else: |
123 | dealers = ' '.join(self.dealer_hand.get_cards()[1:]) | 132 | dealers = ' '.join(self.dealer_hand.get_cards()[1:]) |
124 | print("Dealer's Hand: {}".format(dealers)) | 133 | out_string += "Dealer's Hand: {} showing\n".format(dealers) |
125 | 134 | ||
126 | self.player_points = self.player_hand.get_points() | 135 | self.player_points = self.player_hand.get_points() |
127 | print("Player's Hand: {} for {} points".format(' '.join(self.player_hand.get_cards()), self.player_hand.get_points())) | 136 | out_string += "Player's Hand: {} for {} points".format(' '.join(self.player_hand.get_cards()), self.player_hand.get_points()) |
137 | return out_string | ||
128 | 138 | ||
129 | def get_actions(self): | 139 | def get_actions(self): |
130 | points = self.player_hand.get_points() | 140 | points = self.player_hand.get_points() |
... | @@ -133,34 +143,43 @@ class Blackjack: | ... | @@ -133,34 +143,43 @@ class Blackjack: |
133 | if self.player_hand.is_blackjack(): | 143 | if self.player_hand.is_blackjack(): |
134 | pass | 144 | pass |
135 | elif points < 21 and not self.is_busted() == 2: | 145 | elif points < 21 and not self.is_busted() == 2: |
136 | actions.append('hit') | 146 | actions.append('!hit') |
137 | actions.append('stand') | 147 | actions.append('!stand') |
138 | actions.append('double') | 148 | #actions.append('!double') |
139 | elif len(cards) == 2: | 149 | elif len(cards) == 2: |
140 | if cards[0][0] == cards[1][0]: | 150 | if cards[0][0] == cards[1][0]: |
141 | actions.append('split') | 151 | actions.append('!split') |
142 | return actions | 152 | return actions |
143 | 153 | ||
144 | bet = 10 | 154 | def serialize(self): |
145 | bj = Blackjack(bet) | 155 | return pickle.dumps(self) |
146 | bj.print_hand() | 156 | |
147 | actions = bj.get_actions() | 157 | def deserialize(self, state): |
148 | done = False | 158 | self = pickle.loads(state) |
149 | while len(actions) > 0: | 159 | |
150 | action = raw_input('Please choose an option [{}]'.format(', '.join(actions))) | 160 | # bet = 10 |
151 | if action == 'stand': | 161 | # bj = Blackjack(bet) |
152 | break | 162 | # print(bj.print_hand()) |
153 | elif action == 'hit': | 163 | # actions = bj.get_actions() |
154 | bj.draw() | 164 | # done = False |
155 | bj.print_hand() | 165 | # while len(actions) > 0: |
156 | 166 | # action = raw_input('Please choose an option [{}]'.format(', '.join(actions))) | |
157 | actions = bj.get_actions() | 167 | # if action == 'stand': |
158 | 168 | # break | |
159 | win, response = bj.is_win() | 169 | # elif action == 'hit': |
160 | print('\n') | 170 | # bj.draw() |
161 | bj.print_hand(show_dealer=True) | 171 | # print(bj.print_hand()) |
162 | print('\n') | 172 | # elif action == 'serialize': |
163 | print(response.format(win,)) | 173 | # state = bj.serialize() |
174 | # print(state) | ||
175 | # bj.deserialize(state) | ||
176 | # actions = bj.get_actions() | ||
177 | |||
178 | # win, response = bj.is_win() | ||
179 | # print('\n') | ||
180 | # print(bj.print_hand(show_dealer=True)) | ||
181 | # print('\n') | ||
182 | # print(response.format(win,)) | ||
164 | 183 | ||
165 | 184 | ||
166 | 185 | ... | ... |
No preview for this file type
... | @@ -4,6 +4,7 @@ import random | ... | @@ -4,6 +4,7 @@ import random |
4 | import datetime | 4 | import datetime |
5 | import re | 5 | import re |
6 | import operator | 6 | import operator |
7 | import pickle | ||
7 | 8 | ||
8 | import traceback | 9 | import traceback |
9 | import sys | 10 | import sys |
... | @@ -19,6 +20,7 @@ from collections import defaultdict | ... | @@ -19,6 +20,7 @@ from collections import defaultdict |
19 | from nltk.tag import pos_tag | 20 | from nltk.tag import pos_tag |
20 | import wolframalpha | 21 | import wolframalpha |
21 | import sqlite3 | 22 | import sqlite3 |
23 | from blackjack import Blackjack | ||
22 | 24 | ||
23 | VERSION = 1.6 | 25 | VERSION = 1.6 |
24 | 26 | ||
... | @@ -65,7 +67,7 @@ def leaders(xs, top=20): | ... | @@ -65,7 +67,7 @@ def leaders(xs, top=20): |
65 | 67 | ||
66 | def byteify(input): | 68 | def byteify(input): |
67 | if isinstance(input, dict): | 69 | if isinstance(input, dict): |
68 | return {byteify(key):byteify(value) for key,value in input.iteritems()} | 70 | return {byteify(key): byteify(value) for key, value in input.iteritems()} |
69 | elif isinstance(input, list): | 71 | elif isinstance(input, list): |
70 | return [byteify(element) for element in input] | 72 | return [byteify(element) for element in input] |
71 | elif isinstance(input, unicode): | 73 | elif isinstance(input, unicode): |
... | @@ -112,6 +114,32 @@ def dict_factory(cursor, row): | ... | @@ -112,6 +114,32 @@ def dict_factory(cursor, row): |
112 | d[col[0]] = row[idx] | 114 | d[col[0]] = row[idx] |
113 | return d | 115 | return d |
114 | 116 | ||
117 | def db_add_minigame(member_id, minigame_name, state): | ||
118 | c = conn.cursor() | ||
119 | db_state = c.execute("SELECT state FROM minigames WHERE member_id = ? AND minigame_name = ?;", (member_id,minigame_name)).fetchone() | ||
120 | if not db_state: | ||
121 | c = conn.cursor() | ||
122 | c.execute("""INSERT INTO minigames(member_id, minigame_name, state) | ||
123 | VALUES(?, ?, ?);""", (member_id, minigame_name, state)) | ||
124 | conn.commit() | ||
125 | else: | ||
126 | c = conn.cursor() | ||
127 | c.execute("""UPDATE minigames SET state = ? | ||
128 | WHERE member_id = ? AND minigame_name = ?;""", (state, member_id, minigame_name)) | ||
129 | conn.commit() | ||
130 | pass | ||
131 | |||
132 | def db_get_minigame_state(member_id, minigame_name): | ||
133 | c = conn.cursor() | ||
134 | state = c.execute("SELECT state FROM minigames WHERE member_id = ? AND minigame_name = ?;", (member_id, minigame_name)).fetchone() | ||
135 | if state: | ||
136 | return state[0] | ||
137 | |||
138 | def db_delete_minigame_state(member_id, minigame_name): | ||
139 | c = conn.cursor() | ||
140 | c.execute("DELETE FROM minigames WHERE member_id = ? AND minigame_name = ?;", (member_id, minigame_name)) | ||
141 | conn.commit() | ||
142 | |||
115 | def db_add_message(message, delivery_time, channel, message_from, message_to, user_id): | 143 | def db_add_message(message, delivery_time, channel, message_from, message_to, user_id): |
116 | c = conn.cursor() | 144 | c = conn.cursor() |
117 | c.execute("""INSERT INTO messages(message, delivery_time, channel, message_from, message_to, user_id) | 145 | c.execute("""INSERT INTO messages(message, delivery_time, channel, message_from, message_to, user_id) |
... | @@ -403,6 +431,10 @@ Games: | ... | @@ -403,6 +431,10 @@ Games: |
403 | !games <username> - Returns a list of games played for a username. | 431 | !games <username> - Returns a list of games played for a username. |
404 | !gameslist <count> - Returns a list of the top 20 games and the number of people who have played that game. if you pass a limit it will show that many games instead. | 432 | !gameslist <count> - Returns a list of the top 20 games and the number of people who have played that game. if you pass a limit it will show that many games instead. |
405 | !whoplayed <gamename> - Returns a list of players who have played the game. | 433 | !whoplayed <gamename> - Returns a list of players who have played the game. |
434 | Minigames: | ||
435 | !bet <amount> - Start a game of BlackJack. | ||
436 | !hit - Draw a card | ||
437 | !stand - Show the cards | ||
406 | Spam: | 438 | Spam: |
407 | !youtube <search term> - Returns the first video from the search results for the search term. | 439 | !youtube <search term> - Returns the first video from the search results for the search term. |
408 | !gif <search term> - Returns the first gif from the search results. | 440 | !gif <search term> - Returns the first gif from the search results. |
... | @@ -556,24 +588,104 @@ Stuff: | ... | @@ -556,24 +588,104 @@ Stuff: |
556 | out_string = out_string[1900:] | 588 | out_string = out_string[1900:] |
557 | return | 589 | return |
558 | 590 | ||
591 | if message.content.startswith('!hit') or message.content.startswith('!draw'): | ||
592 | member = db_get_member(message.author.id) | ||
593 | if not member: | ||
594 | client.send_message(message.author, "There was a problem looking up your information.") | ||
595 | elif type(message.channel) is not discord.channel.PrivateChannel: | ||
596 | client.send_message(message.author, "You must make all bets / gaming via private message.") | ||
597 | else: | ||
598 | state = db_get_minigame_state(member['member_id'], 'blackjack') | ||
599 | if state: | ||
600 | out_string = "" | ||
601 | bj = pickle.loads(str(state)) | ||
602 | bj.draw() | ||
603 | out_string += bj.print_hand() | ||
604 | actions = bj.get_actions() | ||
605 | if len(actions) > 0: | ||
606 | out_string += '\n\nPlease choose an option [{}]\n'.format(', '.join(actions)) | ||
607 | db_add_minigame(member['member_id'], 'blackjack', bj.serialize()) | ||
608 | else: | ||
609 | win, response = bj.is_win() | ||
610 | out_string += "\n\n" + bj.print_hand(show_dealer=True) | ||
611 | out_string += "\n\n" + response.format(win,) | ||
612 | db_delete_minigame_state(member['member_id'], 'blackjack') | ||
613 | client.send_message(message.author, out_string) | ||
614 | |||
615 | else: | ||
616 | client.send_message(message.author, "You must start a game with !bet before you can ask for a new card.") | ||
617 | return | ||
618 | |||
619 | if message.content.startswith('!stay') or message.content.startswith('!stand'): | ||
620 | member = db_get_member(message.author.id) | ||
621 | if not member: | ||
622 | client.send_message(message.author, "There was a problem looking up your information.") | ||
623 | elif type(message.channel) is not discord.channel.PrivateChannel: | ||
624 | client.send_message(message.author, "You must make all bets / gaming via private message.") | ||
625 | else: | ||
626 | state = db_get_minigame_state(member['member_id'], 'blackjack') | ||
627 | if state: | ||
628 | out_string = "" | ||
629 | bj = pickle.loads(str(state)) | ||
630 | |||
631 | win, response = bj.is_win() | ||
632 | out_string += "\n\n" + bj.print_hand(show_dealer=True) | ||
633 | out_string += "\n\n" + response.format(win,) | ||
634 | db_delete_minigame_state(member['member_id'], 'blackjack') | ||
635 | |||
636 | client.send_message(message.author, out_string) | ||
637 | return | ||
638 | |||
559 | if message.content.startswith('!bet'): | 639 | if message.content.startswith('!bet'): |
560 | if type(message.channel) is not discord.channel.PrivateChannel: | 640 | member = db_get_member(message.author.id) |
641 | if not member: | ||
642 | client.send_message(message.author, "There was a problem looking up your information.") | ||
643 | elif type(message.channel) is not discord.channel.PrivateChannel: | ||
561 | client.send_message(message.author, "You must make all bets / gaming via private message.") | 644 | client.send_message(message.author, "You must make all bets / gaming via private message.") |
562 | else: | 645 | else: |
646 | state = db_get_minigame_state(member['member_id'], 'blackjack') | ||
647 | if state: | ||
648 | client.send_message(message.author, "You are already playing a game!") | ||
649 | |||
650 | out_string = "" | ||
651 | bj = pickle.loads(str(state)) | ||
652 | out_string += bj.print_hand() | ||
653 | actions = bj.get_actions() | ||
654 | if len(actions) > 0: | ||
655 | out_string += '\n\nPlease choose an option [{}]\n'.format(', '.join(actions)) | ||
656 | db_add_minigame(member['member_id'], 'blackjack', bj.serialize()) | ||
657 | else: | ||
658 | win, response = bj.is_win() | ||
659 | out_string += "\n\n" + bj.print_hand(show_dealer=True) | ||
660 | out_string += "\n\n" + response.format(win,) | ||
661 | db_delete_minigame_state(member['member_id'], 'blackjack') | ||
662 | client.send_message(message.author, out_string) | ||
663 | |||
664 | return | ||
665 | |||
666 | out_string = "" | ||
563 | bet_amount = message.content[5:] | 667 | bet_amount = message.content[5:] |
564 | client.send_message(message.author, "Welcome to BlackJack! :flower_playing_cards: You have placed a bet of: {}".format(bet_amount)) | 668 | if not bet_amount.isdigit(): |
565 | client.send_message(message.author, "Your Hand: {} {}".format(byteify('A:diamonds:'), byteify('J:hearts:'))) | 669 | client.send_message(message.author, "Please provide a bet amount. !bet 10") |
566 | client.send_message(message.author, "Dealers Hand: {} {}".format(byteify('A:diamonds:'), byteify(':bell:'))) | ||
567 | return | 670 | return |
671 | out_string += "Welcome to BlackJack! :flower_playing_cards: You have placed a bet of: {}\n".format(bet_amount) | ||
672 | bj = Blackjack(bet_amount) | ||
568 | 673 | ||
569 | if message.content.startswith('!direct'): | 674 | out_string += bj.print_hand() |
675 | actions = bj.get_actions() | ||
676 | if len(actions) > 0: | ||
677 | out_string += '\n\nPlease choose an option [{}]\n'.format(', '.join(actions)) | ||
678 | db_add_minigame(member['member_id'], 'blackjack', pickle.dumps(bj)) | ||
679 | else: | ||
680 | win, response = bj.is_win() | ||
681 | out_string += "\n\n" + bj.print_hand(show_dealer=True) | ||
682 | out_string += "\n\n" + response.format(win,) | ||
683 | db_delete_minigame_state(member['member_id'], 'blackjack') | ||
570 | 684 | ||
571 | channel = message.channel | 685 | client.send_message(message.author, out_string) |
572 | author = message.author | ||
573 | 686 | ||
574 | log("{} {} - type: {}".format(channel.id, author.id, type(channel))) | ||
575 | client.send_message(author, "test") | ||
576 | return | 687 | return |
688 | |||
577 | # !msg joe in 5 minutes YOU ARE A DICK | 689 | # !msg joe in 5 minutes YOU ARE A DICK |
578 | if message.content.startswith('!msg'): | 690 | if message.content.startswith('!msg'): |
579 | try: | 691 | try: | ... | ... |
-
Please register or sign in to post a comment