Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Python Blackjack Game Here are some special cases to consider. If the Dealer goe

ID: 3796272 • Letter: P

Question

Python Blackjack Game

Here are some special cases to consider. If the Dealer goes over 21, all players who are still standing win. But the players that are not standing have already lost. If the Dealer does not go over 21 but stands on say 19 points then all players having points greater than 19 win. All players having points less than 19 lose. All players having points equal to 19 tie. The program should stop asking to hit if the player gets 21 points.

Output should look like this:

Code so far: (The code in Play should be edited to the conditions mentioned in bold above)

Please Write code in Python only

import random

class Card (object):
RANKS = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

SUITS = ('S', 'D', 'H', 'C')

def __init__ (self, rank = 12, suit = 'S'):
    if (rank in Card.RANKS):
      self.rank = rank
    else:
      self.rank = 12

    if (suit in Card.SUITS):
      self.suit = suit
    else:
      self.suit = 'S'

def __str__ (self):
    if self.rank == 1:
      rank = 'A'
    elif self.rank == 13:
      rank = 'K'
    elif self.rank == 12:
      rank = 'Q'
    elif self.rank == 11:
      rank = 'J'
    else:
      rank = self.rank
    return str(rank) + self.suit

def __eq__ (self, other):
    return (self.rank == other.rank)

def __ne__ (self, other):
    return (self.rank != other.rank)

def __lt__ (self, other):
    return (self.rank < other.rank)

def __le__ (self, other):
    return (self.rank <= other.rank)

def __gt__ (self, other):
    return (self.rank > other.rank)

def __ge__ (self, other):
    return (self.rank >= other.rank)

class Deck (object):
def __init__ (self):
    self.deck = []
    for suit in Card.SUITS:
      for rank in Card.RANKS:
        card = Card (rank, suit)
        self.deck.append(card)
       
def shuffle (self):
    random.shuffle (self.deck)

def deal (self):
    if len(self.deck) == 0:
      return None
    else:
      return self.deck.pop(0)

class Player (object):
# cards is a list of card objects
def __init__ (self, cards):
    self.cards = cards

def hit (self, card):
    self.cards.append(card)

def getPoints (self):
    count = 0
    for card in self.cards:
      if card.rank > 9:
        count += 10
      elif card.rank == 1:
        count += 11
      else:
        count += card.rank

    # deduct 10 if Ace is there and needed as 1
    for card in self.cards:
      if count <= 21:
        break
      elif card.rank == 1:
        count = count - 10
   
    return count

# does the player have 21 points or not
def hasBlackjack (self):
    return len (self.cards) == 2 and self.getPoints() == 21

# complete the code so that the cards and points are printed
def __str__ (self):
    b = ''
    for a in self.cards:
        b += str(a) +" "
    return b + str(self.getPoints())

# Dealer class inherits from the Player class
class Dealer (Player):
def __init__ (self, cards):
    Player.__init__ (self, cards)
    self.show_one_card = True

# over-ride the hit() function in the parent class
# add cards while points < 17, then allow all to be shown
def hit (self, deck):
    self.show_one_card = False
    while self.getPoints() < 17:
      self.cards.append (deck.deal())

# return just one card if not hit yet by over-riding the str function
def __str__ (self):
    if self.show_one_card:
      return str(self.cards[0])
    else:
      return Player.__str__(self)

class Blackjack (object):
def __init__ (self, numPlayers = 1):
    self.deck = Deck()
    self.deck.shuffle()

    self.numPlayers = numPlayers
    self.Players = []

    # create the number of players specified
    # each player gets two cards
    for i in range (self.numPlayers):
      self.Players.append (Player([self.deck.deal(), self.deck.deal()]))

    # create the dealer
    # dealer gets two cards
    self.dealer = Dealer ([self.deck.deal(), self.deck.deal()])

def play (self):
    # Print the cards that each player has
    for i in range (self.numPlayers):
      print ('Player ' + str(i + 1) + ': ' + str(self.Players[i]))

    # Print the cards that the dealer has
    print ('Dealer: ' + str(self.dealer))

    # Each player hits until he says no
    playerPoints = []
    for i in range (self.numPlayers):
      while True:
        choice = input ('Player ' + str(i + 1) + ', do you want to hit? [y / n]: ')
        if choice in ('y', 'Y'):
          (self.Players[i]).hit (self.deck.deal())
          points = (self.Players[i]).getPoints()
          print ('Player ' + str(i + 1) + ': ' + str(self.Players[i]))
          if points >= 21:
            break
        else:
          break
      playerPoints.append ((self.Players[i]).getPoints())
    print(playerPoints)

    # Dealer's turn to hit
    self.dealer.hit (self.deck)
    dealerPoints = self.dealer.getPoints()
    print ('Dealer: ' + str(self.dealer) + ' - ' + str(dealerPoints))

    # determine the outcome; you will have to re-write the code
    # it was written for just one player having playerPoints
    # do not output result for dealer

    if (dealerPoints < playerPoints and playerPoints <= 21):
      print ('Player wins')
    elif dealerPoints == playerPoints:
      if self.player.hasBlackjack() and not self.dealer.hasBlackjack():
        print ('Player wins')
      elif not self.player.hasBlackjack() and self.dealer.hasBlackjack():
        print ('Dealer wins')
      else:
        print ('There is a tie')

def main():

    numPlayers = eval (input ('Enter number of players: '))
    while (numPlayers < 1 or numPlayers > 6):
        numPlayers = eval (input ('Enter number of players: '))
    game = Blackjack (numPlayers)
    game.play()

   
main()

Explanation / Answer

Python Blackjack Game:

import random
DEFAULT_CHIPS = 21

class Card(object):

cardname = {1:"Ace", 2:"Two", 3:"Three", 4:"Four", 5:"Five", 6:"Six", 7:"Seven",
8:"Eight", 9:"Nine", 10:"Ten", 11:"Jack", 12:"Queen", 13:"King"}

def __init__(self, value, suit):
self.name = self.card_to_name[value]
self.suit = suit
self.title = "%s of %s" % (self.name, self.suit)
self.score = min(value, 10)

def __repr__(self):
return self.title

class Hand(object):
def __init__(self, cards):
self.hand = cards

def get_scores(self):
num_aces = sum(card.name == "Ace" for card in self.hand)
score = sum(card.score for card in self.hand)
return [score + i*10 for i in range(num_aces+1)]

def possible_scores(self):
return [s for s in self.get_scores() if s <= 21]

def __repr__(self):
return str(self.hand)

class Deck(object):
unshuffled_deck = [Card(card, suit) for card in range(1, 14) for suit in ["Clubs", "Diamonds", "Hearts", "Spades"]]
def __init__(self, num_decks=1):
self.deck = self.unshuffled_deck * num_decks
random.shuffle(self.deck)

def deal_card(self):
return self.deck.pop()

def deal_hand(self):
return Hand([self.deal_card(), self.deal_card()])

class Player(object):
def __init__(self, name="Player 1", chips=DEFAULT_CHIPS):
self.name = name
self.chips = chips
self.current_bet = 0

def new_hand(self, hand):
self.hand = hand

def hit(self, card):
self.hand.hand.append(card)

def is_busted(self):
return len(self.hand.possible_scores()) == 0

def scores(self):
return self.hand.get_scores() if self.is_busted() else self.hand.possible_scores()

def __repr__(self):
player_str = self.name + "(BUSTED)" if self.is_busted() else self.name
return "Player: {} Chips: {} Current Bet: {} Cards: {} Score: {}".format(
player_str, self.chips, self.current_bet, self.hand, self.scores())

if __name__ == "__main__":
d = Deck()
print d.deck
h = d.deal_hand()
p = Player()
p.new_hand(h)
print p
p.hit(d.deal_card())
print p