from __future__ import division, print_function

# Iterated Prisoner's Dilemma
# Doug Blank, Fall 2013
# CS361 Emergence

from conx import SRN
import random
import copy
import random
import math
import time

rewards = {"DC": 5,
           "CC": 3,
           "DD": 1,
           "CD": 0}

def random_player(history1, history2):
    """ A Random Player """
    return random.choice(["C", "D"])

def always_defect(history1, history2):
    """ Always defects """
    return "D"

def always_cooperate(history1, history2):
    """ Always cooperates """
    return "C"

def tit_for_tat(history1, history2):
    """ Tit for tat, initial C """
    if len(history2) > 0:
        return history2[-1]
    else:
        return "C"

def tit_for_tat2(history1, history2):
    """ Delayed tit for tat, initial C """
    if len(history2) == 49:
        return "D"
    elif len(history2) > 1:
        return history2[-2]
    else:
        return "C"

def besan_and_emily(history1, history2):
    # basically if the player is always defecting we need to defect too
    if len(history1) > 25:
        return "D"
    else:
        return "C"
    # else the player is not always defecting then we can cooperate
    # and have a better chance at getting more points


def allie_grace_dan(history1, history2):
    if len(history1) <= 4:
        return "C"
    elif len(history1) >= 48:
        return "D"
    else:
        defect = 0
        for i in range(len(history2)):
            if history2[i] == "D":
                defect = defect +1

        avg =  defect / len(history2)
        if avg > 0.5:
            return "D"
        else:
            return "C"

def michelle_gabby(history1, history2):
    x = random.choice(["A", "A", "B"])
    if x == "A":
        return "D"
    else:
        return random.choice(["D","D","D","D","D","D","C"])

def michelle_gabby2(history1, history2):
    x = random.choice(["A", "A", "B"])
    if history2[-4:] == ["D","D","D","D"]:
        return "D"
    elif x == "A":
        return "D"
    else:
        return random.choice(["D","D","D","D","D","D","C"])

def iris_sam(history1, history2):
    """TFT mod and cruel"""
    if len(history2) > 0 and len(history2) < 48:
        return history2[-1]
    else:
        return "D"

def iris_sam2(history1, history2):
    """TFT mod and  nice"""
    if len(history2) > 0:
        return history2[-1]
    elif len(history2) > 48:
        return "D"
    else:
        return "C"

def allie_grace_dan2(history1, history2):
    if len(history1) == 0: # we're at timestep 1
        return "C"
    elif len(history1) >= 48: # we're at timestep 49 or 50
        return "D"
    else:
        return history2[-1] # copy ipd2's most recent move

def play(ipd1, ipd2):
    score1 = 0
    score2 = 0
    history1 = []
    history2 = []
    for i in range(50):
        move1 = ipd1(history1, history2)
        move2 = ipd2(history2, history1)
        score1 += rewards[move1 + move2]
        score2 += rewards[move2 + move1]
        history1.append(move1)
        history2.append(move2)
    return (score1, score2)

def load_population(filename):
    """
    Load the generation from a file.
    """
    global POPULATION, GEN
    import pickle
    fp = open(filename, "r")
    GEN = int(fp.readline())
    data = fp.readlines()
    POPULATION = pickle.loads("".join(data))
    fp.close()

def ipd_network(history1, history2):
    network = SRN()
    network.addLayers(2, 5, 1)
    pattern = {"C": 0.1, "D": 0.9}
    network.unArrayify([0.6984408160400013, 0.58743156211198855, 0.16047091610763142, 
                        -0.44643271291544906, 0.25580664461247848, -0.52786400842445347, 
                        -0.28106022011362342, 0.0095948561848000491, -0.55860425460114271, 
                        0.025808988727769933, 0.60116880116715454, -0.94077627564930499, 
                        -0.46423369221143473, 0.26002336986619357, -0.89836583334454545, 
                        -0.92707775767381273, 0.76766655996751276, -0.50699755474054786, 
                        -0.61568740690715584, 0.089552617793158706, -0.15710819246113439, 
                        -0.83735383614276815, 0.95950550720711436, -0.84776335687045812, 
                        0.33689399059707026, -0.50138747975139042, 0.86687180353274762, 
                        0.59110729550518104, 0.081848696701098067, 0.79724015365931855, 
                        -0.77801319101663724, 0.76710118599256827, 0.4534127569770674, 
                        0.5736312814509632, 0.86076668574808601, 0.28198912350275251, 
                        0.51922317468641777, -0.23990610652530986, 0.55361966149092345, 
                        -0.33227522267456089, -0.84709304905395433, 0.53694563839674214, 
                        -0.64536693401000633, 0.016025826918225183, 0.94053694300471524, 
                        0.46810733298010665])
    output = network.propagate(input=[0.5, 0.5], context=[0.5, .5, .5, .5, .5])
    for a, b in zip(history1, history2):
        i1, i2 = pattern[a], pattern[b]
        output = network.propagate(input=[i1, i2], context=network["hidden"].activation)
    if output[0] < .5:
        return "C"
    else:
        return "D"

