Dentosal / python-sc2

A StarCraft II bot api client library for Python 3
MIT License
586 stars 182 forks source link

cannot produce viking from starport #203

Closed ceacar closed 5 years ago

ceacar commented 5 years ago

tryied VIKING,VIKING_UNIT,VIKINGFIGHTER,VIKINGASSAULT ERROR:sc2.main:AI step threw an error Traceback (most recent call last): File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\main.py", line 63, in _play_game_ai await ai.on_step(iteration) File "D:/codes/python_workspace/sc2_ai/src/graze_ein.py", line 100, in on_step self.pump_force_terran() File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 217, in pump_force_terran self.produce_tank_marine_medivac() File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 194, in produce_tank_marine_medivac self.produce_force(UnitTypeId.STARPORT, UnitTypeId.VIKING, batch_count=1, maintain_at=viking_count_max) File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 168, in produce_force if self.can_afford(unit) and producer.noqueue: File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\bot_ai.py", line 258, in can_afford cost = self._game_data.calculate_ability_cost(unit.creation_ability) File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 38, in calculate_ability_cost assert isinstance(ability, AbilityData), f"C: {ability}" AssertionError: C: None ERROR:sc2.main:resigning due to previous error

tweakimp commented 5 years ago

can you also provide the code

ceacar commented 5 years ago

what used is this command "self.combinedActions.append(producer.train(unit))" in the end of iteration it will loop through self.combinedActions and then run the cmd inside self.do(cmd)

below is the full code, same code works for marine and siege tank, but not for viking:

def produce_force(self, building: 'UnitTypeId.BARRACKS', unit: 'UnitTypeId.MARINE', batch_count=1, maintain_at=999):
        if self.units(unit).amount >= maintain_at:
            # maintain unit at a level
            return
        counter = 0
        for producer in self.units(building):
            if self.can_afford(unit) and producer.noqueue:
                print("producing", unit, "from", building)
                self.combinedActions.append(producer.train(unit))
                counter = counter + 1
            if counter >= batch_count:
                # has queued targeted number
                break

#tried VIKING, VIKINGASSAULT, VIKINGFIGHTER and many more, no luck
self.produce_force(UnitTypeId.STARPORT, UnitTypeId.VIKINGSKY_UNIT, batch_count=1,
                               maintain_at=viking_count_max)
tweakimp commented 5 years ago

The unit you need to be ordering is definitely VIKINGFIGHTER. If you are using a list of actions, like self.combinedActions, you need to call it with await self.do_actions(self.combinedActions)

I built your code into of the Terran examples and it works with do_actions. https://pastebin.com/Nkf0Bqer

ceacar commented 5 years ago

thank you very much for your reply, i do use self.do_action(self.combinedActions), i didn't check my code and then said it is self.do, sorry about it. i tried VIKINGFIGHTER in my code it doesn't work, error below:

Traceback (most recent call last):
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\main.py", line 63, in _play_game_ai
    await ai.on_step(iteration)
  File "D:/codes/python_workspace/sc2_ai/src/graze_ein.py", line 100, in on_step
    self.pump_force_terran()
  File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 219, in pump_force_terran
    self.produce_tank_marine_medivac()
  File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 197, in produce_tank_marine_medivac
    self.produce_force(UnitTypeId.STARPORT, UnitTypeId.VIKINGFIGHTER, batch_count=1, maintain_at=viking_count_max)
  File "D:\codes\python_workspace\sc2_ai\src\terran_ai.py", line 168, in produce_force
    if self.can_afford(unit) and producer.noqueue:
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\bot_ai.py", line 258, in can_afford
    cost = self._game_data.calculate_ability_cost(unit.creation_ability)
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 59, in calculate_ability_cost
    morph_cost = unit.morph_cost
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 229, in morph_cost
    if self.tech_alias is None or self.tech_alias[0] in {UnitTypeId.TECHLAB, UnitTypeId.REACTOR}:
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 181, in tech_alias
    return_list.append(UnitTypeId(tech_alias))
  File "D:\codes\python3\lib\enum.py", line 309, in __call__
    return cls.__new__(cls, value)
  File "D:\codes\python3\lib\enum.py", line 561, in __new__
    raise exc
  File "D:\codes\python3\lib\enum.py", line 545, in __new__
    result = cls._missing_(value)
  File "D:\codes\python3\lib\enum.py", line 574, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 1940 is not a valid UnitTypeId

I thought it was my code caused this problem, so i tried the terran example script "onebase_battlecruiser.py" and then swap in the VIKINGFIGHTER

the code i swapped is

        if self.can_afford(VIKINGFIGHTER):
            for sp in self.units(STARPORT):
                if sp.has_add_on and sp.noqueue:
                    if not self.can_afford(VIKINGFIGHTER):
                        break
                    await self.do(sp.train(VIKINGFIGHTER)

Errors below:

ERROR:sc2.main:AI step threw an error
ValueError: 1940 is not a valid UnitTypeId

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\main.py", line 63, in _play_game_ai
    await ai.on_step(iteration)
  File ".\onebase_battlecruiser.py", line 55, in on_step
    if self.can_afford(VIKINGFIGHTER):
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\bot_ai.py", line 258, in can_afford
    cost = self._game_data.calculate_ability_cost(unit.creation_ability)
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 59, in calculate_ability_cost
    morph_cost = unit.morph_cost
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 229, in morph_cost
    if self.tech_alias is None or self.tech_alias[0] in {UnitTypeId.TECHLAB, UnitTypeId.REACTOR}:
  File "C:\Users\ceacar\AppData\Roaming\Python\Python37\site-packages\sc2\game_data.py", line 181, in tech_alias
    return_list.append(UnitTypeId(tech_alias))
  File "D:\codes\python3\lib\enum.py", line 309, in __call__
    return cls.__new__(cls, value)
  File "D:\codes\python3\lib\enum.py", line 561, in __new__
    raise exc
  File "D:\codes\python3\lib\enum.py", line 545, in __new__
    result = cls._missing_(value)
  File "D:\codes\python3\lib\enum.py", line 574, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 1940 is not a valid UnitTypeId
ERROR:sc2.main:resigning due to previous error
INFO:root:Result for player id: 1: Result.Defeat
INFO:sc2.protocol:Client status changed to Status.launched (was Status.in_game)
INFO:sc2.protocol:Client status changed to Status.quit (was Status.launched)
INFO:sc2.sc2process:kill_switch: Process cleanup
INFO:sc2.sc2process:Cleaning up...
INFO:sc2.sc2process:Cleanup complete
tweakimp commented 5 years ago

your ids are not up to date. run starcraft in case you are not on the current version already (4.8.1.71523) then run generate_id_constants_from_stableid.py

BurnySc2 commented 5 years ago

What tweakimp said. However if you just ran the pip install sc2 command then you might not have a generate_id_constants_from_stableid.py file doesn't get installed using pip, a pip install --upgrade sc2 should also work in this case.

ceacar commented 5 years ago

"pip install --upgrade sc2 " does solve the problem. thank you all