Beispiel #1
0
 def test_deck(self):
     '''test deck'''
     deck = Deck(52)
     deck.shuffle()
     for index in range(52):
         card = deck.deal()
         print('{}. {}'.format(index + 1, card.__str__()))
     no_of_cards = len(deck)
     self.assertEqual(no_of_cards, 0)
Beispiel #2
0
class Game:
    '''game class'''
    # pylint: disable=too-many-instance-attributes

    bust = False
    bj_pays = 3/2
    bj_player = False
    bj_dealer = False
    total_p = 0
    total_d = 0

    def __init__(self):
        '''
        game init
        '''
        #print(Deck())
        print('BlackJack pays {}'.format(self.bj_pays))
        self.deck = Deck()
        self.player = Player()
        self.dealer = Dealer()
        self.deck.shuffle()

    def deal_two_foreach(self):
        '''
        deal 2 cards for each player
        '''
        #one for the player
        card = self.deck.deal()
        self.player.hit(card)
        #one for the dealer, hidden
        card = self.deck.deal(message=False)
        card.hide()# one card of the dealer is hidden
        self.dealer.hit(card)
        #one for the player
        card = self.deck.deal(message=False)
        self.player.hit(card)
        #one for the dealer
        card = self.deck.deal(message=False)
        self.dealer.hit(card)
        #show table
        self.deck.draw_table(self.player.cards, self.dealer.cards)

    def check_hand(self, cards):
        '''
        counts the number of aces
        calculates hand total
        checks if busted
        @param cards
        @return total
        '''
        total = 0
        has_ace = 0
        for card in cards:
            #count aces
            if card.value == 11:
                has_ace += 1
            total += card.value
        #if total exceds 21, set aces value to 1 until total gets to 21 or below
        while total > 21 and has_ace > 0:
            total = total - 10
            has_ace -= 1
        #busted
        if total > 21:
            self.bust = True
        return total

    def players_run(self):
        '''
        hit or stand actions for the player
        '''
        while self.bj_player is False:

            self.total_p = self.check_hand(self.player.cards)
            #check hand
            if self.total_p == 21:
                #player has 21
                break
            elif self.bust:
                #bust
                print('You lost.')
                self.play_again()
                return
            else:
                while True:
                    try:
                        action = int(input('Press 1 for Hit or 2 for Stand: '))
                        break
                    except ValueError:
                        pass
                if action == 1:
                    #one for the player
                    card = self.deck.deal()
                    self.player.hit(card)
                    #show table
                    self.deck.draw_table(self.player.cards, self.dealer.cards)
                else:
                    #stand
                    self.player.stand()
                    break

    def dealers_run(self):
        '''
        hit or stand actions for the dealer
        '''
        #show hidden card
        self.dealer.cards[0].show()
        self.deck.draw_table(self.player.cards, self.dealer.cards)
        while self.bj_dealer is False and self.bj_player is False:
            # if the player has blackjack and the dealer is not,
            # dealing more cards doesn't make sense
            self.total_d = self.check_hand(self.dealer.cards)
            #check hand
            if self.total_d == 21:
                #dealer has 21
                break
            elif self.bust is True:
                #bust
                print('You won {} chip(s).'.format(2*self.player.bet_value))
                self.player.chips += 2*self.player.bet_value
                self.play_again()
                return
            elif self.total_d <= self.dealer.draw_until:
                card = self.deck.deal()
                self.dealer.hit(card)
                self.deck.draw_table(self.player.cards, self.dealer.cards)
            elif self.total_d >= self.dealer.must_stand:
                self.dealer.stand()
                break

    def conclude(self):
        '''
        decide who the winner is
        '''
        if (self.bj_player == True and self.bj_dealer == True) or (self.total_p == self.total_d):
            # tie
            print('Tie game')
            self.player.chips += self.player.bet_value
        elif self.bj_player:
            print('You won {} chip(s)'.format((self.bj_pays+1)*self.player.bet_value))
            self.player.chips += (self.bj_pays+1)*self.player.bet_value
        elif self.total_p > self.total_d:
            print('You won {} chip(s)'.format(2*self.player.bet_value))
            self.player.chips += 2*self.player.bet_value
        else:
            print('You lost.')
        self.play_again()

    def play(self):
        '''
        game thread
        '''
        #check if player has chips
        if self.player.chips == 0:
            print('You don\'t have any chips')
            quit()
        #check if enough cards
        if len(self.deck.cards) < self.deck.min_in_shoe:
            print('Not enough cards')
            self.deck.reset()
        # place bet
        print('You have {} chips'.format(self.player.chips))
        self.player.bet()
        #deal cards
        self.deal_two_foreach()
        # check player for blackjack
        self.total_p = self.check_hand(self.player.cards)
        self.bj_player = (self.total_p == 21)
        # check dealer for blackjack
        self.total_d = self.check_hand(self.dealer.cards)
        self.bj_dealer = (self.total_d == 21)
        #player first
        self.players_run()
        #dealer second
        self.dealers_run()
        #decide who the winner is
        self.conclude()

    def play_again(self):
        '''
        new game
        '''
        while True:
            action = str(input('Play again? (y/n)'))
            if action.lower() == 'y':
                self.reset()
                self.play()
                break
            elif action.lower() == 'n':
                quit()

    def reset(self):
        '''
        reset game
        '''
        self.player.cards = []
        self.dealer.cards = []
        self.player.bet_value = 1
        self.bust = False
        self.bj_player = False
        self.bj_dealer = False
        self.total_p = 0
        self.total_d = 0
        
Beispiel #3
0
from classes.card import Card
from classes.deck import Deck
from classes.player import Player

player_one = Player("One")
player_two = Player("Two")

new_deck = Deck()
new_deck.shuffle()

for x in range(26):
    player_one.add_cards(new_deck.deal_one())
    player_two.add_cards(new_deck.deal_one())

game_on = True

round_number = 0

while game_on:

    round_number += 1
    print(f"Round {round_number}")

    if len(player_one.all_cards) == 0:
        print("Player one, out of cards! Player two wins!")
        game_on = False
        break

    if len(player_two.all_cards) == 0:
        print("Player two, out of cards! Player one wins!")
        game_on = False
Beispiel #4
0
class Game:
	"""This is a class for controlling the operations of the blackjack game. 

	Attributes: 
        winnings (int) -- the amount of money the player has.
	"""
	def __init__(self):
		"""The constructor for the Game class."""
		self.winnings = 100

	def play(self):
		"""The main controller for playing the game of Blackjack."""

		play_again = True
			
		while play_again:

			self.deck = Deck()
			self.deck.shuffle()

			# Initialize player and dealer's hands
			self.player_hand = Hand()
			self.dealer_hand = Hand(isDealer = True)

			self.display_empty_game()

			self.player_hand.prompt_for_wager(self.winnings)
			self.winnings -= self.player_hand.wager  # remove wager from current winnings

			self.deal_cards()

			self.dealer_hand.cards[first_card].flip_face_down()  # flip dealer's first card face down
			
			self.display_state_of_game(self.player_hand)


			choice = 'n'  # holder value for choice variable
			
			# player must have enough money to wager and cards in equal rank to split his or her hand
			if (self.winnings > self.player_hand.wager) and (self.player_hand.cards[first_card].rank == self.player_hand.cards[second_card].rank):
				choice = util.get_valid_input('\nWould you like to split? (Y)es or (N)o?: ', ['y','n'], 'Not a valid response')
				if choice == 'y':
					self.split_hand()
					self.play_split_hand()

			if choice != 'y':  # player did not choose to split or did not have ability to
				self.player_turn(self.player_hand)
				
				# dealer only needs to play if player has not gone over 21 and does not have blackjack
				if self.player_hand.get_over_21_status():
					self.dealer_hand.cards[first_card].flip_face_up()
				elif self.player_hand.has_blackjack():
					self.dealer_hand.cards[first_card].flip_face_up()
				else:
					self.dealer_turn(self.player_hand)
				
				self.resolve_wager(self.player_hand)

				self.display_state_of_game(self.player_hand)


			if self.player_hand.is_split:  # print outcome of both hands
				print('\nThe dealer finished with a score of',self.dealer_hand.sum_of_cards)
				print('Your first hand finished with a score of', self.player_hand.sum_of_cards)
				self.display_final_outcome(self.player_hand)
				
				print('\nThe dealer finished with a score of',self.dealer_hand.sum_of_cards)
				print('You second hand finished with a score of', self.player_second_hand.sum_of_cards)
				self.display_final_outcome(self.player_second_hand)
			else:
				print('\nThe dealer finished with a score of',self.dealer_hand.sum_of_cards)
				print('You finished with a score of', self.player_hand.sum_of_cards)
				self.display_final_outcome(self.player_hand)


			response = util.get_valid_input('Would you like to play again? (Y)es or (N)o: ', ['y','n'], 'Not a valid response')
			
			if self.winnings == 0:
				print('Sorry, you ran out of money. Goodbye.')
			elif response == 'n':
				print('Thanks for playing. Goodbye.')
				break


	def deal_cards(self):
		"""Deal two cards to each the player and the dealer."""
		for i in range(2):  # deal cards back and forth like a real game
			self.player_hand.add_card(self.deck.deal_card())
			self.dealer_hand.add_card(self.deck.deal_card())

	def player_turn(self, hand):
		"""Execute the user/player's turn while recommending the best strategy for beating the dealer.

		Keyword Arguments:
			hand (Hand) -- the player's hand playing the current turn.
		"""
		again = True
		while again and not hand.get_over_21_status():
			
			if hand.has_blackjack():  # stop turn of player has blackjack
				break
			
			self.display_state_of_game(hand)
			self.recommend_strategy(hand)

			if hand.wager > self.winnings:  # If the user does not have enough funds. Don't allow him or her to double down
				choice = util.get_valid_input('\n(H)it or (S)tand?: ', ['h', 's'], 'Invalid choice. Please choose "H" to hit or "S" to stand')
			else:
				choice = util.get_valid_input('\n(H)it, (S)tand, or (D)ouble Down?: ', ['h', 's', 'd'], 'Invalid choice. Please choose "H" to hit or "S" to stand')
			
			if choice == 'h':
				hand.add_card(self.deck.deal_card())
			elif choice == 'd':
				# double wager
				self.winnings -= hand.wager
				hand.wager += hand.wager
				
				# add only one card to hand. Player may not hit again
				hand.add_card(self.deck.deal_card())
				again = False  
			elif choice == 's':
				again = False

			self.display_state_of_game(hand)

	def recommend_strategy(self, player_hand):
		"""Inform the user of the statistically best move to make based on his or her hand sum, and the dealer's single visible card.

		Keyword Arguments:
			player_hand (Hand) -- the player's hand playing the current turn.
		"""
		Ace = 'A'
		if (player_hand.cards[first_card].rank == player_hand.cards[second_card].rank) and len(player_hand.cards) < 3:  # player has a pair on the first turn
			strategy = bs.make_pair_recommendation(player_hand.cards[first_card].rank, self.dealer_hand.cards[second_card].rank) # always check the dealer's face-up card (second card)
		elif player_hand.cards[first_card].rank != Ace and player_hand.cards[second_card].rank != Ace:  # user does not have an ace
			strategy = bs.make_hard_total_recommendation(player_hand.sum_of_cards, self.dealer_hand.cards[second_card].rank)
		elif player_hand.cards[first_card].rank != Ace and player_hand.cards[second_card].rank == Ace and len(player_hand.cards) < 3:  # user has an ace and a non-ace in the first hand
			strategy = bs.make_soft_total_recommendation(player_hand.cards[first_card].rank, self.dealer_hand.cards[second_card].rank)
		elif player_hand.cards[first_card].rank == Ace and player_hand.cards[second_card].rank != Ace and len(player_hand.cards) < 3:   # user has an ace and a non-ace in the first hand
			strategy = bs.make_soft_total_recommendation(player_hand.cards[second_card].rank, self.dealer_hand.cards[second_card].rank)
		else:
			strategy = bs.make_hard_total_recommendation(player_hand.sum_of_cards, self.dealer_hand.cards[second_card].rank)
		print('\nThe recommended strategy is to:', strategy)


	def dealer_turn(self, player_hand):
		"""Execute the dealer/computer player's turn. A dealer must always hit on a hand value less than 17.

		Keyword Arguments:
			player_hand (Hand) -- the player's hand playing the current turn.
		"""
		self.dealer_hand.cards[first_card].flip_face_up()
		self.display_state_of_game(player_hand)
		again = True
		while again:
			if self.dealer_hand.sum_of_cards < 17:  # dealer must hit when under 17
				self.dealer_hand.add_card(self.deck.deal_card())
			else:
				again = False
			time.sleep(.50)
			self.display_state_of_game(player_hand)


	def display_final_outcome(self, player_hand):
		"""Determine the final outcome of the hand against the dealer's hand to display the appropriate message to the user.

		Keyword Arguments:
			player_hand (Hand) -- the player's hand playing the current turn.
		"""
		if player_hand.has_blackjack():
			print('\nCongratualtions! You got Blackjack. You WIN!\n')
		elif player_hand.get_over_21_status():
			print('\nYou went over 21. You LOSE!\n')
		elif self.dealer_hand.get_over_21_status():
			print('\nThe dealer went over 21. You WIN!\n')
		elif self.dealer_hand.sum_of_cards < player_hand.sum_of_cards:
			print('\nYou WIN!\n')
		elif player_hand.sum_of_cards < self.dealer_hand.sum_of_cards:
			print('\nYou LOSE!\n')
		else:
			print('\nTie! The game results in a PUSH.\n')


	def resolve_wager(self, player_hand):
		"""Calculate the amount the player won or lost, and adjust his or her winnings appropriately.

		Keyword Arguments:
			player_hand (Hand) -- the player's hand playing the current turn.
		"""
		if player_hand.has_blackjack():
			self.winnings += player_hand.wager * 3
			player_hand.reset_wager()
		elif player_hand.get_over_21_status():  # player lost
			player_hand.reset_wager()
		elif self.dealer_hand.get_over_21_status():  # player won
			self.winnings += player_hand.wager * 2
			player_hand.reset_wager()
		elif player_hand.sum_of_cards < self.dealer_hand.sum_of_cards:  # player lost
			player_hand.reset_wager()
		elif self.dealer_hand.sum_of_cards < player_hand.sum_of_cards:  # player won
			self.winnings += player_hand.wager * 2
			player_hand.reset_wager()
		else:  # game ended in a push
			self.winnings += player_hand.wager
			player_hand.reset_wager()

	def display_empty_game(self):
		"""Print two empty cards for both the dealer and the player, as will as the player's current funds and bet."""
		util.clear_window()
		lines = [''] * max_card_height
		for i in range(2):  # display 2 cards
			lines[0] += '┌─────────┐'
			lines[1] += '│         │'
			lines[2] += '│         │'
			lines[3] += '│         │'
			lines[4] += '│         │'
			lines[5] += '│         │'
			lines[6] += '│         │' 
			lines[7] += '│         │'
			lines[8] += '└─────────┘'
		for line in lines:
			print(line)
		for line in lines:
			print(line)
		print('\n   Funds: ${} | Bet: ${}'.format(self.winnings, 0))  # display wager

	def display_state_of_game(self, player_hand):
		"""Print the dealer's hand, player's hand, current funds, and current bet amount to the console.

		Keyword Arguments:
			player_hand (Hand) -- the player's hand playing the current turn.
		"""
		time.sleep(.20)
		util.clear_window()
		self.dealer_hand.display_hand()
		player_hand.display_hand()
		print('\n   Funds: ${} | Bet: ${}'.format(self.winnings, player_hand.wager))  # display wager	

	
	# Methods used for gameplay when user splits his or her hand

	def play_split_hand(self):
		"""Play the rest of the game using two hands for the player rather than one."""
		self.player_turn(self.player_hand)
		self.player_turn(self.player_second_hand)
		
		self.dealer_turn(self.player_second_hand)
		
		self.resolve_wager(self.player_hand)
		self.resolve_wager(self.player_second_hand)

		self.display_state_of_game(self.player_second_hand)  # show the updated winnings and null bet amount after completed

	def split_hand(self):
		""" Create a second hand with a wager equal to that of the first hand so the user can play using both hands."""
		self.player_second_hand = Hand()
		self.player_second_hand.add_card(self.player_hand.remove_last_card())  # remove card from hand one and give it to hand two
		
		self.player_hand.indicate_hand_is_split()
		self.player_second_hand.indicate_hand_is_split()

		# deal a card to each hand
		self.player_hand.add_card(self.deck.deal_card())
		self.player_second_hand.add_card(self.deck.deal_card())

		# double wager
		self.winnings -= self.player_hand.wager
		self.player_second_hand.wager += self.player_hand.wager