"""
Strategies from Axelrod's second tournament. All strategies in this module are
prefixed by `SecondBy` to indicate that they were submitted in Axelrod's Second
tournament by the given author.
"""

from typing import List

import numpy as np

from axelrod.action import Action

from axelrod.interaction_utils import compute_final_score

from axelrod.player import Player

from axelrod.strategies.finite_state_machines import FSMPlayer

C, D = Action.C, Action.D

class FSMPlayer(Player):
    """Abstract base class for finite state machine players."""

    name = "FSM Player"

    classifier: Dict[Text, Any] = {
        "memory_depth": 1,
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }

    def __init__(
        self,
        transitions: Tuple[Transition, ...] = ((1, C, 1, C), (1, D, 1, D)),
        initial_state: int = 1,
        initial_action: Action = C,
    ) -> None:
        Player.__init__(self)
        self.initial_state = initial_state
        self.initial_action = initial_action
        self.fsm = SimpleFSM(transitions, initial_state)

    def strategy(self, opponent: Player) -> Action:
        """Actual strategy definition that determines player's action."""
        if len(self.history) == 0:
            return self.initial_action
        else:
            return self.fsm.move(opponent.history[-1])

class SecondByColbert(FSMPlayer):
    """
    Strategy submitted to Axelrod's second tournament by William Colbert (K51R)
    and came in eighteenth in that tournament.

    In the first eight turns, this strategy Coopearates on all but the sixth
    turn, in which it Defects.  After that, the strategy responds to an
    opponent Cooperation with a single Cooperation, and responds to a Defection
    with a chain of responses:  Defect, Defect, Cooperate, Cooperate.  During
    this chain, the strategy ignores opponent's moves.

    Names:

    - Colbert: [Axelrod1980b]_
    """

    name = "Second by Colbert"
    classifier = {
        "memory_depth": 4,
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }

    def __init__(self) -> None:
        transitions = (
            (0, C, 1, C),
            (0, D, 1, C),  # First 8 turns are special
            (1, C, 2, C),
            (1, D, 2, C),
            (2, C, 3, C),
            (2, D, 3, C),
            (3, C, 4, C),
            (3, D, 4, C),
            (4, C, 5, D),
            (4, D, 5, D),  # Defect on 6th turn.
            (5, C, 6, C),
            (5, D, 6, C),
            (6, C, 7, C),
            (6, D, 7, C),
            (7, C, 7, C),
            (7, D, 8, D),
            (8, C, 9, D),
            (8, D, 9, D),
            (9, C, 10, C),
            (9, D, 10, C),
            (10, C, 7, C),
            (10, D, 7, C),
        )

        super().__init__(
            transitions=transitions, initial_state=0, initial_action=C
        )