import os
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras.layers import Dense

#Critic network outputs the q values by taking the actions and pbservations into account
class CriticNetwork(keras.Model):
    def __init__(self, n_actions, fc1_dims = 512, fc2_dims=512, name='critic', chkpt_dir='tmp/ddpg'):
        super(CriticNetwork, self).__init__()
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions

        self.model_name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, self.model_name+'_ddpg.h5')

        self.fc1 = Dense(self.fc1_dims, activation='relu')  #1st layer
        self.fc2 = Dense(self.fc2_dims, activation='relu')  #2nd Layer
        self.q = Dense(1, activation=None)                  #Output Layer

    # Feedforward
    def call(self, state, action):
        action_value = self.fc1(tf.concat([state,action], axis=1))
        action_value = self.fc2(action_value)

        q = self.q(action_value)

        return q

# Actor network outputs the actions by taking the observations as input    
class ActorNetwork(keras.Model):
    def __init__(self, fc1_dims=512, fc2_dims=512, n_actions=2, name='actor', chkpt_dir='tmp/ddpg'):
        super(ActorNetwork, self).__init__()
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions

        self.model_name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, self.model_name+'_ddpg.h5')

        self.fc1 = Dense(self.fc1_dims, activation='relu')
        self.fc2 = Dense(self.fc2_dims, activation='relu')
        self.mu = Dense(self.n_actions, activation='tanh')      # Tanh is bounded by -+1 to bound action spaces

    def call(self, state):
        prob = self.fc1(state)
        prob = self.fc2(prob)

        mu = self.mu(prob)

        return mu

import os
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras.layers import Dense

#Critic network outputs the q values by taking the actions and pbservations into account
class CriticNetwork(keras.Model):
    def __init__(self, n_actions, fc1_dims = 512, fc2_dims=512, name='critic', chkpt_dir='tmp/ddpg'):
        super(CriticNetwork, self).__init__()
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions

        self.model_name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, self.model_name+'_ddpg.h5')

        self.fc1 = Dense(self.fc1_dims, activation='relu')  #1st layer
        self.fc2 = Dense(self.fc2_dims, activation='relu')  #2nd Layer
        self.q = Dense(1, activation=None)                  #Output Layer

    # Feedforward
    def call(self, state, action):
        action_value = self.fc1(tf.concat([state,action], axis=1))
        action_value = self.fc2(action_value)

        q = self.q(action_value)

        return q

# Actor network outputs the actions by taking the observations as input    
class ActorNetwork(keras.Model):
    def __init__(self, fc1_dims=512, fc2_dims=512, n_actions=2, name='actor', chkpt_dir='tmp/ddpg'):
        super(ActorNetwork, self).__init__()
        self.fc1_dims = fc1_dims
        self.fc2_dims = fc2_dims
        self.n_actions = n_actions

        self.model_name = name
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, self.model_name+'_ddpg.h5')

        self.fc1 = Dense(self.fc1_dims, activation='relu')
        self.fc2 = Dense(self.fc2_dims, activation='relu')
        self.mu = Dense(self.n_actions, activation='tanh')      # Tanh is bounded by -+1 to bound action spaces

    def call(self, state):
        prob = self.fc1(state)
        prob = self.fc2(prob)

        mu = self.mu(prob)

        return mu

#Critic network outputs the q values by taking the actions and pbservations into account #1st layer #2nd Layer #Output Layer # Feedforward # Actor network outputs the actions by taking the observations as input # Tanh is bounded by -+1 to bound action spaces