DEV Community

dev.to staff
dev.to 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.

Scoring:
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"]
["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!

Top comments (3)

Collapse
 
edh_developer profile image
edh_developer

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
    else:
      total += int(c)


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

  if total > 21:
    print "Busted!"

  return total

Collapse
 
vladignatyev profile image
Vladimir Ignatev • 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)
        else:
            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"],
    ["A", "J"],
    ["A", "10", "A"],
    ["5", "3", "7"],
    ["5", "4", "3", "2", "A", "K"]
]

for case in cases:
    print(case)
    print(bj_score(case))

Collapse
 
edh_developer profile image
edh_developer

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