Blizzard / s2client-api

StarCraft II Client - C++ library supported on Windows, Linux and Mac designed for building scripted bots and research using the SC2API.
MIT License
1.66k stars 281 forks source link

How do I use select unit? #133

Closed doudoujay closed 7 years ago

doudoujay commented 7 years ago

5/select_unit (8/select_unit_act [4]; 9/select_unit_id [500])

for example, I tried to use actions.FunctionCall(5, [[2],[21]]) passed in env.step. My intention is to select all type of _TERRAN_BARRACKS, but nothing happened...

KevinCalderone commented 7 years ago

Sounds like this is a question about the PySC2 interface. You may get a better answer posing on their repo.

This comment has some details on what that "select_unit " action type means. I don't think it is what you are looking for: https://github.com/deepmind/pysc2/issues/60#issuecomment-327028397

If you are using PySC2, I assume you are working in the feature layer interface? The primary actions for selecting are "select_point" and "selelect_rect". If you want to select all barracks on the screen, you can do a "select_point" on one of the barracks using the "AllType" parameter. (Equivalent to Control clicking on the unit)

doudoujay commented 7 years ago

Are the unit type id in pysc2 the same defined in s2client-api? For example, does 21 for _TERRAN_BARRACKS valid in pysc2?

KevinCalderone commented 7 years ago

Yes the ids should all be the same.

doudoujay commented 7 years ago

So, I tried several times to use FuntionCall(5,[[2],[21]]) which is select unit with ALL type for _TERRAN_BARRACKS in the game, and passed it in env.step(). I still can't get the correct result from the observation["sceen"][7], single_select tensor or multi_select tensor after that step. How do I fix this?

KevinCalderone commented 7 years ago

The "select_unit_id" parameter is not a unit type. It should probably be named something different.

This parameter represents "the index into the multi_select observation": https://github.com/deepmind/pysc2/issues/60#issuecomment-330587016

doudoujay commented 7 years ago

Ok, so I tried to use select point instead of select unit.

_SELECT_ALL_OF_TYPE = 2
_UNIT_TYPE_VIEW = features.SCREEN_FEATURES.unit_type.index
def getTerrainBarracksLocation(obs):
    if any(_TERRAN_BARRACKS in sublist for sublist in obs["screen"][_UNIT_TYPE_VIEW]):
        return zip(*np.where(obs["screen"][_UNIT_TYPE_VIEW] == _TERRAN_BARRACKS))
location = getTerrainBarracksLocation(timestep.observation)
point = list(location[0]) #get point from a lot of locations
a = _SELECT_POINT
args = [[_SELECT_ALL_OF_TYPE],point]
a_call = actions.FunctionCall(a, args)
timestep = env.step(actions=[a_call])[0]

But, after I step through the a_call, I still can't get the correct selected unit in single_select tensor or multi_select tensor. Any thing went wrong?

KevinCalderone commented 7 years ago

I am not familiar with how that PySC2 code works, but what you are trying to do seems right. You may get a better answer if you post an issue on the PySC2 github.

Do other actions work when you use that logic? (eg. Issue move order somewhere)