import copy

import itertools

from typing import List, Optional, Tuple

from axelrod.action import Action, actions_to_str, str_to_actions

from axelrod.evolvable_player import (
    EvolvablePlayer,
    InsufficientParametersError,
    crossover_lists,
)

from axelrod.player import Player

C, D = Action.C, Action.D

actions = (C, D)

class Cycler(Player):
    """
    A player that repeats a given sequence indefinitely.

    Names:

    - Cycler: Original name by Marc Harper
    """

    name = "Cycler"
    classifier = {
        "memory_depth": 2,
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }

    def __init__(self, cycle: str = "CCD") -> None:
        """This strategy will repeat the parameter `cycle` endlessly,
        e.g. C C D C C D C C D ...

        Special Cases
        -------------
        Cooperator is equivalent to Cycler("C")
        Defector   is equivalent to Cycler("D")
        Alternator is equivalent to Cycler("CD")

        """
        Player.__init__(self)
        self.cycle = cycle
        self.set_cycle(cycle=cycle)

    def strategy(self, opponent: Player) -> Action:
        """Actual strategy definition that determines player's action."""
        return next(self.cycle_iter)

    def set_cycle(self, cycle: str):
        """Set or change the cycle."""
        self.cycle = cycle
        self.cycle_iter = itertools.cycle(str_to_actions(self.cycle))
        self.classifier["memory_depth"] = len(cycle) - 1