def render(self):
    self.PLAYERA = pygame.image.load('images/cap.jpg')
    self.PLAYERA = pygame.transform.scale(self.PLAYERA, (50, 50))
    self.PLAYERB = pygame.image.load('images/cap.jpg')
    self.PLAYERB = pygame.transform.scale(self.PLAYERB, (50, 50))
    self.ball = pygame.image.load('images/ball.png')
    self.ball = pygame.transform.scale(self.ball, (15, 15))
    self.playerax = 150
    self.playerbx = 250
    self.ballx = 250
    self.bally = 300
    count = 0
    nextplayer = 'A'
    (obs, reward, done, info) = self.stepA(0)
    stateA = obs
    stateB = obs
    next_state = 0
    iterations = 20000
    iteration = 0
    restart = False
    while (iteration < iterations):
        self.display()
        self.randNumLabelA = self.myFontA.render(((('A (Win): ' + str(self.updateRewardA)) + ', A(loss): ') + str(self.lossA)), 1, self.BLACK)
        self.randNumLabelB = self.myFontB.render(((('B (Win): ' + str(self.updateRewardB)) + ', B(loss): ') + str(self.lossB)), 1, self.BLACK)
        self.randNumLabelIter = self.myFontIter.render(('Iterations: ' + str(self.updateIter)), 1, self.BLACK)
        if (nextplayer == 'A'):
            if (count == 0):
                q_valueA = AgentA.model.predict([stateA])
                actionA = AgentA.epsilon_greedy(q_valueA, iteration)
                (obs, reward, done, info) = self.stepA(action=actionA, count=count)
                next_stateA = obs
                AgentA.replay_memory.append((stateA, actionA, reward, next_stateA, (1.0 - done)))
                stateA = next_stateA
            else:
                q_valueA = AgentA.model.predict([stateA])
                actionA = AgentA.epsilon_greedy(q_valueA, iteration)
                (obs, reward, done, info) = self.stepA(action=actionA, count=count)
                next_stateA = obs
                stateA = next_stateA
            count += 1
            if (count == 50):
                count = 0
                self.updateRewardA += reward
                self.computeLossA(reward)
                if (reward == 0):
                    restart = True
                    time.sleep(0.5)
                    nextplayer = 'B'
                    self.playerbx = self.ballx
                else:
                    restart = False
                (X_state_val, X_action_val, rewards, X_next_state_val, continues) = AgentA.sample_memories(AgentA.batch_size)
                next_q_values = AgentA.model.predict([X_next_state_val])
                max_next_q_values = np.max(next_q_values, axis=1, keepdims=True)
                y_val = (rewards + ((continues * AgentA.discount_rate) * max_next_q_values))
                AgentA.model.fit(X_state_val, tf.keras.utils.to_categorical(X_next_state_val, num_classes=10), verbose=0)
                nextplayer = 'B'
                self.updateIter += 1
            else:
                nextplayer = 'A'
        else:
            if (count == 0):
                q_valueB = AgentB.model.predict([stateB])
                actionB = AgentB.epsilon_greedy(q_valueB, iteration)
                (obs, reward, done, info) = self.stepB(action=actionB, count=count)
                next_stateB = obs
                AgentB.replay_memory.append((stateB, actionB, reward, next_stateB, (1.0 - done)))
                stateB = next_stateB
            else:
                q_valueB = AgentB.model.predict([stateB])
                actionB = AgentB.epsilon_greedy(q_valueB, iteration)
                (obs, reward, done, info) = self.stepB(action=actionB, count=count)
                next_stateB = obs
                stateB = next_stateB
            count += 1
            if (count == 50):
                count = 0
                self.updateRewardB += reward
                self.computeLossB(reward)
                if (reward == 0):
                    restart = True
                    time.sleep(0.5)
                    nextplayer = 'A'
                    self.playerax = self.ballx
                else:
                    restart = False
                (X_state_val, X_action_val, rewards, X_next_state_val, continues) = AgentB.sample_memories(AgentB.batch_size)
                next_q_values = AgentB.model.predict([X_next_state_val])
                max_next_q_values = np.max(next_q_values, axis=1, keepdims=True)
                y_val = (rewards + ((continues * AgentB.discount_rate) * max_next_q_values))
                AgentB.model.fit(X_state_val, tf.keras.utils.to_categorical(X_next_state_val, num_classes=10), verbose=0)
                nextplayer = 'A'
                self.updateIter += 1
            else:
                nextplayer = 'B'
            count += 1
        self.DISPLAYSURF.blit(self.PLAYERA, (self.playerax, 50))
        self.DISPLAYSURF.blit(self.PLAYERB, (self.playerbx, 600))
        self.DISPLAYSURF.blit(self.ball, (self.ballx, self.bally))
        self.DISPLAYSURF.blit(self.randNumLabelA, (300, 630))
        self.DISPLAYSURF.blit(self.randNumLabelB, (300, 40))
        self.DISPLAYSURF.blit(self.randNumLabelIter, (50, 40))
        self.lastxcoordinate = self.ballx
        pygame.display.update()
        self.fpsClock.tick(self.FPS)
        for event in pygame.event.get():
            if (event.type == QUIT):
                AgentA.model.save('AgentA.h5')
                AgentB.model.save('AgentB.h5')
                pygame.quit()
                sys.exit()
def render(self):
    self.PLAYERA = pygame.image.load('images/cap.jpg')
    self.PLAYERA = pygame.transform.scale(self.PLAYERA, (50, 50))
    self.PLAYERB = pygame.image.load('images/cap.jpg')
    self.PLAYERB = pygame.transform.scale(self.PLAYERB, (50, 50))
    self.ball = pygame.image.load('images/ball.png')
    self.ball = pygame.transform.scale(self.ball, (15, 15))
    self.playerax = 150
    self.playerbx = 250
    self.ballx = 250
    self.bally = 300
    count = 0
    nextplayer = 'A'
    (obs, reward, done, info) = self.stepA(0)
    stateA = obs
    stateB = obs
    next_state = 0
    iterations = 20000
    iteration = 0
    restart = False
    while (iteration < iterations):
        self.display()
        self.randNumLabelA = self.myFontA.render(((('A (Win): ' + str(self.updateRewardA)) + ', A(loss): ') + str(self.lossA)), 1, self.BLACK)
        self.randNumLabelB = self.myFontB.render(((('B (Win): ' + str(self.updateRewardB)) + ', B(loss): ') + str(self.lossB)), 1, self.BLACK)
        self.randNumLabelIter = self.myFontIter.render(('Iterations: ' + str(self.updateIter)), 1, self.BLACK)
        if (nextplayer == 'A'):
            if (count == 0):
                q_valueA = AgentA.model.predict([stateA])
                actionA = AgentA.epsilon_greedy(q_valueA, iteration)
                (obs, reward, done, info) = self.stepA(action=actionA, count=count)
                next_stateA = obs
                AgentA.replay_memory.append((stateA, actionA, reward, next_stateA, (1.0 - done)))
                stateA = next_stateA
            else:
                q_valueA = AgentA.model.predict([stateA])
                actionA = AgentA.epsilon_greedy(q_valueA, iteration)
                (obs, reward, done, info) = self.stepA(action=actionA, count=count)
                next_stateA = obs
                stateA = next_stateA
            count += 1
            if (count == 50):
                count = 0
                self.updateRewardA += reward
                self.computeLossA(reward)
                if (reward == 0):
                    restart = True
                    time.sleep(0.5)
                    nextplayer = 'B'
                    self.playerbx = self.ballx
                else:
                    restart = False
                (X_state_val, X_action_val, rewards, X_next_state_val, continues) = AgentA.sample_memories(AgentA.batch_size)
                next_q_values = AgentA.model.predict([X_next_state_val])
                max_next_q_values = np.max(next_q_values, axis=1, keepdims=True)
                y_val = (rewards + ((continues * AgentA.discount_rate) * max_next_q_values))
                AgentA.model.fit(X_state_val, tf.keras.utils.to_categorical(X_next_state_val, num_classes=10), verbose=0)
                nextplayer = 'B'
                self.updateIter += 1
            else:
                nextplayer = 'A'
        else:
            if (count == 0):
                q_valueB = AgentB.model.predict([stateB])
                actionB = AgentB.epsilon_greedy(q_valueB, iteration)
                (obs, reward, done, info) = self.stepB(action=actionB, count=count)
                next_stateB = obs
                AgentB.replay_memory.append((stateB, actionB, reward, next_stateB, (1.0 - done)))
                stateB = next_stateB
            else:
                q_valueB = AgentB.model.predict([stateB])
                actionB = AgentB.epsilon_greedy(q_valueB, iteration)
                (obs, reward, done, info) = self.stepB(action=actionB, count=count)
                next_stateB = obs
                stateB = next_stateB
            count += 1
            if (count == 50):
                count = 0
                self.updateRewardB += reward
                self.computeLossB(reward)
                if (reward == 0):
                    restart = True
                    time.sleep(0.5)
                    nextplayer = 'A'
                    self.playerax = self.ballx
                else:
                    restart = False
                (X_state_val, X_action_val, rewards, X_next_state_val, continues) = AgentB.sample_memories(AgentB.batch_size)
                next_q_values = AgentB.model.predict([X_next_state_val])
                max_next_q_values = np.max(next_q_values, axis=1, keepdims=True)
                y_val = (rewards + ((continues * AgentB.discount_rate) * max_next_q_values))
                AgentB.model.fit(X_state_val, tf.keras.utils.to_categorical(X_next_state_val, num_classes=10), verbose=0)
                nextplayer = 'A'
                self.updateIter += 1
            else:
                nextplayer = 'B'
            count += 1
        self.DISPLAYSURF.blit(self.PLAYERA, (self.playerax, 50))
        self.DISPLAYSURF.blit(self.PLAYERB, (self.playerbx, 600))
        self.DISPLAYSURF.blit(self.ball, (self.ballx, self.bally))
        self.DISPLAYSURF.blit(self.randNumLabelA, (300, 630))
        self.DISPLAYSURF.blit(self.randNumLabelB, (300, 40))
        self.DISPLAYSURF.blit(self.randNumLabelIter, (50, 40))
        self.lastxcoordinate = self.ballx
        pygame.display.update()
        self.fpsClock.tick(self.FPS)
        for event in pygame.event.get():
            if (event.type == QUIT):
                AgentA.model.save('AgentA.h5')
                AgentB.model.save('AgentB.h5')
                pygame.quit()
                sys.exit()