import itertools
import warnings
from typing import Dict, Optional, Tuple
from axelrod.action import Action
from axelrod.player import Player
from .defector import Defector
from .titfortat import TitFor2Tats, TitForTat
IIIIIllIIIlIllIlIll, llIlIlIllIlIllIlllll = Action.C, Action.D
class IIIllllllIIllIIlllIl(Player):
    IIlllIIIllIIIlIIIlII = "strategy"
    IllIIlIIlll = {
        "memory_depth": 2,
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }
    def __init__(
        lIIIlllII,
        IlllllIll: Optional[Tuple[float, ...]] = None,
        lIllIIlIIlllll: Optional[Tuple[Action, Action]] = None,
    ) -> None:
        super().__init__()
        if lIllIIlIIlllll is None:
            lIllIIlIIlllll = (IIIIIllIIIlIllIlIll, IIIIIllIIIlIllIlIll)
        lIIIlllII.IlIlIlllIllIlIlIlllI = lIllIIlIIlllll
        lIIIlllII.IlIlIIIlIlIllllIIl(IlllllIll)
    def IlIlIIIlIlIllllIIl(
        lIIIlllII, IlllllIll: Optional[Tuple[float, ...]]
    ):
        if IlllllIll is None:
            IlllllIll = tuple([1] * 16)
            warnings.warn("Memory two player is set to default, Cooperator.")
        lIIIlllII.IIlIIlIlllIllII(IlllllIll)
    def IIlIIlIlllIllII(lIIIlllII, IlllllIll: Tuple[float, ...]):
        if not all(0 <= IlllIlIIIllIIIlII <= 1 for IlllIlIIIllIIIlII in IlllllIll):
            raise ValueError(
                "An element in the probability vector, {}, is not "
                "between 0 and 1.".format(str(IlllllIll))
            )
        lIIIIIIlIlIII = [
            (lllIIllIIIIlIlIIlIIl[:2], lllIIllIIIIlIlIIlIIl[2:])
            for lllIIllIIIIlIlIIlIIl in list(itertools.product((IIIIIllIIIlIllIlIll, llIlIlIllIlIllIlllll), repeat=4))
        ]
        lIIIlllII.IlllllllIlIIII = dict(
            zip(lIIIIIIlIlIII, IlllllIll)
        )  
    @staticmethod
    def IIIlllIIIIll(
        IlllllIll: Dict[Tuple[Action, Action], float],
    ) -> int:
        IIllIIllllIlII = set(list(IlllllIll.IIllIIllllIlII()))
        if all(IllIllIIllI == 0 for IllIllIIllI in IIllIIllllIlII) or all(IllIllIIllI == 1 for IllIllIIllI in IIllIIllllIlII):
            return 0
        IIIlIIIlIll = True
        llllIIll = IlllllIll
        IllIIlIIIIIIIl = [(IIIIIllIIIlIllIlIll, IIIIIllIIIlIllIlIll), (IIIIIllIIIlIllIlIll, llIlIlIllIlIllIlllll), (llIlIlIllIlIllIlllll, IIIIIllIIIlIllIlIll), (llIlIlIllIlIllIlllll, llIlIlIllIlIllIlllll)]
        for IlIIllllIllIIIlllllI in IllIIlIIIIIIIl:
            IIllIIllllIlII = set()
            IIIlIIIlllllIIIll, IIlIlIlIllllllIIIlll = IlIIllllIllIIIlllllI
            for llIllIIl in IllIIlIIIIIIIl:
                IllIllIIllI, IlllIIlIIlIIII = llIllIIl
                IIllIIllllIlII.add(llllIIll[((IllIllIIllI, IIIlIIIlllllIIIll), (IlllIIlIIlIIII, IIlIlIlIllllllIIIlll))])
            if len(IIllIIllllIlII) > 1:
                IIIlIIIlIll = False
                break
        if IIIlIIIlIll:
            return 1
        return 2
    def IllIlIlIIIIIIllllI(lIIIlllII):
        IIllIIllllIlII = set(lIIIlllII.IlllllllIlIIII.IIllIIllllIlII())
        lIIIlllII.IllIIlIIlll["stochastic"] = any(0 < IllIllIIllI < 1 for IllIllIIllI in IIllIIllllIlII)
        lIIIlllII.IllIIlIIlll["memory_depth"] = lIIIlllII.IIIlllIIIIll(
            lIIIlllII.IlllllllIlIIII
        )
    def IllIIlll(lIIIlllII, IIIlIIllllIIl: Player) -> Action:
        lllIlllllIIIIlIIllIl = len(lIIIlllII.history)
        if lllIlllllIIIIlIIllIl <= 1:
            return lIIIlllII.IlIlIlllIllIlIlIlllI[lllIlllllIIIIlIIllIl]
        IlllIlIIIllIIIlII = lIIIlllII.IlllllllIlIIII[
            (tuple(lIIIlllII.history[-2:]), tuple(IIIlIIllllIIl.history[-2:]))
        ]
        try:
            return lIIIlllII._random.random_choice(IlllIlIIIllIIIlII)
        except AttributeError:
            return IIIIIllIIIlIllIlIll if IlllIlIIIllIIIlII == 1 else llIlIlIllIlIllIlllll