Beispiel #1
0
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))),
                                     load_qt='learningRushMarine3.csv')
        self.rewardTable = RewardCollector(
            tableName='learningRushMarine3Reward.csv')

        self.previous_score = 0
        self.episodes = 0
        self.previous_idle_workers = 0
        self.previous_workers_count = 12
        self.previus_enemy_count = 0

        self.previous_action = None
        self.previous_state = None
Beispiel #2
0
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))),
                                     load_qt='learningBuildMarinesV3.csv')
        self.rewardTable = RewardCollector(
            tableName='learningBuildMarinesV3Reward.csv')

        self.previous_score = 0
        self.episodes = 0
        self.previous_army_count = 0
        self.previous_barracks_count = 0
        self.previous_idle_workers = 0

        self.previous_action = None
        self.previous_state = None
        self.last_build_x = None
        self.last_build_y = None
Beispiel #3
0
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(
            actions=list(range(len(smart_actions))),
            load_qt='learningCollectMineralsAndGas.csv')
        self.rewardTable = RewardCollector(
            tableName='learningCollectMineralsAndGasReward.csv',
            columnsRow=['mineral_count', 'vispen_count', 'scv_count'])

        self.previous_score = 0
        self.episodes = 0
        self.previous_mineral_count = 0
        self.previous_gas_count = 0
        self.previous_scv_count = 12
        self.previous_idle_workers = 12

        self.previous_action = None
        self.previous_state = None
Beispiel #4
0
class SmartAgent(base_agent.BaseAgent):
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))), load_qt= 'learningCollectMineralsAndGasV3.csv')
        self.rewardTable = RewardCollector(tableName = 'learningCollectMineralsAndGasV3Reward.csv', columnsRow = ['mineral_count', 'vispen_count', 'scv_count'])


        self.previous_score = 0
        self.episodes = 0
        self.previous_mineral_count = 0
        self.previous_gas_count = 0
        self.previous_scv_count = 12
        self.previous_idle_workers = 12

        self.previous_action = None
        self.previous_state = None
    
    def reset(self):
        self.qlearn.save_qtable('learningCollectMineralsAndGasV3.csv')
        self.rewardTable.collectReward(rewardRow = self.previous_score)
        self.rewardTable.save_table('learningCollectMineralsAndGasV3Reward.csv')
        self.previous_score = 0
        self.episodes += 1
        self.previous_mineral_count = 0
        self.previous_gas_count = 0
        self.previous_scv_count = 12
        self.previous_idle_workers = 12

    def step(self, obs):
        super(SmartAgent, self).step(obs)

        state, playerInformation, mineralsPosition, targetVespine, targetTerranCenter, targetForBuild, targetScv = get_state(obs)
        current_state = [state[0], state[1], state[2], state[3], state[4]]

        if self.previous_action is not None:
            reward = 0

            if state[0] > self.previous_mineral_count :
                  reward += REWARD_COLLECT_MINERAL

            if state[1] > self.previous_gas_count:
                reward += REWARD_COLLECT_GAS

            if state[3] > self.previous_scv_count:
                reward += REWARD_BUILD_SCV

            if state[4] < self.previous_idle_workers:
                reward += REWARD_SCV_BUSY
            
            self.qlearn.learn(str(self.previous_state), self.previous_action, reward, str(current_state))

        action = self.qlearn.choose_action(str(current_state))
        smart_action = smart_actions[int(action)]
        
        self.previous_score = { 'mineral_count': int(state[0]) + ((int(state[3]) - 12) * 50) + (int(state[5]) * 100) + (int(state[6]) * 75), 'vispen_count': state[1], 'scv_count': state[3], 'reward': obs.reward  }
        self.previous_gas_count = state[1]
        self.previous_mineral_count = state[0]
        self.previous_scv_count = state[3]
        self.previous_idle_workers = state[4]
        self.previous_state = current_state
        self.previous_action = action
        
        
        if smart_action == ACTION_DO_NOTHING:
          return FUNCTIONS.no_op()

        elif smart_action == ACTION_SELECT_WORKER:
          if playerInformation[0] == 1:
            return FUNCTIONS.select_idle_worker("select")
        
        elif smart_action == ACTION_GATHER:
          if playerInformation[1] == 1:
            return actions.FunctionCall(GATHER, [SCREEN, [mineralsPosition[1][10],  mineralsPosition[0][10]]])

        elif smart_action == ACTION_BUILD_REFINERY:
          if playerInformation[2] == 1:
            return actions.FunctionCall(BUILD_REFINERY, [SCREEN, targetVespine])
            
        elif smart_action == ACTION_SELECT_COMMAND_CENTER:
          return actions.FunctionCall(SELECT_POINT, [SCREEN, targetTerranCenter])

        elif smart_action == ACTION_TRAIN_SCV:
          if  playerInformation[3] == 1:
            return actions.FunctionCall(TRAIN_SCV, [SCREEN])

        elif smart_action == ACTION_BUILD_SUPPLY_DEPOT:
          if  playerInformation[4] == 1:
            return actions.FunctionCall(BUILD_SUPPLY_DEPOT, [SCREEN, targetForBuild])
        
        elif smart_action == ACTION_SELECT_SCV:
          if targetScv and playerInformation[0] == 1:
            return actions.FunctionCall(SELECT_POINT, [SCREEN, targetScv])

        return FUNCTIONS.no_op()
Beispiel #5
0
class SmartAgent(base_agent.BaseAgent):
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))),
                                     load_qt='learningRushMarine3.csv')
        self.rewardTable = RewardCollector(
            tableName='learningRushMarine3Reward.csv')

        self.previous_score = 0
        self.episodes = 0
        self.previous_idle_workers = 0
        self.previous_workers_count = 12
        self.previus_enemy_count = 0

        self.previous_action = None
        self.previous_state = None

    def reset(self):
        self.qlearn.save_qtable('learningRushMarine3.csv')
        self.rewardTable.collectReward(rewardRow=self.previous_score)
        self.rewardTable.save_table('learningRushMarine3Reward.csv')
        self.previous_score = 0
        self.episodes += 1
        self.previous_idle_workers = 0
        self.previous_workers_count = 12
        self.previus_enemy_count = 0

    def step(self, obs):
        super(SmartAgent, self).step(obs)

        state, playerInformation, mineralTarget, targetTerranCenter, targetForBuild, targetScv, targetForBuildBaracks, targetBarracks, targetAttackEnemy, targetEnemyBase = get_state(
            obs)
        current_state = [state[0], state[1], state[2], state[3], state[4]]

        if self.previous_action is not None:
            reward = 0

            if smart_actions[int(
                    self.previous_action
            )] == ACTION_TRAIN_MARINE and state[0] and state[4] < 1:
                reward += REWARD_BUILD_MARINE

            if smart_actions[int(
                    self.previous_action)] == ACTION_BUILD_BARRACKS and state[
                        1] < self.previous_idle_workers:
                reward += REWARD_BUILD_BARRACKS
            elif smart_actions[int(self.previous_action
                                   )] == ACTION_BUILD_SUPPLY_DEPOT and state[
                                       1] < self.previous_idle_workers:
                reward += REWARD_BUILD_BARRACKS
            elif state[1] < self.previous_idle_workers:
                reward += REWARD_SCV_BUSY

            # smart_actions[int(self.previous_action)] == ACTION_ATTACK_ENEMY and
            if state[3] > self.previus_enemy_count:
                reward += REWARD_KILLED_ENEMY

            self.qlearn.learn(str(self.previous_state), self.previous_action,
                              reward, str(current_state))

        action = self.qlearn.choose_action(str(current_state))
        smart_action = smart_actions[int(action)]

        self.previous_score = {'reward': obs.reward}
        self.previous_idle_workers = state[1]
        self.previus_enemy_count = state[3]
        self.previous_state = current_state
        self.previous_action = action

        if smart_action == ACTION_DO_NOTHING or targetTerranCenter == None:
            return FUNCTIONS.no_op()

        elif smart_action == ACTION_SELECT_WORKER:
            if playerInformation[0] == 1:
                return FUNCTIONS.select_idle_worker("select")

        elif smart_action == ACTION_GATHER:
            if playerInformation[1] == 1 and mineralTarget:
                return actions.FunctionCall(GATHER, [SCREEN, mineralTarget])

        elif smart_action == ACTION_SELECT_BARRACKS:
            if targetBarracks:
                return FUNCTIONS.select_point("select_all_type",
                                              targetBarracks)

        elif smart_action == ACTION_TRAIN_MARINE:
            if playerInformation[5] == 1:
                return actions.FunctionCall(TRAIN_MARINE, [SCREEN])

        elif smart_action == ACTION_BUILD_SUPPLY_DEPOT:
            if playerInformation[4] == 1:
                return actions.FunctionCall(BUILD_SUPPLY_DEPOT,
                                            [SCREEN, targetForBuild])

        elif smart_action == ACTION_BUILD_BARRACKS:
            if playerInformation[2] == 1:
                return actions.FunctionCall(BUILD_BARRACKS,
                                            [SCREEN, targetForBuildBaracks])

        elif smart_action == ACTION_SELECT_SCV:
            if targetScv:
                return actions.FunctionCall(SELECT_POINT, [SCREEN, targetScv])

        elif smart_action == ACTION_SELECT_ARMY:
            if playerInformation[6] == 1:
                return FUNCTIONS.select_army("select")

        elif smart_action == ACTION_ATTACK_ENEMY:
            if state[2] == 1 and targetAttackEnemy:
                return actions.FunctionCall(ATTACK_MINIMAP,
                                            [SCREEN, targetAttackEnemy])

        # elif smart_action == ACTION_ATTACK_BASE:
        #   if state[2] == 1 and state[4] == 1 and targetEnemyBase:
        #     return actions.FunctionCall(ATTACK_MINIMAP, [SCREEN, targetEnemyBase])

        return FUNCTIONS.no_op()
Beispiel #6
0
class SmartAgent(base_agent.BaseAgent):
    def get_state(self, obs):
        unit_type = obs.observation.feature_screen[UNIT_TYPE]
        playerInformation = obs.observation['player']

        mineral_count = playerInformation[1]
        vispen_count = playerInformation[2]
        supply_limit = playerInformation[4]
        scv_count = playerInformation[6]
        idle_workers = playerInformation[7]
        army_count = playerInformation[8]
        army_food_taken = playerInformation[5]

        supply_depot_count = int(round((supply_limit - 15) / 8))

        player_y, player_x = (obs.observation.feature_screen[_AI_RELATIVE] ==
                              _AI_SELF).nonzero()
        base_top_left = 1 if player_y.any() and player_y.mean() <= 31 else 0

        canSelectWorker = 1 if SELECT_IDLE_WORKER in obs.observation[
            'available_actions'] else 0
        canGather = 1 if GATHER in obs.observation['available_actions'] else 0
        canBuildBarracks = 1 if BUILD_BARRACKS in obs.observation[
            'available_actions'] else 0
        canTrainScv = 1 if TRAIN_SCV in obs.observation[
            'available_actions'] and supply_limit > (scv_count +
                                                     army_food_taken) else 0
        canBuildSupplyDepot = 1 if BUILD_SUPPLY_DEPOT in obs.observation[
            'available_actions'] else 0
        canTrainMarine = 1 if TRAIN_MARINE in obs.observation[
            'available_actions'] and supply_limit > (scv_count +
                                                     army_food_taken) else 0

        barracks_y, barracks_x = (unit_type == BARRACKS).nonzero()
        mineral_y, mineral_x = (unit_type == MINERALFIELD).nonzero()
        terran_center_y, terran_center_x = (
            unit_type == TERRAN_COMMAND_CENTER).nonzero()
        targetTerranCenter = [terran_center_x.mean(), terran_center_y.mean()]

        targetBarracks = None
        if barracks_y.any():
            i = random.randint(0, len(barracks_y) - 1)
            targetBarracks = [barracks_x[i].mean(), barracks_y[i].mean()]

        mineralTarget = None
        if mineral_y.any():
            i = random.randint(0, len(mineral_y) - 1)
            mineralTarget = [mineral_x[i], mineral_y[i]]

        if supply_depot_count == 0:
            self.last_build_x = int(terran_center_x.mean())
            self.last_build_y = int(terran_center_y.mean())
            targetForBuild = transformLocation(base_top_left,
                                               self.last_build_x, -10,
                                               self.last_build_y, 20)
        else:
            x = random.randint(2, 3)
            targetForBuild = transformLocation(base_top_left,
                                               int(terran_center_x.mean()),
                                               -10 * x,
                                               int(terran_center_y.mean()), 20)
            self.last_build_x = targetForBuild[0]
            self.last_build_y = targetForBuild[1]

        targetForBuildBaracks = transformLocation(base_top_left,
                                                  int(terran_center_x.mean()),
                                                  0,
                                                  int(terran_center_y.mean()),
                                                  20)

        barracks_count = round(len(barracks_y) /
                               137) if barracks_y.any() else 0

        targetScv = None
        scv_y, scv_x = (unit_type == TERRAN_SCV).nonzero()
        if scv_y.any():
            i = random.randint(0, len(scv_y) - 1)
            targetScv = [scv_x[i], scv_y[i]]

        return (
            barracks_count, army_count, supply_depot_count, idle_workers
        ), (
            canSelectWorker, canGather, canBuildBarracks, canTrainScv,
            canBuildSupplyDepot, canTrainMarine
        ), mineralTarget, targetTerranCenter, targetForBuild, targetScv, targetForBuildBaracks, targetBarracks

    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))),
                                     load_qt='learningBuildMarinesV3.csv')
        self.rewardTable = RewardCollector(
            tableName='learningBuildMarinesV3Reward.csv')

        self.previous_score = 0
        self.episodes = 0
        self.previous_army_count = 0
        self.previous_barracks_count = 0
        self.previous_idle_workers = 0

        self.previous_action = None
        self.previous_state = None
        self.last_build_x = None
        self.last_build_y = None

    def reset(self):
        self.qlearn.save_qtable('learningBuildMarinesV3.csv')
        self.rewardTable.collectReward(rewardRow=self.previous_score)
        self.rewardTable.save_table('learningBuildMarinesV3Reward.csv')
        self.previous_score = 0
        self.episodes += 1
        self.previous_army_count = 0
        self.previous_barracks_count = 0
        self.previous_idle_workers = 0
        self.last_build_x = None
        self.last_build_y = None

    def step(self, obs):
        super(SmartAgent, self).step(obs)

        state, playerInformation, mineralTarget, targetTerranCenter, targetForBuild, targetScv, targetForBuildBaracks, targetBarracks = self.get_state(
            obs)
        current_state = [state[0], state[1], state[2]]

        if self.previous_action is not None:
            reward = 0

            if state[1] > self.previous_army_count:
                reward += (state[1] - self.previous_army_count)

            self.qlearn.learn(str(self.previous_state), self.previous_action,
                              reward, str(current_state))

        action = self.qlearn.choose_action(str(current_state))
        smart_action = smart_actions[int(action)]

        self.previous_score = {'reward': state[1]}
        self.previous_army_count = state[1]
        self.previous_barracks_count = state[0]
        self.previous_state = current_state
        self.previous_action = action

        if smart_action == ACTION_DO_NOTHING:
            return FUNCTIONS.no_op()

        elif smart_action == ACTION_SELECT_WORKER:
            if playerInformation[0] == 1:
                return FUNCTIONS.select_idle_worker("select")

        elif smart_action == ACTION_GATHER:
            if playerInformation[1] == 1 and mineralTarget:
                return actions.FunctionCall(GATHER, [SCREEN, mineralTarget])

        elif smart_action == ACTION_SELECT_BARRACKS:
            if targetBarracks:
                return FUNCTIONS.select_point("select_all_type",
                                              targetBarracks)

        elif smart_action == ACTION_TRAIN_MARINE:
            if playerInformation[5] == 1:
                return actions.FunctionCall(TRAIN_MARINE, [SCREEN])

        elif smart_action == ACTION_BUILD_SUPPLY_DEPOT:
            if playerInformation[4] == 1:
                return actions.FunctionCall(BUILD_SUPPLY_DEPOT,
                                            [SCREEN, targetForBuild])

        elif smart_action == ACTION_BUILD_BARRACKS:
            if playerInformation[2] == 1:
                return actions.FunctionCall(BUILD_BARRACKS,
                                            [SCREEN, targetForBuildBaracks])

        elif smart_action == ACTION_SELECT_SCV:
            if targetScv:
                return FUNCTIONS.select_point("select", targetScv)

        return FUNCTIONS.no_op()
class SmartAgent(base_agent.BaseAgent):
    def __init__(self):
        super(SmartAgent, self).__init__()

        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))), load_qt= 'learningBuildMarinesV4.csv')
        self.rewardTable = RewardCollector(tableName = 'learningBuildMarinesV4Reward.csv', columnsRow = ['reward', 'workers', 'supply_depot', 'barracks'])

        self.previous_score = 0
        self.episodes = 0
        self.previous_army_count = 0
        self.previous_barracks_count = 0
        self.previous_idle_workers = 0
        self.previous_workers_count = 12

        self.previous_action = None
        self.previous_state = None
    
    def reset(self):
        self.qlearn.save_qtable('learningBuildMarinesV4.csv')
        self.rewardTable.collectReward(rewardRow = self.previous_score)
        self.rewardTable.save_table('learningBuildMarinesV4Reward.csv')
        self.previous_score = 0
        self.episodes += 1
        self.previous_army_count = 0
        self.previous_barracks_count = 0
        self.previous_idle_workers = 0
        self.previous_workers_count = 12

    def step(self, obs):
        super(SmartAgent, self).step(obs)

        state, playerInformation, mineralTarget, targetTerranCenter, targetForBuild, targetScv, targetForBuildBaracks, targetBarracks = get_state(obs)
        current_state = [state[0], state[2], state[3], state[4], state[5]]

        if self.previous_action is not None:
            reward = 0

            if smart_actions[int(self.previous_action)] == ACTION_TRAIN_MARINE and state[4] >= self.previous_army_count:
              reward += REWARD_BUILD_MARINE

            if state[0] > self.previous_barracks_count:
              reward += REWARD_BUILD_BARRACKS

            if state[5] < self.previous_idle_workers:
              reward += REWARD_SCV_BUSY

            if smart_actions[int(self.previous_action)] == ACTION_TRAIN_SCV and state[3] >= self.previous_workers_count:
              reward -= REWARD_SCV_BUSY
            
            self.qlearn.learn(str(self.previous_state), self.previous_action, reward, str(current_state))

        action = self.qlearn.choose_action(str(current_state))
        smart_action = smart_actions[int(action)]
        
        self.previous_score = { 'reward': state[1], 'workers': state[3], 'supply_depot': state[2], 'barracks': state[0] }
        self.previous_army_count = state[4]
        self.previous_barracks_count = state[0]
        self.previous_idle_workers = state[5]
        self.previous_workers_count = state[3]
        self.previous_state = current_state
        self.previous_action = action
        
        
        if smart_action == ACTION_DO_NOTHING:
          return FUNCTIONS.no_op()

        elif smart_action == ACTION_SELECT_WORKER:
          if playerInformation[0] == 1:
            return FUNCTIONS.select_idle_worker("select")
        
        elif smart_action == ACTION_GATHER:
          if playerInformation[1] == 1 and mineralTarget:
            return actions.FunctionCall(GATHER, [SCREEN, mineralTarget])
            
        elif smart_action == ACTION_SELECT_COMMAND_CENTER:
          return actions.FunctionCall(SELECT_POINT, [SCREEN, targetTerranCenter])

        elif smart_action == ACTION_SELECT_BARRACKS:
          if targetBarracks:
            return FUNCTIONS.select_point("select_all_type", targetBarracks)

        elif smart_action == ACTION_TRAIN_SCV:
          if  playerInformation[3] == 1:
            return actions.FunctionCall(TRAIN_SCV, [SCREEN])

        elif smart_action == ACTION_TRAIN_MARINE:
          if  playerInformation[5] == 1:
            return actions.FunctionCall(TRAIN_MARINE, [SCREEN])

        elif smart_action == ACTION_BUILD_SUPPLY_DEPOT:
          if  playerInformation[4] == 1:
            return actions.FunctionCall(BUILD_SUPPLY_DEPOT, [SCREEN, targetForBuild])
        
        elif smart_action == ACTION_BUILD_BARRACKS:
          if  playerInformation[2] == 1:
            return actions.FunctionCall(BUILD_BARRACKS, [SCREEN, targetForBuildBaracks])
        
        elif smart_action == ACTION_SELECT_SCV:
          if targetScv:
            return actions.FunctionCall(SELECT_POINT, [SCREEN, targetScv])

        return FUNCTIONS.no_op()
class SmartAgent(base_agent.BaseAgent):
    # depot_x = 5

    def __init__(self):
        self.qlearn = QLearningTable(actions=list(range(len(smart_actions))))
        self.previous_score = 0
        self.previous_killed_unit_score = 0
        self.previous_killed_building_score = 0
        self.previous_action = None
        self.previous_state = None

        self.depot_x = 5
        self.depot_y = 5

    # def transformLocation(self, x, x_distance, y, y_distance):
    #     if not self.base_top_left:
    #         return [max(x - x_distance, 0), max(y - y_distance, 0)]
    #
    #     return [min(x + x_distance, MAP_MAXSIZE), min(y + y_distance, MAP_MAXSIZE)]

    def step(self, obs):

        super(SmartAgent, self).step(obs)

        player_y, player_x = (obs.observation['minimap'][_PLAYER_RELATIVE] ==
                              _PLAYER_SELF).nonzero()
        self.base_top_left = 1 if player_y.any(
        ) and player_y.mean() <= 31 else 0

        unit_type = obs.observation['screen'][_UNIT_TYPE]
        depot_y, depot_x = (unit_type == TERRAN.SUPPLY_DEPOT).nonzero()

        supply_depot_count = supply_depot_count = 1 if depot_y.any() else 0

        barracks_y, barracks_x = (unit_type == TERRAN.BARRACKS).nonzero()
        barracks_count = 1 if barracks_y.any() else 0

        supply_limit = obs.observation['player'][4]
        army_supply = obs.observation['player'][5]

        killed_unit_score = obs.observation['score_cumulative'][5]
        score = obs.observation['score_cumulative'][0]
        killed_building_score = obs.observation['score_cumulative'][6]

        current_state = [
            supply_depot_count,
            barracks_count,
            supply_limit,
            army_supply,
        ]

        if self.previous_action is not None:
            reward = 0

            if killed_unit_score > self.previous_killed_unit_score:
                reward += REWARD.KILL_UNIT

            if killed_unit_score < self.previous_killed_unit_score:
                reward += REWARD.LOST_UNIT

            if killed_building_score > self.previous_killed_building_score:
                reward += REWARD.KILL_BUILDING

            # if 0 != reward:

            tt = math.exp(-np.logaddexp(0, -(score - self.previous_score)))

            self.qlearn.learn(str(self.previous_state), self.previous_action,
                              tt, str(current_state))

        rl_action = self.qlearn.choose_action(str(current_state))
        smart_action = smart_actions[rl_action]

        self.previous_score = score
        self.previous_killed_unit_score = killed_unit_score
        self.previous_killed_building_score = killed_building_score
        self.previous_state = current_state
        self.previous_action = rl_action

        if smart_action == ACTION_DO_NOTHING:
            # ScLogger.logbo(smart_action)
            return actions.FunctionCall(_NO_OP, [])

        elif smart_action == ACTION_SELECT_SCV:
            unit_type = obs.observation['screen'][_UNIT_TYPE]
            unit_y, unit_x = (unit_type == TERRAN.SCV).nonzero()

            if unit_y.any() and len(unit_y) > 1:
                i = random.randrange(0, len(unit_y) - 1)
                target = [unit_x[i], unit_y[i]]

                return actions.FunctionCall(_SELECT_POINT, [_SCREEN, target])

        elif smart_action == ACTION_BUILD_SUPPLY_DEPOT and supply_depot_count == 0:
            if _BUILD_SUPPLY_DEPOT in obs.observation['available_actions']:
                ScLogger.logbo(smart_action)
                target = self.findLocationForBuilding(obs,
                                                      TERRAN.SUPPLY_DEPOT_SIZE)
                return actions.FunctionCall(_BUILD_SUPPLY_DEPOT,
                                            [_SCREEN, target])

        elif smart_action == ACTION_BUILD_BARRACKS:
            if _BUILD_BARRACKS in obs.observation['available_actions']:
                ScLogger.logbo(smart_action)
                target = self.findLocationForBuilding(obs,
                                                      TERRAN.BARRACKS_SIZE)
                return actions.FunctionCall(_BUILD_BARRACKS, [_SCREEN, target])

        elif smart_action == ACTION_SELECT_BARRACKS:
            unit_type = obs.observation['screen'][_UNIT_TYPE]
            unit_y, unit_x = (unit_type == TERRAN.BARRACKS).nonzero()

            if unit_y.any():
                target = [int(unit_x.mean()), int(unit_y.mean())]
                return actions.FunctionCall(_SELECT_POINT, [_SCREEN, target])

        elif smart_action == ACTION_BUILD_MARINE:
            ScLogger.logbo(smart_action)
            if _TRAIN_MARINE in obs.observation['available_actions']:
                return actions.FunctionCall(_TRAIN_MARINE, [[1]])

        elif smart_action == ACTION_SELECT_ARMY:
            if _SELECT_ARMY in obs.observation['available_actions']:
                return actions.FunctionCall(_SELECT_ARMY, [[0]])

        elif smart_action == ACTION_ATTACK:
            if _ATTACK_MINIMAP in obs.observation["available_actions"]:
                if self.base_top_left:
                    return actions.FunctionCall(_ATTACK_MINIMAP,
                                                [[1], [39, 45]])

                return actions.FunctionCall(_ATTACK_MINIMAP, [[1], [21, 24]])

        return actions.FunctionCall(_NO_OP, [])

    def findLocationForBuilding(self, obs, size):
        unit_type = obs.observation["screen"][_UNIT_TYPE]
        minefield_y, minefield_x = (
            unit_type == NEUTRAL.MINERALFIELD).nonzero()
        max_y, max_x = unit_type.shape
        distance = 6
        chance = 10
        while True:
            s_target_x = int(self.depot_x +
                             np.random.choice([-1, 0, 1], 1) * distance)
            s_target_y = int(self.depot_y +
                             np.random.choice([-1, 0, 1], 1) * distance)
            within_map = (0 < s_target_x < max_x - size) and (0 < s_target_y <
                                                              max_y - size)
            buildings = [NEUTRAL.MINERALFIELD] + TERRAN.BUILDINGS
            ScLogger.log(buildings)
            area = unit_type[s_target_y:s_target_y + 6][s_target_x:s_target_x +
                                                        6]
            space_available = not any(x in area for x in buildings)
            within_mineral_field = (
                min(minefield_y) < s_target_y < max(minefield_y)) and (
                    min(minefield_x) < s_target_x < 11 + max(minefield_x))
            chance += -1
            if within_map and space_available and not within_mineral_field:
                self.depot_x = s_target_x
                self.depot_y = s_target_y
                s_target = np.array([s_target_x, s_target_y])
                ScLogger.log(s_target)
                break
            if chance == 0:
                distance += 1
                chance = 10
        ScLogger.log("Go go building")
        return s_target