"""
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 SecondByBlack(Player):
    """
    Strategy submitted to Axelrod's second tournament by Paul E Black (K83R)
    and came in fifteenth in that tournament.

    The strategy Cooperates for the first five turns.  Then it calculates the
    number of opponent defects in the last five moves and Cooperates with
    probability `prob_coop`[`number_defects`], where:

    prob_coop[number_defects] = 1 - (number_defects^ 2 - 1) / 25

    Names:

    - Black: [Axelrod1980b]_
    """

    name = "Second by Black"
    classifier = {
        "memory_depth": 5,
        "stochastic": True,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }

    def __init__(self) -> None:
        super().__init__()
        # Maps number of opponent defects from last five moves to own
        # Cooperation probability
        self.prob_coop = {0: 1.0, 1: 1.0, 2: 0.88, 3: 0.68, 4: 0.4, 5: 0.04}

    def strategy(self, opponent: Player) -> Action:
        if len(opponent.history) < 5:
            return C

        recent_history = opponent.history[-5:]

        did_d = np.vectorize(lambda action: int(action == D))
        number_defects = sum(did_d(recent_history))

        return self._random.random_choice(self.prob_coop[number_defects])