#                             BlackJack                             #
#                                                                   #
#                        Created by Tjampman                        #
#                                                                   #
#####################################################################
#                                                                   #
#                     BlackJack ver. 0.2.1 Alpha                    #
#   You can read version history in 'BlackJack Ducumentation.txt'   #
#                Check out the rules of blackjack at                #
#                   http://www.blackjackinfo.com/                   #
#                                                                   #
#####################################################################

# importing modules
import random
from time import sleep

# Funcions
def hit_or_stand():
    print "Do you want to\n1 hit or\n2 stand?"

def shuffle():
    """deck = shuffle -> deck will be created,\nand
    consist of 52 cards of 4 colours."""
    return [[ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king],
            [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king],
            [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king],
            [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]]


def deal(hand, deck):
    """deal(hand, deck) -> one card will be cut from
    the deck\nand copied to the hand."""
    # We need a colour and a value using
    # random.randrange to get a random card from
    # the deck
    colour = random.randrange(0, len(deck))
    if len(deck[colour]) == 0:
        del deck[colour]
        colour = random.randrange(0, len(deck))
            
    value = random.randrange(0, len(deck[colour]))
    # Adding the card to hand
    hand.append(deck[colour][value])
    # And deleting the card from the deck
    del(deck[colour][value])

def sum_(hand):
    """sum_(hand) -> returns the value that the
    player holds"""
    t = i = 0
    for x in hand:
	t += x  # This counts the value of the hand, counting ace as 11
	if x == ace:
	    i = i + 1   #Counts aces in hand
    if t == 21 and len(hand) == 2:
	    return "BlackJack"
    elif i == 0:    # If no ace's: do this
	if len(hand) == 5 and t <= 21:
            return 21   # If you hold five cards, it counts as 21 but > BJ
	else:
	    return t
    elif i > 0:     # If you hold ace(s) the sum must be calculated differently
        # 'Hard sum' is when you have no ace or ace(s) counts as 1
	hard = t - i*10
	# 'Soft sum' is the sum of hand carrying an ace with the value of 11
	soft = t - (i-1)*10 # Hence 'i' is one less then with hard sum
	if len(hand) == 5 and hard <= 21:
	    return 21	
	elif t > 21 and soft > 21:
	    return hard
	else:
	    return hard, soft
    else:   # Just in case
	return "Out of Bounds"

def count(deck, i=0):
    """count(deck) -> returns the amount of cards in the deck."""
    for x in deck:
        i += len(x)
    return i

def dealer(hand):
    """Dealer(hand) -> returns 1 if dealer has to hit"""
    if (sum_(hand) < 17) or ((type(sum_(hand)) == tuple) and (sum_(hand)[0] <= 17)):
        return 1
    else:
        return 0

def win_lose(dhand, phand):
    """Win_lose(dhand, phand) -> returns the hand that wins.\n
    Dhand is the dealers hand and phand is the players hand."""
    play = sum_(phand)
    deal = sum_(dhand)
    if play == tuple:
        play = play[1]
    if deal == tuple:
        deal = deal[1]
        
    if ((play > deal) or (deal > 21)) and (play <= 21):
        return 1
    elif (play < deal) or (play > 21):
        return 0
    else:
        return 2

# Defining card values
# As default ace is 11. Check sum_() above.
ace = 11
jack = queen = king = 10

# Starting with a fresh deck of cards
deck_cards = shuffle()
# Game is 1 to start the first while loop
game = "1"
bust = 0
while game != "2":
    if game == "1": # Only '2' exits the loop
        hand = []   # Hand is allways empty when starting
        dhand = []
        if count(deck_cards) < 20:   # if needed: shufle
            deck_cards = shuffle()
            print "Shufling"
            print "."
            sleep(1)
            print "."
            sleep(1)
            print "."
        deal(hand, deck_cards)
        deal(hand, deck_cards)
        if type(sum_(hand))== tuple:    #i.e. more than one value
                                        # make sure the string can handle that
            print "You hold:", hand, "sum: %s/%s" % (sum_(hand)[0], sum_(hand)[1])
        else:
            print "you hold:", hand, "sum: %s" % (sum_(hand))

        if sum_(hand) != "BlackJack":
            hit_or_stand()
            play = raw_input()

            while play != "2":
                if play == "1": # Same as in the first loop
                    deal(hand, deck_cards)
                    if sum_(hand) > 21 and type(sum_(hand)) == int:
                        bust = 1
                        print "You busted with", hand, "sum: %s" % (sum_(hand))
                        break
                                
                    if type(sum_(hand))== tuple:
                        print "You hold:", hand, "sum: %s/%s" % (sum_(hand)[0], sum_(hand)[1])
                    else:
                        print "You hold:", hand, "sum: %s" % (sum_(hand))
                    hit_or_stand()
                    play = raw_input()
                    
                else:
                    hit_or_stand()
                    play = raw_input()

        # Dealers turn:
        if not bust:
            deal(dhand, deck_cards)
            deal(dhand, deck_cards)
            print dhand
            sleep(1)
            while dealer(dhand):
                deal(dhand, deck_cards)
                print dhand
                sleep(1)


            if win_lose(dhand, hand) == 1:
                print "Player wins"
            elif win_lose(dhand, hand) == 0:
                print "Dealer wins"
            elif win_lose(dhand, hand) == 2:
                print "Push"
            else:
                 print "Somethings are wrong"
        else:
            print "Dealer wins"
        print "dealer has:", sum_(dhand), "player has:", sum_(hand)
        sleep(3)
        print ""
        print ""
        print len(deck_cards), "colours left"
        print count(deck_cards), "cards left"
        # blocked out for testing
        #game = raw_input("Play again?\n1 Yes\n2 No\n")
    else:
        game = raw_input("Play again?\n1 Yes\n2 No\n")
print "end"

