"""
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 SecondByLeyvraz(Player):
    """
    Strategy submitted to Axelrod's second tournament by Fransois Leyvraz
    (K68R) and came in twelfth in that tournament.

    The strategy uses the opponent's last three moves to decide on an action
    based on the following ordered rules.

    1. If opponent Defected last two turns, then Defect with prob 75%.
    2. If opponent Defected three turns ago, then Cooperate.
    3. If opponent Defected two turns ago, then Defect.
    4. If opponent Defected last turn, then Defect with prob 50%.
    5. Otherwise (all Cooperations), then Cooperate.

    Names:

    - Leyvraz: [Axelrod1980b]_
    """

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

    def __init__(self) -> None:
        super().__init__()
        self.prob_coop = {
            (C, C, C): 1.0,
            (C, C, D): 0.5,  # Rule 4
            (C, D, C): 0.0,  # Rule 3
            (C, D, D): 0.25,  # Rule 1
            (D, C, C): 1.0,  # Rule 2
            (D, C, D): 1.0,  # Rule 2
            (D, D, C): 1.0,  # Rule 2
            (D, D, D): 0.25,  # Rule 1
        }

    def strategy(self, opponent: Player) -> Action:
        recent_history = [C, C, C]  # Default to C.
        for go_back in range(1, 4):
            if len(opponent.history) >= go_back:
                recent_history[-go_back] = opponent.history[-go_back]

        return self._random.random_choice(
            self.prob_coop[
                (recent_history[-3], recent_history[-2], recent_history[-1])
            ]
        )