code: def run_episode(env, agents, config, test=False):
      o, u, r, s, avail_u, u_onehot, isover, padded = (
          [],
          [],
          [],
          [],
          [],
          [],
          [],
          [],
      )
      env.reset()
      done = False
      step = 0
      ep_reward = 0
      last_act = [0 for _ in range(config["n_agents"])]
      agents.init_hidden()  # init rnn h0 for all agents
  
      while not done:
          obs = env.get_obs()
          state = env.get_state()
          acts, avail_acts, acts_onehot = [], [], []
  
          for agent_id in range(config["n_agents"]):
              avail_act = env.get_avail_agent_actions(agent_id)
  
              # action
              epsilon = 0 if test else config["epsilon"]
              act = agents.sample(
                  obs[agent_id],
                  last_act[agent_id],
                  agent_id,
                  avail_act,
                  epsilon,
                  test,
              )
              last_act[agent_id] = act
  
              # action one-hot
              act_onehot = np.zeros(config["n_actions"])
              act_onehot[act] = 1
              acts.append(act)
              acts_onehot.append(act_onehot)
              avail_acts.append(avail_act)
  
          # step
          reward, done, _ = env.step(acts)
  
          if step == config["episode_limit"] - 1:
              done = 1
  
          o.append(obs)
          s.append(state)
          u.append(np.reshape(acts, [config["n_agents"], 1]))
          u_onehot.append(acts_onehot)
          avail_u.append(avail_acts)
          r.append([reward])
          isover.append([done])
          padded.append([0.0])  # 0: no padded, 1: padded
  
          ep_reward += reward
          step += 1
  
      # fill trainsition len to episode_limit
      for _ in range(step, config["episode_limit"]):
          # shape: (config['episode_limit'], n_agents, shape)
          o.append(np.zeros((config["n_agents"], config["obs_shape"])))
          s.append(np.zeros(config["state_shape"]))
          u.append(np.zeros([config["n_agents"], 1]))
          u_onehot.append(
              np.zeros((config["n_agents"], config["n_actions"]))
          )
          avail_u.append(
              np.zeros((config["n_agents"], config["n_actions"]))
          )
          # shape: (config['episode_limit'], 1)
          r.append([0.0])
          padded.append([1.0])
          isover.append([1.0])
  
      ep_data = dict(
          o=o.copy(),
          s=s.copy(),
          u=u.copy(),
          r=r.copy(),
          avail_u=avail_u.copy(),
          u_onehot=u_onehot.copy(),
          padded=padded.copy(),
          isover=isover.copy(),
      )
  
      # add an additional dimension at axis 0 for each item
      for key in ep_data.keys():
          # each items shape: (1, trainsition_num, n_agents, own_shape)
          ep_data[key] = np.array([ep_data[key]])
  
      return ep_data, ep_reward
  
file_path: PARL/benchmark/torch/coma/train.py
imports: from smac.env import StarCraft2Env
  import numpy
  import os
  from sc2_model import ComaModel
  from sc2_agent import Agents
  from parl.algorithms import COMA
  from parl.utils import summary
label_desc: Use image node_id 1 for calling a global function with example usage: run_episode(env, agents, config, test) and returns: ep_data,  ep_reward