# Path: lcs/strategies/action_selection/BestAction.py
# class BestAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         cl = population.get_best_classifier()
# 
#         if cl is not None:
#             return cl.action
#         else:
#             return np.random.randint(self.all_actions)
# 
# Path: lcs/strategies/action_selection/RandomAction.py
# class RandomAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         return np.random.randint(self.all_actions)


import numpy as np
from lcs.strategies.action_selection.BestAction import BestAction
from lcs.strategies.action_selection.RandomAction import RandomAction



class EpsilonGreedy:

    def __init__(self, all_actions: int, **kwargs):
        self.all_actions = all_actions
        self.epsilon = kwargs['epsilon']
        assert 0 <= self.epsilon <= 1

    def __call__(self, population) -> int:
        if np.random.uniform() > self.epsilon:
            return BestAction(all_actions=self.all_actions)(population)
        else:

# Path: lcs/strategies/action_selection/BestAction.py
# class BestAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         cl = population.get_best_classifier()
# 
#         if cl is not None:
#             return cl.action
#         else:
#             return np.random.randint(self.all_actions)
# 
# Path: lcs/strategies/action_selection/RandomAction.py
# class RandomAction:
# 
#     def __init__(self, all_actions: int):
#         self.all_actions = all_actions
# 
#     def __call__(self, population):
#         return np.random.randint(self.all_actions)


# Path: lcs/strategies/action_selection/EpsilonGreedy.py
import numpy as np
from lcs.strategies.action_selection.BestAction import BestAction
from lcs.strategies.action_selection.RandomAction import RandomAction




class EpsilonGreedy:

    def __init__(self, all_actions: int, **kwargs):
        self.all_actions = all_actions
        self.epsilon = kwargs['epsilon']
        assert 0 <= self.epsilon <= 1

    def __call__(self, population) -> int:
        if np.random.uniform() > self.epsilon:
            return BestAction(all_actions=self.all_actions)(population)
        else:

            return RandomAction(all_actions=self.all_actions)(population)