f5a1eebd by Barry

Blackjack is now working. No double-down, split, or insurance

1 parent b5453b97
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:
......