# Arup Guha
# 10/29/2020
# Blackjack!
# On this day, we only got to figuring out two different ways to shuffle a deck.

import random

NUMCARDS = 52

def main():

    # Test making a deck.
    deck = makeUnshuffledDeck()
    print(deck)
    print()

    # Test our rifle shuffle.
    deck = rifleShufflenTimes(deck,7)
    print(deck)

# Returns an unshuffled deck of 52 cards.
def makeUnshuffledDeck():
    deck = []
    for i in range(NUMCARDS):
        deck.append(i)
    return deck

# Shuffles deck by repeatedly swapping randomly chosen cards.
def shuffleRandom(deck):

    # Cards in deck.
    size = len(deck)
    
    # Do this 1000 times.
    for i in range(1000):

        # Pick two random slots in the deck.
        c1 = random.randint(0,size-1)
        c2 = random.randint(0,size-1)

        # Swap the values in those two slots.
        temp = deck[c1]
        deck[c1] = deck[c2]
        deck[c2] = temp

    # Return the new list
    return deck

# Does n rifle shuffles on deck and returns the result in a new list.
# The original deck is unchanged.
def rifleShufflenTimes(deck,n):

    # Store the shuffle in a new place.
    mydeck = rifleShuffle(deck)

    # Now, do n-1 more shuffles.
    for i in range(n-1):
        mydeck = rifleShuffle(mydeck)

    # Now, return the resulting deck.
    return mydeck

# Leaves deck unchanged but returns a newly formed list created from
# deck by simulating a shuffle where you take 1 or 2 cards from one side
# and then swap sides.
def rifleShuffle(deck):

    # Store new cards here.
    newdeck = []

    # i is index into left half, j into right half.
    # So left is [0..len//2-1] and right is [len//2..len-1].
    i = 0
    j = len(deck)//2

    # Which side i take from.
    side = random.randint(0,1)

    # Keep going as long as there are some cards we haven't taken.
    while i<len(deck)//2 or j<len(deck):
        

        # Take from left when side is 0 and there's a card to take OR
        # if side is 1 and there is no card to take from the right side.
        if (side == 0 and i < len(deck)//2) or (side == 1 and j==len(deck)):

            # Figure out 1 or 2.
            numCards = random.randint(1,2)

            # Special case.
            if i == len(deck)//2 - 1:
                numCards = 1

            # Adds each card from the deck to this side.
            for loc in range(i, i+numCards):
                newdeck.append(deck[loc])

            # Update where we will add from next time.
            i += numCards

        # Guaranteed to take from right side in this case.
        else:

            # Figure out 1 or 2.
            numCards = random.randint(1,2)

            # Special case.
            if j == len(deck) - 1:
                numCards = 1

            # Adds each card from the deck to this side.
            for loc in range(j, j+numCards):
                #print("loc is ",loc)
                newdeck.append(deck[loc])

            # Update where we will add from next time.
            j += numCards            


        # Flips the side for next time.
        side = 1 - side

    # Return it.
    return newdeck

# Run it!
main()
