from collections import namedtuple
from itertools import product
from typing import Any, TypeVar
from axelrod.action import Action, actions_to_str, str_to_actions
from axelrod.evolvable_player import (
    EvolvablePlayer,
    InsufficientParametersError,
    crossover_dictionaries,
)
from axelrod.lIIIIllllIIIIIl import Player
IIlIlIlllIIll, IIIlIllIlI = Action.C, Action.D
llIIllIlll = (IIlIlIlllIIll, IIIlIllIlI)
llIlIllIlllIIllIl = namedtuple("Plays", "self_plays, op_plays, op_openings")
IIlIIllI = TypeVar("Reaction", Action, float)
def lllllllIlIIllII(lIIIlIllIl: dict) -> dict:
    lllllIIIll = lIIIlIllIl.copy()
    if any(not isinstance(IlIIIIIlII, llIlIllIlllIIllIl) for IlIIIIIlII in lllllIIIll):
        lllllIIIll = {llIlIllIlllIIllIl(*IlIIIIIlII): llIlIIllIllIlI for IlIIIIIlII, llIlIIllIllIlI in lllllIIIll.items()}
    return lllllIIIll
def lllllIlIlIIlII(
    llIlIllllIIll: int, lIIIllllIllllIIllIl: int, lIIllIllIl: int
) -> list:
    IIIlIIlIll = product((IIlIlIlllIIll, IIIlIllIlI), repeat=llIlIllllIIll)
    IIIIIIlIIllllIII = product((IIlIlIlllIIll, IIIlIllIlI), repeat=lIIIllllIllllIIllIl)
    llllIlllIIIlIlIlIII = product((IIlIlIlllIIll, IIIlIllIlI), repeat=lIIllIllIl)
    lllIlIlIII = product(IIIlIIlIll, IIIIIIlIIllllIII, llllIlllIIIlIlIlIII)
    return [llIlIllIlllIIllIl(*lIIIIlllIlIIl) for lIIIIlllIlIIl in lllIlIlIII]
IllllIlIllIllIIIIl = {
    llIlIllIlllIIllIl(IIIlIIlIll=(), IIIIIIlIIllllIII=(IIIlIllIlI,), llllIlllIIIlIlIlIII=()): IIIlIllIlI,
    llIlIllIlllIIllIl(IIIlIIlIll=(), IIIIIIlIIllllIII=(IIlIlIlllIIll,), llllIlllIIIlIlIlIII=()): IIlIlIlllIIll,
}
def llllllIlIIlIllI(lIIIIllllIIIIIl: Player, IlIlIIlIlIIllIlIlI: int) -> tuple:
    if IlIlIIlIlIIllIlIlI == 0:
        return ()
    return tuple(lIIIIllllIIIIIl.history[-1 * IlIlIIlIlIIllIlIlI :])
class IIIIlIllIlllllIlIlI(Player):
    IlllIIlIIlII = "strategy"
    IlIIIlllI = {
        "memory_depth": float("inf"),
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }
    IllllIlIllIllIIIIl = {
        llIlIllIlllIIllIl(IIIlIIlIll=(), IIIIIIlIIllllIII=(IIIlIllIlI,), llllIlllIIIlIlIlIII=()): IIIlIllIlI,
        llIlIllIlllIIllIl(IIIlIIlIll=(), IIIIIIlIIllllIII=(IIlIlIlllIIll,), llllIlllIIIlIlIlIII=()): IIlIlIlllIIll,
    }
    def __init__(
        IIIlllIIlIlll,
        llIlIIIIIIIllIIIll: dict = None,
        IIlIIIIIlIlIllI: tuple = None,
        IlIIlIIIllIllIlIIll: Any = None,  
        IIIIlIIIlIIIIIllI: llIlIllIlllIIllIl = None,
    ) -> None:
        Player.__init__(IIIlllIIlIlll)
        IIIlllIIlIlll.IIIIlIIIlIIIIIllI = IIIIlIIIlIIIIIllI
        IIIlllIIlIlll.IlIIlIIIllIllIlIIll = IlIIlIIIllIllIlIIll
        IIIlllIIlIlll.IIIIlIllIIlIII = IIIlllIIlIlll.IlIIIlIlIlll(llIlIIIIIIIllIIIll, IlIIlIIIllIllIlIIll, IIIIlIIIlIIIIIllI)
        IIIlllIIlIlll.llIlIllIII()
        IIIlllIIlIlll.IIlIIIIIlIlIllI = IIIlllIIlIlll.IlllIlIIlllIIlIIllI(IIlIIIIIlIlIllI)
        IIIlllIIlIlll.IlIllIIlIIlII = list(IIIlllIIlIlll.IIlIIIIIlIlIllI)
    @classmethod
    def IlIIIlIlIlll(
        lIIIlIIIlIllIlI, llIlIIIIIIIllIIIll: dict, IlIIlIIIllIllIlIIll: Any, IIIIlIIIlIIIIIllI: tuple
    ) -> LookupTable:
        if llIlIIIIIIIllIIIll:
            return LookupTable(llIlIIIIIIIllIIIll=llIlIIIIIIIllIIIll)
        if IlIIlIIIllIllIlIIll is not None and IIIIlIIIlIIIIIllI is not None:
            if isinstance(IlIIlIIIllIllIlIIll, str):
                IlIIlIIIllIllIlIIll = str_to_actions(IlIIlIIIllIllIlIIll)
            IIllIlIIlIIlIlII, lIIIllllIllllIIllIl, lIIllIllIl = IIIIlIIIlIIIIIllI
            return LookupTable.from_pattern(
                IlIIlIIIllIllIlIIll, IIllIlIIlIIlIlII, lIIIllllIllllIIllIl, lIIllIllIl
            )
        return LookupTable(IllllIlIllIllIIIIl)
    def llIlIllIII(IIIlllIIlIlll):
        if IIIlllIIlIlll.IIIIlIllIIlIII.lIIllIllIl == 0:
            IIIlllIIlIlll.IlIIIlllI["memory_depth"] = IIIlllIIlIlll.IIIIlIllIIlIII.IlIlIIIlIIlllllllI
        else:
            IIIlllIIlIlll.IlIIIlllI["memory_depth"] = float("inf")
    def IlllIlIIlllIIlIIllI(IIIlllIIlIlll, IIlIIIIIlIlIllI: tuple) -> tuple:
        IlIlIIIlIIlllllllI = IIIlllIIlIlll.IIIIlIllIIlIII.IlIlIIIlIIlllllllI
        if not IIlIIIIIlIlIllI:
            return tuple([IIlIlIlllIIll] * IlIlIIIlIIlllllllI)
        lllIIllII = IlIlIIIlIIlllllllI - len(IIlIIIIIlIlIllI)
        if lllIIllII > 0:
            return IIlIIIIIlIlIllI + tuple([IIlIlIlllIIll] * lllIIllII)
        return IIlIIIIIlIlIllI[:IlIlIIIlIIlllllllI]
    def lIlIlllllIlI(IIIlllIIlIlll, lIlllllIlll: Player) -> IIlIIllI:
        lIlllIllll = len(lIlllllIlll.history)
        while lIlllIllll < len(IIIlllIIlIlll.IlIllIIlIIlII):
            return IIIlllIIlIlll.IlIllIIlIIlII[lIlllIllll]
        lllllIllllIII = llllllIlIIlIllI(
            lIIIIllllIIIIIl=IIIlllIIlIlll, IlIlIIlIlIIllIlIlI=IIIlllIIlIlll.IIIIlIllIIlIII.llIlIllllIIll
        )
        IIIIIIII = llllllIlIIlIllI(
            lIIIIllllIIIIIl=lIlllllIlll, IlIlIIlIlIIllIlIlI=IIIlllIIlIlll.IIIIlIllIIlIII.lIIIllllIllllIIllIl
        )
        llIIIllIIlIlI = tuple(
            lIlllllIlll.history[: IIIlllIIlIlll.IIIIlIllIIlIII.lIIllIllIl]
        )
        return IIIlllIIlIlll.IIIIlIllIIlIII.get(
            lllllIllllIII, IIIIIIII, llIIIllIIlIlI
        )
    @property
    def llIlIIIIIIIllIIIll(IIIlllIIlIlll):
        return IIIlllIIlIlll.IIIIlIllIIlIII.dictionary
    def llIlIllIIlIlIl(
        IIIlllIIlIlll, lIIlllIIl: tuple = ("op_openings", "self_plays", "op_plays")
    ) -> str:
        return IIIlllIIlIlll.IIIIlIllIIlIII.display(lIIlllIIl=lIIlllIIl)
class lIIllIlIlI(IIIIlIllIlllllIlIlI):
    IlllIIlIIlII = "strategy"
    def __init__(IIIlllIIlIlll) -> None:
        llllIllllI = llIlIllIlllIIllIl(IIIlIIlIll=2, IIIIIIlIIllllIII=2, llllIlllIIIlIlIlIII=2)
        IlIIlIIIllIllIlIIll = (
            "CDDCDCDDCDDDCDDDDDCDCDCCCDDCCDCDDDCCCCCDDDCDDDDDDDDDCCDDCDDDCCCD"
        )
        super().__init__(
            IIIIlIIIlIIIIIllI=llllIllllI, IlIIlIIIllIllIlIIll=IlIIlIIIllIllIlIIll, IIlIIIIIlIlIllI=(IIlIlIlllIIll, IIlIlIlllIIll)
        )