DEV Community staff staff

Posted on

Daily Challenge #128 - Blackjack Scorer

Write a function that determines the score of a hand in a standard game of Blackjack 21. The function will receive an array of strings representing the cards that are in the hand of the player. Please return the score of the hand as an integer.

Number cards count as their face values. Royalty count as 10s. An Ace can be either 11 or 1.

Return the score closest to 21. If the score is greater than 21, return the score and say "Busted!".

Test cases:

["A", "J"]
["A", "10", "A"]
["5", "3", "7"]
["5", "4", "3", "2", "A", "K"] 

Happy coding!

This challenge comes from jodymgustafson on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email with your suggestions!

Top comments (4)

edh_developer profile image

Python, with a couple assumptions:

  • ["A","10","A"] should return 12, not 22.
  • If the function is supposed to say "busted", it would have to do that before returning the corresponding numerical value.

def score(cards):
  facecards = ["K","Q","J"]
  total = 0
  aces = 0

  for c in cards:
    if c in facecards:
      total += 10
    elif c == "A":
      total += 11
      aces += 1
      total += int(c)

  for _ in range(aces):
    if total > 21:
      total -= 10

  if total > 21:
    print "Busted!"

  return total

vladignatyev profile image
Vladimir Ignatyev • Edited

My solution uses itertools.product to compute possible variations of Ace counting.

from itertools import product

def score(hand):
    royalty = ('J', 'Q', 'K',)
    ace = ('A',)
    aces = 0
    _score = 0

    for card in hand:
        if card in royalty:
            _score += 10
        elif card not in ace:
            _score += int(card)
            aces += 1

    if aces == 0:
        return _score

    aces_combinations = []

    variations = [_score + sum(ace_values) for ace_values in product((1,11), repeat=aces)]

    variations_vs_delta = [abs(21 - _s) for _s in variations]
    return variations[variations_vs_delta.index(min(variations_vs_delta))]

def bj_score(hand):
    s = score(hand)
    if s > 21:
        print 'Busted!'
    return s

cases = [
    ["A", "J"],
    ["A", "10", "A"],
    ["5", "3", "7"],
    ["5", "4", "3", "2", "A", "K"]

for case in cases:

edh_developer profile image

"closest to 21"? I'm guessing you mean "Closest to 21 without going over. If it's not possible to prevent going over, return the lowest score possible."

Is that correct?