###############################################################################
# ---------------- 15-112 Recitation #15: Recursive and OOPy Applications ---------------- #

# This is a starter file of the problems we did in recitation. A good way to
# use this file is to try to re-write problems you saw in recitation from
# scratch. This way, you can test your understanding and ask on Piazza or
# office hours if you have questions :)

# --------------------------------------------------------------------------- #
###############################################################################
# Combine Ints
###############################################################################
# LEARNING OBJECTIVES
# How do we solve more advanced recursion problems?
'''
Write the function combineInts(lst) which takes a list of integers. The function 
returns the list of integers which can be created by either adding or subtracting 
each element of lst. Each element must either be added or subtracted, and each 
element is only used once. For example, the integers in lst=[1, 1, 2] can be 
combined in the following ways:
#Possible combinations of 1, 1, and 2 
1 + 1 + 2 == 4 
1 + 1 - 2 == 0 
1 - 1 + 2 == 2 
1 - 1 - 2 == -2 
-1 + 1 + 2 == 2 
-1 + 1 - 2 == -2 
-1 - 1 + 2 == 0 
-1 - 1 - 2 == -4
#Since we're storing these combinations in a list, this test should pass 
# assert(combineInts([1, 1, 2]) == [-4, -2, 0, 2, 4])
Note: For a list of 3 elements, there are 8 possible ways to add and subtract 
each integer, but some of those combinations yield the same total, so 
combineInts([1, 1, 2]) returns a listof 5 integers. Here are some additional 
test cases:
assert(combineInts([5]) == [-5, 5]) 
assert(combineInts([1, 5]) == [-6, -4, 4, 6]) 
assert(combineInts([1, 5, 10]) == [4, 6, 14, -16, 16, -14, -6, -4]) 
assert(combineInts([]) == [0])
'''

def combineInts(lst):
    return [42]


###############################################################################
# Shape Invaders
###############################################################################
# LEARNING OBJECTIVES
# How do we solve more advanced OOPy animation

'''
Write the OOPy version of Shape Invaders!
You can use functions outside of a class, but you must use OOP in a meaningful
way.
•   The game starts out with 5 different “shapes” at the bottom of the screen
in a random order. These can all be very similar, so long as there is a way to
differentiate between all of them. (For example, they can all be circles, but
with 5 different colors).
•   From the top of the screen, the same 5 shapes, but in a different, random
order appear. They slowly fall down to the bottom of the screen.
•   If at any point, the shapes from the top collide with the shapes on the
bottom, the game is over.
•   When you click on one shape, it should be highlighted. The way you do this
is up to you, but one way would be drawing the shape with a larger outline.
When a single shape is highlighted, and you click another shape, the shapes
should switch places.
•   If the colors on the bottom match up with the colors on the top, the moving
shapes should disappear, and another row of shapes should start moving from the
top.
•   Lastly, the more rows you destroy, the faster the game goes! So, as the
game progresses, the moving shapes should progress down from the screen faster
and faster.
'''

# Animation Starter Code, Focus on timerFired

from tkinter import *

####################################
# customize these functions
####################################

def init(data):
    # load data.xyz as appropriate
    pass

def mousePressed(event, data):
    # use event.x and event.y
    pass

def keyPressed(event, data):
    # use event.char and event.keysym
    pass

def timerFired(data):
    pass

def redrawAll(canvas, data):
    # draw in canvas
    pass

####################################
# use the run function as-is
####################################

def run(width=300, height=300):
    def redrawAllWrapper(canvas, data):
        canvas.delete(ALL)
        canvas.create_rectangle(0, 0, data.width, data.height,
                                fill='white', width=0)
        redrawAll(canvas, data)
        canvas.update()

    def mousePressedWrapper(event, canvas, data):
        mousePressed(event, data)
        redrawAllWrapper(canvas, data)

    def keyPressedWrapper(event, canvas, data):
        keyPressed(event, data)
        redrawAllWrapper(canvas, data)

    def timerFiredWrapper(canvas, data):
        timerFired(data)
        redrawAllWrapper(canvas, data)
        # pause, then call timerFired again
        canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
    # Set up data and call init
    class Struct(object): pass
    data = Struct()
    data.width = width
    data.height = height
    data.timerDelay = 100 # milliseconds
    root = Tk()
    init(data)
    # create the root and the canvas
    canvas = Canvas(root, width=data.width, height=data.height)
    canvas.configure(bd=0, highlightthickness=0)
    canvas.pack()
    # set up events
    root.bind("<Button-1>", lambda event:
                            mousePressedWrapper(event, canvas, data))
    root.bind("<Key>", lambda event:
                            keyPressedWrapper(event, canvas, data))
    timerFiredWrapper(canvas, data)
    # and launch the app
    root.mainloop()  # blocks until window is closed
    print("bye!")

#run(400, 400)








