def __init__(self, env: gym.Env, combined_observation_space: Tuple[(Tuple[(int, int, int)], int)], lr: float, gamma: float, epsilon: float, epsilon_decay: float, target_update_interval: int=100, log_wandb: bool=False, replay_buffer: Optional[ReplayBuffer]=None, fc_layers: Optional[List[int]]=None, conv_layers: Optional[List[int]]=None):
    "\n        Construct a new 'Deep Q-Network' object.\n\n        :param env: The environment of the game\n        :param lr: The learning rate of the agent\n        :param gamma: The amount of weight it gives to future rewards in the value function\n        :param epsilon: The probability where we do not go with the “greedy” action with the highest Q-value but rather choose a random action\n        :param epsilon_decay: The rate by which epsilon decreases after an episode\n        :param target_update_interval: The interval between updates of the target network\n        :param replay_buffer: Replay memory object to store and sample observations from for training.\n         Defaults to double-end queue with maximum length of 500_000 steps.\n        "
    self.log_wandb = log_wandb
    self.env = env
    self.action_space = env.action_space
    self.combined_observation_space = combined_observation_space
    self.lr = lr
    self.gamma = gamma
    self.epsilon = epsilon
    self.epsilon_decay = epsilon_decay
    self.target_update_interval = target_update_interval
    self.rewards_list = []
    self.buffer = (replay_buffer if replay_buffer else ReplayBuffer(maxlen=2500))
    self.batch_size = 64
    self.epsilon_min = 0.01
    self.num_action_space = 4
    self.fc_layers = ([128, 128, 128] if (not fc_layers) else fc_layers)
    assert (len(self.fc_layers) >= 1), 'You need at least one hidden layer'
    self.conv_layers = ([32, 64, 128] if (not conv_layers) else conv_layers)
    assert (len(self.conv_layers) >= 1), 'You need at least one hidden layer'
    self.model = self.initialize_model()
    self.model_target = clone_model(self.model)
    if self.log_wandb:
        wandb.config.update({'lr': self.lr, 'gamma': self.gamma, 'epsilon': self.epsilon, 'epsilon_decay': self.epsilon_decay, 'target_update_interval': self.target_update_interval, 'batch_size': self.batch_size, 'fc_layers': self.fc_layers})
Construct a new 'Deep Q-Network' object.

:param env: The environment of the game
:param lr: The learning rate of the agent
:param gamma: The amount of weight it gives to future rewards in the value function
:param epsilon: The probability where we do not go with the “greedy” action with the highest Q-value but rather choose a random action
:param epsilon_decay: The rate by which epsilon decreases after an episode
:param target_update_interval: The interval between updates of the target network
:param replay_buffer: Replay memory object to store and sample observations from for training.
 Defaults to double-end queue with maximum length of 500_000 steps.
def __init__(self, env: gym.Env, combined_observation_space: Tuple[(Tuple[(int, int, int)], int)], lr: float, gamma: float, epsilon: float, epsilon_decay: float, target_update_interval: int=100, log_wandb: bool=False, replay_buffer: Optional[ReplayBuffer]=None, fc_layers: Optional[List[int]]=None, conv_layers: Optional[List[int]]=None):
    "\n        Construct a new 'Deep Q-Network' object.\n\n        :param env: The environment of the game\n        :param lr: The learning rate of the agent\n        :param gamma: The amount of weight it gives to future rewards in the value function\n        :param epsilon: The probability where we do not go with the “greedy” action with the highest Q-value but rather choose a random action\n        :param epsilon_decay: The rate by which epsilon decreases after an episode\n        :param target_update_interval: The interval between updates of the target network\n        :param replay_buffer: Replay memory object to store and sample observations from for training.\n         Defaults to double-end queue with maximum length of 500_000 steps.\n        "
    self.log_wandb = log_wandb
    self.env = env
    self.action_space = env.action_space
    self.combined_observation_space = combined_observation_space
    self.lr = lr
    self.gamma = gamma
    self.epsilon = epsilon
    self.epsilon_decay = epsilon_decay
    self.target_update_interval = target_update_interval
    self.rewards_list = []
    self.buffer = (replay_buffer if replay_buffer else ReplayBuffer(maxlen=2500))
    self.batch_size = 64
    self.epsilon_min = 0.01
    self.num_action_space = 4
    self.fc_layers = ([128, 128, 128] if (not fc_layers) else fc_layers)
    assert (len(self.fc_layers) >= 1), 'You need at least one hidden layer'
    self.conv_layers = ([32, 64, 128] if (not conv_layers) else conv_layers)
    assert (len(self.conv_layers) >= 1), 'You need at least one hidden layer'
    self.model = self.initialize_model()
    self.model_target = clone_model(self.model)
    if self.log_wandb:
        wandb.config.update({'lr': self.lr, 'gamma': self.gamma, 'epsilon': self.epsilon, 'epsilon_decay': self.epsilon_decay, 'target_update_interval': self.target_update_interval, 'batch_size': self.batch_size, 'fc_layers': self.fc_layers})