Daily Challenge #128 - Blackjack Scorer

thepracticaldev profile image dev.to staff ・1 min read

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 yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff


The hardworking team behind dev.to ❤️


Editor guide

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


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:


"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?