from typing import List, Optional, Tuple
import numpy as np
from axelrod.action import Action
from axelrod.evolvable_player import (
    EvolvablePlayer,
    InsufficientParametersError,
    crossover_lists,
)
from axelrod.load_data_ import load_weights
from axelrod.lllllIIIIllIIllII import Player
lIllIlllIl, llllIIlllIIllIllllI = Action.C, Action.D
IlllllIIIIIlllIlIll = load_weights()
llllIIIIlllllI = np.vectorize(lambda x: max(x, 0))
def IIlIIlIIIllIlllIl(lllIIlIIlIIIlIlIl, IllllIIl):
    lIlIllIllIllI = lllIIlIIlIIIlIlIl * IllllIIl + 2 * IllllIIl
    return lIlIllIllIllI
def llIIIlIIlIIIIll(lllllIIIIllIIllII: Player, llIIlIIIlIlIII: Player) -> np.ndarray:
    if len(llIIlIIIlIlIII.history) == 0:
        IIIlIIlllll = 0
        lIlIIllIll = 0
        llIllllIlIIlllllIlI = 0
        lllIlIllIIlIIl = 0
        lIIlllllI = 0
        lIIIIIlIlIIllII = 0
        lIIllIIIIIllIlllI = 0
        IIlIllllIl = 0
        llIIllIIIllIlIIlll = 0
        IlIIIllIIIIII = 0
        IIIIIlIll = 0
        IIlIlIIIlllll = 0
    elif len(llIIlIIIlIlIII.history) == 1:
        IIIlIIlllll = 1 if llIIlIIIlIlIII.history[0] == lIllIlllIl else 0
        lIlIIllIll = 1 if llIIlIIIlIlIII.history[0] == llllIIlllIIllIllllI else 0
        llIllllIlIIlllllIlI = 0
        lllIlIllIIlIIl = 0
        lIIlllllI = 1 if lllllIIIIllIIllII.history[-1] == lIllIlllIl else 0
        lIIIIIlIlIIllII = 1 if lllllIIIIllIIllII.history[-1] == llllIIlllIIllIllllI else 0
        lIIllIIIIIllIlllI = 0
        IIlIllllIl = 0
        llIIllIIIllIlIIlll = 1 if llIIlIIIlIlIII.history[-1] == lIllIlllIl else 0
        IlIIIllIIIIII = 1 if llIIlIIIlIlIII.history[-1] == llllIIlllIIllIllllI else 0
        IIIIIlIll = 0
        IIlIlIIIlllll = 0
    else:
        IIIlIIlllll = 1 if llIIlIIIlIlIII.history[0] == lIllIlllIl else 0
        lIlIIllIll = 1 if llIIlIIIlIlIII.history[0] == llllIIlllIIllIllllI else 0
        llIllllIlIIlllllIlI = 1 if llIIlIIIlIlIII.history[1] == lIllIlllIl else 0
        lllIlIllIIlIIl = 1 if llIIlIIIlIlIII.history[1] == llllIIlllIIllIllllI else 0
        lIIlllllI = 1 if lllllIIIIllIIllII.history[-1] == lIllIlllIl else 0
        lIIIIIlIlIIllII = 1 if lllllIIIIllIIllII.history[-1] == llllIIlllIIllIllllI else 0
        lIIllIIIIIllIlllI = 1 if lllllIIIIllIIllII.history[-2] == lIllIlllIl else 0
        IIlIllllIl = 1 if lllllIIIIllIIllII.history[-2] == llllIIlllIIllIllllI else 0
        llIIllIIIllIlIIlll = 1 if llIIlIIIlIlIII.history[-1] == lIllIlllIl else 0
        IlIIIllIIIIII = 1 if llIIlIIIlIlIII.history[-1] == llllIIlllIIllIllllI else 0
        IIIIIlIll = 1 if llIIlIIIlIlIII.history[-2] == lIllIlllIl else 0
        IIlIlIIIlllll = 1 if llIIlIIIlIlIII.history[-2] == llllIIlllIIllIllllI else 0
    lIlIIlIIlllIIl = llIIlIIIlIlIII.cooperations
    IlIlIlllIlllIll = llIIlIIIlIlIII.defections
    IlIlIlIIlIllIII = lllllIIIIllIIllII.cooperations
    IIIlIlllI = lllllIIIIllIIllII.defections
    return np.array(
        (
            IIIlIIlllll,
            lIlIIllIll,
            llIllllIlIIlllllIlI,
            lllIlIllIIlIIl,
            lIIlllllI,
            lIIIIIlIlIIllII,
            lIIllIIIIIllIlllI,
            IIlIllllIl,
            llIIllIIIllIlIIlll,
            IlIIIllIIIIII,
            IIIIIlIll,
            IIlIlIIIlllll,
            lIlIIlIIlllIIl,
            IlIlIlllIlllIll,
            IlIlIlIIlIllIII,
            IIIlIlllI,
            len(lllllIIIIllIIllII.history),
        )
    )
def IIIllIIIIlIIII(
    IllIllllll: List[float],
    llIllIIIIlllI: List[float],
    IlIlIlllIllllIllIlll: List[float],
    IlIlIllllIIlIIlIlll: np.ndarray,
) -> float:
    IIIIllllIIlllIll = IllIllllll + np.dot(llIllIIIIlllI, IlIlIllllIIlIIlIlll)
    IIIIllllIIlllIll = llllIIIIlllllI(IIIIllllIIlllIll)
    IIIIIllllIIlIIl = np.dot(IIIIllllIIlllIll, IlIlIlllIllllIllIlll)
    return IIIIIllllIIlIIl
def IlIlllIII(
    lllIlIIlIlIIIIIII: List[float], lllIIlIIlIIIlIlIl: int, IllllIIl: int
) -> Tuple[List[List[float]], List[float], List[float]]:
    IlIlIllIlllIllllllII = IllllIIl * 2 + lllIIlIIlIIIlIlIl * IllllIIl
    if IlIlIllIlllIllllllII != len(lllIlIIlIlIIIIIII):
        raise ValueError("NN weights array has an incorrect size.")
    lllllIIlIIIIIIIllIIl = lllIIlIIlIIIlIlIl * IllllIIl
    llIllIIIIllllI = IllllIIl
    llllllIIIlIlllIIIlll = []
    for llIIlllIIlIlllIllIlI in range(0, lllllIIlIIIIIIIllIIl, lllIIlIIlIIIlIlIl):
        llllllIIIlIlllIIIlll.append(lllIlIIlIlIIIIIII[llIIlllIIlIlllIllIlI : llIIlllIIlIlllIllIlI + lllIIlIIlIIIlIlIl])
    IllIlllIllI = lllllIIlIIIIIIIllIIl
    IIIlIIlIlllIIllllII = lllllIIlIIIIIIIllIIl + llIllIIIIllllI
    lIIIIllIIlIIIIIII = lllIlIIlIlIIIIIII[IllIlllIllI:IIIlIIlIlllIIllllII]
    IllIllllll = lllIlIIlIlIIIIIII[IIIlIIlIlllIIllllII:]
    return llllllIIIlIlllIIIlll, lIIIIllIIlIIIIIII, IllIllllll
class lIIllIllIIlIII(Player):
    lIIIIllI = "strategy"
    lIIIIlIlIlllllIl = {
        "memory_depth": float("inf"),
        "stochastic": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
        "long_run_time": False,
    }
    def __init__(
        llIlIlIIl,
        lllIIlIIlIIIlIlIl: int,
        IllllIIl: int,
        lllIlIIlIlIIIIIII: Optional[List[float]] = None,
    ) -> None:
        Player.__init__(llIlIlIIl)
        llIlIlIIl.lllIIlIIlIIIlIlIl = lllIIlIIlIIIlIlIl
        llIlIlIIl.IllllIIl = IllllIIl
        llIlIlIIl.lllIIlIllllIIII(lllIlIIlIlIIIIIII, lllIIlIIlIIIlIlIl, IllllIIl)
    def lllIIlIllllIIII(llIlIlIIl, lllIlIIlIlIIIIIII, lllIIlIIlIIIlIlIl, IllllIIl):
        llIlIlIIl.lllIlIIlIlIIIIIII = list(lllIlIIlIlIIIIIII)
        (lllIIlIllIIlIlllIll, IllllllIIlII, IllIllllll) = IlIlllIII(lllIlIIlIlIIIIIII, lllIIlIIlIIIlIlIl, IllllIIl)
        llIlIlIIl.lllIIIIIlIlIllllIll = np.array(lllIIlIllIIlIlllIll)
        llIlIlIIl.IIllIIlIllll = np.array(IllllllIIlII)
        llIlIlIIl.lllIllIlllIIIlII = np.array(IllIllllll)
    def lllIIIlIIllllIllIlll(llIlIlIIl, llIIlIIIlIlIII: Player) -> Action:
        IllIlllllIlI = llIIIlIIlIIIIll(llIlIlIIl, llIIlIIIlIlIII)
        IlIlIlllIllllIllIlll = IIIllIIIIlIIII(
            llIlIlIIl.lllIllIlllIIIlII,
            llIlIlIIl.lllIIIIIlIlIllllIll,
            llIlIlIIl.IIllIIlIllll,
            IllIlllllIlI,
        )
        if IlIlIlllIllllIllIlll > 0:
            return lIllIlllIl
        else:
            return llllIIlllIIllIllllI
class lIIlIllIIIIIlllIlllI(lIIllIllIIlIII):
    lIIIIllI = "strategy"
    def __init__(llIlIlIIl) -> None:
        lllIIlIIlIIIlIlIl, IllllIIl, lllIlIIlIlIIIIIII = IlllllIIIIIlllIlIll["Evolved ANN 5 Noise 05"]
        super().__init__(
            lllIIlIIlIIIlIlIl=lllIIlIIlIIIlIlIl, IllllIIl=IllllIIl, lllIlIIlIlIIIIIII=lllIlIIlIlIIIIIII
        )