[Tutor] Newbie Q's

Jeff Shannon jeff@ccvcorp.com
Tue, 11 Jun 2002 09:59:07 -0700


alan.gauld@bt.com wrote:

> > The biggest difficulty I'm having is dealing with
> > aces, which can be valued at 1 or 11. I thought I had
> > everything figured out, until a hand came up that had
> > two aces in it :-)

> Special cases need special code. For blackjack you would
> count the Ace as 11 if the total was <= 21 else count them
> as 1...
> So something like the following untested code:
>
> def AddCards(cardlist):
>     tot = reduce(operator.add, cardlist)
>     if  tot > 21: #too high
>        while 11 in cardlist:   #do we have high aces?
>          if tot-10 <= 21:      # total too high so use low ace
>            pos = cardist.index(11)
>            cardlist[pos] = 1   # change from 11 to 1
>            tot = reduce(operator.add, cardlist)
>     return tot

It seems to me that this code will also cause problems if there are
two aces.  :)  This will reduce *all* aces in the hand to 1, not just
enough of them to drop the score just below 21.  Also, it's not really
necessary to check whether switching the ace from high to low will
drop the total below 21 -- ISTM that any high ace should be converted
to low before declaring the hand busted.  Perhaps something like this
would work better...

def AddCards(cardlist):
    tot = reduce(operator.add, cardlist)
    while tot > 21 and 11 in cardlist:
        pos = cardlist.index(11)
        cardlist[pos] = 1
        tot = reduce(operator.add, cardlist)
    return tot

This is still not terribly efficient ('value in list' and list.index()
are slow for large lists), but should be good enough for a blackjack
game (which would not have large lists or too terribly strict speed
requirements ;) ).  One thing that could speed it up would be to
combine the two searches:

def AddCards(cardlist):
    tot = reduce(operator.add, cardlist)
    while tot > 21:
        pos = cardlist.index(11)   # returns the index, or -1 if not
found
        if pos >= 0:
            cardlist[pos] = 1
            tot = reduce(operator.add, cardlist)
        else:
            break    # exit 'while' if there are no high aces
    return tot

I'm sure that further improvements are possible (such as eliminating
the multiple reduce() calls), but this should be good enough for now.
:)

Jeff Shannon
Technician/Programmer
Credit International