woodsja icon

Classes are for nerds

woodsja | PRO | 11/18/18 08:49:06 PM UTC | 0 ⭐ | 418 👁️ | Never ⏰ | []
Python |

5.34 KB

|

None

|

0 👍

/

0 👎

from pysc2.agents import base_agent
from pysc2.env import sc2_env
from pysc2.lib import actions, features, units
from absl import app
import time
from datetime import datetime
 
 
import numpy as np
 
 
 
SCREEN_SIZE = 84
MINIMAP_SIZE = 64
 
# A3C example from: https://github.com/greentfrapp/pysc2-RLagents/blob/master/Agents/PySC2_A3C_AtariNet.py
 
"""
Use the following command to launch Tensorboard:
tensorboard --logdir=worker_0:'./train_0',worker_1:'./train_1',worker_2:'./train_2',worker_3:'./train_3'
"""
 
# helper functions
 
# copies one set of variables to another
# used to set worker network parameters to those of the global network
def update_target_graph(from_scope, to_scope):
  from_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, from_scope)
  to_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, to_scope)
  op_holder = []
  for from_var, to_var, in zip(from_vars, to_vars):
    op_holder.append(to_var.assign(from_var))
  return op_holder
 
def process_observation(observation, action_spec):
  # reward
  reward = observation.reward
  # features
  features = observation.observation
  # these have spatial data that we should process with a conv net
  spatial_features = ['feature_minimap','feature_screen']
  # they're variable features because they change size depending on what you select
  variable_features = ['cargo','multi_select','build_queue']
  available_actions = ['available_actions']
 
  # shapes of some features depend on the state
  # tf requires fixed-input shapes, set max size then pad the input if it falls short
  max_no = {'available_actions':len(action_spec.functions), 'cargo': 500, 'multi_select': 500, 'build_queue': 10}
  non_spatial_stack = []
  for feature_label in observation.observation:
    if feature_label not in spatial_features + variable_features + available_actions:
      non_spatial_stack = np.concatenate((non_spatial_stack, feature_label.reshape(-1)))
 
 
class minigame_agent(base_agent.BaseAgent):
  def __init__(self):
    super(minigame_agent, self).__init__()
 
 
  def step(self, obs):
    super(minigame_agent, self).step(obs)
 
    # single_select will always be a tuple(7,) i.e. invarient dims
    #raveled_single_select = np.ravel(obs.observation.single_select[0]).tolist()
    #single_select = raveled_single_select
 
    # multi_select will be a tuple(n,7) *if* something's selected.
    # If nothing is selected multi_select will return NoneType
    # DefeatRoaches has at most 9 marines you can select...
    # since there's gonna be a maximum of 200 units, why not map onto a bigger vector of zeros?
    #raveled_multi_select = np.ravel(obs.observation.multi_select).tolist()
    #multi_select = [0] * 7 * 9
    #for i, item in enumerate(raveled_multi_select):
    #  multi_select[i] = item
 
    # feature_screen should always be a tuple(17, SCREEN_SIZE, SCREEN_SIZE)
    #feature_screen = obs.observation.feature_screen.tolist()
 
 
    # feature_minimap should always be a tuple(7, SCREEN_SIZE, SCREEN_SIZE)
    #feature_minimap = obs.observation.feature_minimap.tolist()
 
 
    # player should always be a tuple(11,)
    #raveled_player = np.ravel(obs.observation.player).tolist()
    #player = raveled_player
 
    # feature_units will be a tuple(n,26) where n is the number of units present on the map
    # since there's a maximum of 200 units why not map onto a bigger vector of zeros?
    # in DefeatRoaches, there are a maximum of 9+5 units
 
    #raveled_feature_units = np.ravel(obs.observation.feature_units).tolist()
    #feature_units = [0] * 26 * 14
    #for i, item in enumerate(raveled_feature_units):
    #  feature_units[i] = item
 
    # Since actions are sequenced, it would be nice to have them as a one-hot implementation; 523 total actions
    #raveled_available_actions = np.ravel(obs.observation.available_actions).tolist()
    #available_actions = [0] * 523
    #for i, item in enumerate(raveled_available_actions):
    #  available_actions[item] = 1
 
    # what happens if we just work off the nonspatial list first?
    #nonspatial_list = single_select + multi_select + player + feature_units + available_actions
 
    #process_observation(self.obs_spec, self.action_spec)
 
    # put a break point here to see what's going on
    return actions.FUNCTIONS.no_op()
 
def main(unused_argv):
  agent = minigame_agent()
  try:
    while True:
      try:
        with sc2_env.SC2Env(
          map_name="DefeatRoaches",
          agent_interface_format=features.AgentInterfaceFormat(
            feature_dimensions=features.Dimensions(screen=SCREEN_SIZE,
                                                   minimap=MINIMAP_SIZE),
            use_feature_units=True),
          step_mul=1,
          game_steps_per_episode=0,
          visualize=True,
          ) as env:
 
          agent.setup(env.observation_spec(), env.action_spec())
          timesteps = env.reset()
          agent.reset()
 
          while True:
            step_actions = [agent.step(timesteps[0])]
            timesteps = env.step(step_actions)
 
      except KeyboardInterrupt:
        raise
      except Exception as e:
        with open('log.txt', 'a') as myfile:
          myfile.write('At %s recorded exception: %s.\n' %
                       (datetime.now(), repr(e)))
 
  except KeyboardInterrupt:
    pass
 
if __name__ == "__main__":
  app.run(main)

Comments