class Table(object): def __init__(self, minimum=1, maximum=500, payout=1, hit_soft_17=True, insurance_allowed=True, insurance_payout=2, num_decks=6, reshuffle_each_hand=True, blackjack_payout=1.5, max_split_hands=3, surrender_allowed=True, hit_split_ace=False, resplit_aces=False, split_A10_is_blackjack=False, double_after_split=False, double_after_hit= False): # Establish table rules self.min = minimum if minimum > 0 else 1 self.standard_bet = self.min self.max = maximum if maximum > minimum else 500 self.payout = payout if payout > 0 else 1 self.hit_soft_17 = hit_soft_17 self.insurance_allowed = insurance_allowed self.insurance_payout = insurance_payout if insurance_payout > 0 else 2 self.num_decks = num_decks if num_decks > 0 else 6 self.reshuffle_each_hand = reshuffle_each_hand self.blackjack_payout = blackjack_payout if blackjack_payout > 0 else 1.5 self.max_split_hands = max_split_hands if max_split_hands >= 2 else 3 self.surrender_allowed = surrender_allowed self.hit_split_ace = hit_split_ace self.resplit_aces = resplit_aces self.split_A10_is_blackjack = split_A10_is_blackjack self.double_after_split = double_after_split self.double_after_hit = double_after_hit # Initialize necessary variables if debug: print "Established table" self.init_deck() self.dealer_hand = Hand("Dealer") def init_deck(self): self.deck = Deck(self.num_decks) self.deck.shuffle() def buy_in(self, name, chips, bet_method, play_method): if debug: print name + " bought into the table with $" + str(chips) self.player_name = name self.player_chips = chips self.player_hands = [Hand(name)] self.player_surrendered = False self.bets = [] self.win_streak = 0 self.in_play = [False] self.bet_method = bet_method self.play_method = play_method self.doubled = [False] def add_funds(self, chips): self.player_chips = self.player_chips + chips def __str__(self): if len(self.dealer_hand.cards) > 0: ret = "Dealer is showing: " + str(self.dealer_hand.cards[0]) + "\n" for h in range(len(self.player_hands)): ret = ret + str(self.player_hands[h]) + " w/ value " + str(hand_value(self.player_hands[h])) + " and $" + str(self.bets[h]) + " bet" return ret else: return "Waiting for hand to be dealt\n" def deal(self): if self.reshuffle_each_hand or self.deck.cards_left() < 4: # if debug: # print "Shuffling decks" self.init_deck() # if debug: # print "Dealing" self.deck.move_cards(self.dealer_hand, 2) self.deck.move_cards(self.player_hands[0], 2) self.player_hands[0].sort() self.in_play[0] = True def get_bets(self): bet = self.bet_method(self.player_chips) if bet == "rebet": self.place_bet(self.standard_bet) else: while not self.place_bet(bet): bet = self.bet_method() if bet == "rebet": self.place_bet(self.standard_bet) def place_bet(self, bet): if bet < self.min: if debug: print "Must bet at least the minimum: " + str(self.min) return False elif bet > self.max: if debug: print "Must bet less than the maximum: " + str(self.max) return False elif bet > self.player_chips: if debug: print "Don't have funds to place bet. Current chip count: " + str(self.player_chips) return False else: self.bets.append(bet) self.doubled.append(False) self.player_chips = self.player_chips - bet self.standard_bet = bet if debug: print self.player_name + " placed bet: " + str(bet) return True def handle_player(self): while any(self.in_play): for h in range(len(self.in_play)): if self.in_play[h]: break hand = self.player_hands[h] completed_hand = False minimum, maximum = hand_value(hand) if minimum == 21 or maximum == 21: completed_hand = True self.in_play[h] = False dealer_min, dealer_max = hand_value(self.dealer_hand) if dealer_max == 21: completed_hand = True self.in_play[h] = False while not completed_hand: insurance = False surrender = False split = False double = False stand = True hit = True if len(hand.cards) == 2: if self.dealer_hand.cards[0].rank == 1: insurance = True if len(self.player_hands) == 1: surrender = True double = True if hand.cards[0].rank == hand.cards[1].rank: if h == 0 or ((h > 0 and hand.cards[0].rank != 1) or (self.resplit_aces and hand.cards[0].rank == 1)): if len(self.player_hands) < self.max_split_hands: split = True possible_plays = [insurance, surrender, split, double, stand, hit] choice = self.play_method(self.dealer_hand.cards[0], hand, possible_plays) if choice == "dh": choice = "d" if double else "h" if choice == "ds": choice = "d" if double else "s" if choice == "rh": if not surrender: choice = "h" if choice == "sp" or choice == "split": choice = "h" if choice == "hit" or choice == "h": self.hit(hand) elif choice == "split" or choice == "sp": if split: self.split(hand, self.bets[h]) elif hand.cards[0].rank == 1: if debug: print "Can't split on split Aces" elif len(self.player_hands) == self.max_split_hands: if debug: print "Can't split hands more than " + str(self.max_split_hands) + " times" else: if debug: print "Can only split on matching cards" elif choice == "double" or choice == "d": self.double(h) elif choice == "stand" or choice == "s": completed_hand = True self.in_play[h] = False elif choice == "rh": self.player_surrendered = True completed_hand = True self.in_play[h] = False else: if debug: print "Invalid operation" minimum, maximum = hand_value(hand) if minimum > 21: completed_hand = True self.in_play[h] = False def hit(self, hand): self.deck.move_cards(hand, 1) minimum, maximum = hand_value(hand) if debug: print str(hand) + " " + str((minimum, maximum)) if minimum > 21: if debug: print "Busted...\n" def split(self, hand, bet): new_hand = Hand("Split") new_hand.add_card(hand.cards[1]) hand.remove_card(hand.cards[1]) self.deck.move_cards(hand, 1) self.deck.move_cards(new_hand, 1) self.player_hands.append(new_hand) self.player_chips = self.player_chips - bet self.bets.append(bet) self.in_play.append(True) def double(self, hand_index): self.player_chips = self.player_chips - self.bets[hand_index] self.bets[hand_index] = 2 * self.bets[hand_index] self.doubled[hand_index] = True self.hit(self.player_hands[hand_index]) def handle_dealer(self): if debug: print str(self.dealer_hand) + str(hand_value(self.dealer_hand)) minimum, maximum = hand_value(self.dealer_hand) if maximum == 21: if debug: print "Dealer hit blackjack..." elif maximum > 17: if debug: print "Dealer stands" else: while maximum < 17 or (minimum + 10 <= 17 and [c.rank for c in self.dealer_hand.cards].count(1) >= 1): if debug: print "Dealer hits" self.deck.move_cards(self.dealer_hand, 1) if debug: print str(self.dealer_hand) + str(hand_value(self.dealer_hand)) minimum, maximum = hand_value(self.dealer_hand) def check_bets(self): wins = 0 pushes = 0 losses = 0 dealer_min, dealer_max = hand_value(self.dealer_hand) dealer_bust = False if dealer_min > 21: dealer_bust = True if debug: print "Dealer Busted!" for h in range(len(self.player_hands)): if self.player_surrendered: if debug: print "Player surrendered" self.player_chips = self.player_chips + 0.5 * self.bets[h] self.player_surrendered = False losses = 1 break hand = self.player_hands[h] minimum, maximum = hand_value(hand) if minimum == 21 or maximum == 21: if len(self.player_hands) == 1 and len(hand.cards) == 2: if dealer_max == 21 and len(self.dealer_hand.cards) == 2: if debug: print str(hand) + " hit Blackjack but so did dealer, so a push" self.player_chips = self.player_chips + self.bets[h] pushes = pushes + 1 else: if debug: print str(hand) + " hit Blackjack!" self.player_chips = self.player_chips + 5*self.bets[h]/2 wins = wins + 1 if self.doubled[h]: wins = wins + 1 else: if dealer_max == 21 and len(self.dealer_hand.cards) == 2: if debug: print str(hand) + " hit 21 but so did dealer, so a push" self.player_chips = self.player_chips + self.bets[h] pushes = pushes + 1 else: if debug: print str(hand) + " hit 21!" self.player_chips = self.player_chips + 2*self.bets[h] wins = wins + 1 if self.doubled[h]: wins = wins + 1 elif dealer_bust and minimum < 21: if debug: print str(hand) + " wins " + str(self.bets[h]) self.player_chips = self.player_chips + 2*self.bets[h] wins = wins + 1 if self.doubled[h]: wins = wins + 1 else: if dealer_max > 22: dealer_max = dealer_min if maximum > 21: maximum = minimum if maximum < 21: if maximum > dealer_max: if debug: print str(hand) + " wins " + str(self.bets[h]) self.player_chips = self.player_chips + 2*self.bets[h] wins = wins + 1 if self.doubled[h]: wins = wins + 1 elif maximum == dealer_max: if debug: print str(hand) + " pushed" self.player_chips = self.player_chips + self.bets[h] pushes = pushes + 1 else: if debug: print str(hand) + " lost" losses = losses + 1 else: if debug: print str(hand) + " busted and lost" losses = losses + 1 if losses == 0: self.win_streak = self.win_streak + wins else: self.win_streak = 0 self.reset() def reset(self): self.player_hands = [Hand(self.player_name)] self.in_play = [True] self.doubled = [False] self.dealer_hand = Hand("Dealer") self.bets = [] self.init_deck()
class Blackjack: def __init__(self,h,n=5,b=1): self.Stat = Stats() self.number_of_decks = n self.house = h self.players = [] self.deck = Deck(self.number_of_decks) self.minimum_bet = b self.deck.shuffle() def throw_all_hands(self): for a in self.players: a.throw_hand() a.clear_bet() self.house.throw_hand() def add_player(self,p): self.players.append(p) def remove_player(self,p): [a for a in self.players if a.name == p] def play(self,silent=False): #Check if house is bankrupt if (self.house.money <= 0): print "House is bankrupt" return True print "*** Game started ***" all_players_lost = self.play_round(silent) print "cards left %d" % (self.deck.cards_left()) print "*** Game End ***\n" return all_players_lost def pop_card(self): #All cards are used create an new deck of cards if self.deck.cards_left() == 0: self.deck = Deck(self.number_of_decks) self.deck.shuffle() return self.deck.pop_card() def start_deal(self,silent): #Has all player money left for a in self.players: if a.money <= 0: print "%s lost all money" % (a.name) self.players.remove(a) #Check if all players busted if (len(self.players) == 0): print "House has won!" return True #Players gets their first cards for a in self.players: c = self.pop_card() a.place_bet(self.minimum_bet) a.take_card(c) if not silent: print "%s hand %d=[%s]" % (a.name,a.sum_hand(),a.get_hand()) #House gets it's first card c = self.pop_card() self.house.take_card(c) if not silent: print "House hand %d" % (c.value) #Let players know what card house got for a in self.players: a.add_house_card(c) #House gets it's second card but is not #showed to players. c = self.pop_card() self.house.take_card(c) return False def play_round(self,silent): all_players_lost = self.start_deal(silent) #Now players can decide if they should #have more cards or stop for a in self.players: while a.more_cards(): c = self.pop_card() a.take_card(c) if not silent: print "%s hand %d=[%s]" % (a.name,a.sum_hand(),a.get_hand()) #House turn to pick cards while self.house.more_cards(): self.house.take_card( self.pop_card()) #Track all stats self.Stat.collect_data(self.house,self.players) #Round is over throw the cards holding #and clear all bets. self.throw_all_hands() return all_players_lost def show_results(self): print "not implemented yet"