0

I am creating a simplified blackjack game, and when game over is called in one of my functions, it is not being registered in the 'while' loop, and it just starts over. I've tried debugging, and I can see when game_over is called, however the while loop continues. I know there is definitely an easier way to write this, but in the spirit of learning I am just writing it in the way that immediately makes sense and will clean it later. Thank you.

start_game = (input("Do you want to play a game of BlackJack?  Type 'y' or 'n': ")).lower()

if start_game == 'y':
  def deal_card(hand):
    cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
    hand.append(random.choice(cards))
  
  def calculate_score(hand):
    score = sum(hand)
    if score == 21:
      return 0
      game_over = True
    elif score > 21:
      new_hand = []
      for cards in hand:
        if cards == 11:
          cards = 1
          new_hand.append(cards)
          if sum(new_hand) == 2:
            new_hand = [11, 1]
        else:
          new_hand.append(cards)
      score = sum(new_hand)
      return score
      game_over = True
    else:
      return score
      
  def compare(user, pc):
    if sum(user) == 0:
      print("You got BlackJack!  You win.")
    elif sum(pc) == 0:
      print("Computer got BlackJack!  You lose.")
    elif sum(user) > 21:
      print("You busted your load.  You lose.")
    elif sum(pc) > 21:
      print("The computer busted his load.  You win.")
    elif sum(user) > sum(pc):
      print("You win.")
    else:
      print("You lose")
    game_over = True

  user_hand = []
  deal_card(user_hand)
  deal_card(user_hand)
  
  pc_hand = []
  deal_card(pc_hand)
  deal_card(pc_hand)
  
  game_over = False
  while not game_over:
    print(f"Your cards: {user_hand}, current score: {sum(user_hand)}")
    print(f"Computer's first card: {pc_hand[0]}")
    hit_me = (input("Type 'y' to get another card, type 'n' to hold: ")).lower()
    if hit_me == 'n':
      print(f"Your final hand: {user_hand}, final score: {calculate_score(user_hand)}")
      pc_done = False
      while not pc_done:
        if calculate_score(pc_hand) < 17 and calculate_score(pc_hand) > 0:
          deal_card(pc_hand)
        else:
          compare(user_hand, pc_hand)
    if hit_me == 'y':
      deal_card(user_hand)
      calculate_score(user_hand)
    
  print(f"Your final hand: {user_hand}, final score: {calculate_score(user_hand)}\nComputer's final hand: {pc_hand}, final score: {calculate_score(pc_hand)}")
  • 1
    Anything after a `return` in a function will never be executed... – BeRT2me Sep 28 '22 at 23:45
  • 2
    It's generally poor design to define functions inside `if` blocks. Define the functions at top-level, and call them from the `if` code. – Barmar Sep 28 '22 at 23:46
  • 2
    `game_over` is a local variable in each of the functions. You need to declare `global game_over` for them to assign the global variable. – Barmar Sep 28 '22 at 23:47
  • 2
    Also, you need to look at python's variable scoping rules. you define `game_over` both in your main block and within each function. those are not the same variable and game_over in your while loop will never evaluate to False – Michael Delgado Sep 28 '22 at 23:47
  • 2
    I'd argue for returning `score, True` or `score, False` and assigning `score, game_over = calculate_score(hand)` rather than messing with global variables... @Barmar – BeRT2me Sep 28 '22 at 23:51
  • totally, or wrap this into a class. it seems that the OP is trying to rely on a combination of functions/method and global state, which makes sense for a card game. this is heading too much in an opinion-based and stylistic direction, but it's definitely true that the code needs a refactor *or* proper handling of globals (or both) – Michael Delgado Sep 28 '22 at 23:54
  • Ye, the greater issue is still not understanding how `return` works here. Even if `game_over` were declared as global earlier on, it'd never get set with what OP has. – BeRT2me Sep 28 '22 at 23:58

0 Answers0