pythonclassobjectcomparison

How do I check if multiple returned class objects have the same value for comparison and edit only one, while keeping both for addition later


I'm currently creating a blackjack card game using OOP and the blessed library. As it stands I create the card objects which return a class object to me:

player_card_data = [<blackjack.card.Card object at 0x7f3900226330>, <blackjack.card.Card object at 0x7f3900225f70>]

I can then dive into those and get the card value:

player_card_data[0].card_value

This, for example, gives me 10.

My current issue is I want to account for aces, which earlier in my program I set to the value 11. I need to check and see what the score is so that the hand does not automatically go bust by drawing 2 aces (22), I'm currently building it into a reusable function and figure I'd need to do a simple compariosn operator.

(This is also currently what I am trying / have tried and so far no results.)

def calculate_score(player_card_data):
  """
  Calculates the score of the players cards, accounting for aces, then returns the score
  """
  if player_card_data[0].card_value == player_card_data[1].card_value:
    player_card_data[0].card_value = 1

  player_score = player_card_data[0].card_value + player_card_data[1].card_value
  return player_score

The problem I see with this while it works with two cards, it doesn't scale and completely breaks if more than 3 cards are in the player_card_data object. I was thinking of using *args but i'm not sure if this would work / have not been able to get it working in this situation. I am not looking to make it into a set as I need both values for addition later in the function.

The card objects are initially populated into a deck array, which the cards are then drawn from, then deleted from this deck. This ensures that the objects i'm manipulating only exist for the round of blackjack being played and as a result won't affect the deck as after the current round, no longer exist. I am aware that manipulating objects is generally bad practice but if the object no longer exists after the round figured it isn't a severe issue.

I do it like this to create a finite number of plays before the deck needs to be "reshuffled" (recreated).

The data that's fed in to create the card objects is housed outside the card class inside objects and arrays:

suits = ["Spades", "Hearts", "Clubs", "Diamonds"]
suits_values = {"Spades":"\u2664", "Hearts":"\u2661", "Clubs": "\u2667", "Diamonds": "\u2662"}
cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
cards_values = {"A": 11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10, "J":10, "Q":10, "K":10}

which is then sent to the card class and populated in the deck to make the 52 unique card objects:

def create_deck():
  """
  Creates a new deck of 52 card objects by passing each card suit, card and card value
  into the Card class, then appending it to the deck array.
  """
  # we now create our deck of cards
  deck = []
  # Loop for every type of suit
  for suit in suits:
    cards = ["A", "A", "A", "A"]
    # Loop for every type of card in a suit
    for card in cards:
      # Adding card to the deck
      deck.append(Card(suits_values[suit], card, cards_values[card]))

  return deck

The cards once "drawn" in the round are removed completely from the deck, im looking to find a way to calculate the score based on if the player or CPU draws multiple "Ace" (11) card objects. I do this because I want to draw the cards onto the terminal with blessed later on, so I need to store them in an object to access later.

How could I go about making this scalable for any number of cards?


Solution

  • An alternative approach is to consider every ace as having value 1, and if the sum of a hand containing at least one ace is 11 or less, add a bonus of 10. This works because at most one of the aces can be assigned a value of 11 without exceeding 21.