Пример #1
0
 async def _send_debug(self):
     """ Sends the debug draw execution. This is run by main.py now automatically, if there is any items in the list. You do not need to run this manually any longer.
     Check examples/terran/ramp_wall.py for example drawing. Each draw request needs to be sent again in every single on_step iteration.
     """
     debug_hash = (
         sum(hash(item) for item in self._debug_texts),
         sum(hash(item) for item in self._debug_lines),
         sum(hash(item) for item in self._debug_boxes),
         sum(hash(item) for item in self._debug_spheres),
     )
     if debug_hash != (0, 0, 0, 0):
         if debug_hash != self._debug_hash_tuple_last_iteration:
             # Something has changed, either more or less is to be drawn, or a position of a drawing changed (e.g. when drawing on a moving unit)
             self._debug_hash_tuple_last_iteration = debug_hash
             await self._execute(
                 debug=sc_pb.RequestDebug(
                     debug=[
                         debug_pb.DebugCommand(
                             draw=debug_pb.DebugDraw(
                                 text=[text.to_proto() for text in self._debug_texts] if self._debug_texts else None,
                                 lines=[line.to_proto() for line in self._debug_lines]
                                 if self._debug_lines
                                 else None,
                                 boxes=[box.to_proto() for box in self._debug_boxes] if self._debug_boxes else None,
                                 spheres=[sphere.to_proto() for sphere in self._debug_spheres]
                                 if self._debug_spheres
                                 else None,
                             )
                         )
                     ]
                 )
             )
         self._debug_draw_last_frame = True
         self._debug_texts.clear()
         self._debug_lines.clear()
         self._debug_boxes.clear()
         self._debug_spheres.clear()
     elif self._debug_draw_last_frame:
         # Clear drawing if we drew last frame but nothing to draw this frame
         self._debug_hash_tuple_last_iteration = (0, 0, 0, 0)
         await self._execute(
             debug=sc_pb.RequestDebug(
                 debug=[
                     debug_pb.DebugCommand(draw=debug_pb.DebugDraw(text=None, lines=None, boxes=None, spheres=None))
                 ]
             )
         )
         self._debug_draw_last_frame = False
Пример #2
0
    async def debug_text(self,
                         texts: Union[str, list],
                         positions: Union[list, set],
                         color=(0, 255, 0),
                         size_px=16):
        """ Deprecated, may be removed soon """
        if isinstance(positions, (set, list)):
            if not positions:
                return

            if isinstance(texts, str):
                texts = [texts] * len(positions)
            assert len(texts) == len(positions)

            await self._execute(debug=sc_pb.RequestDebug(debug=[
                debug_pb.DebugCommand(draw=debug_pb.DebugDraw(text=[
                    debug_pb.DebugText(
                        text=t,
                        color=debug_pb.Color(
                            r=color[0], g=color[1], b=color[2]),
                        world_pos=common_pb.Point(
                            x=p.x, y=p.y, z=getattr(p, "z", 10)),
                        size=size_px) for t, p in zip(texts, positions)
                ]))
            ]))
        else:
            await self.debug_text([texts], [positions], color)
Пример #3
0
 async def debug_set_unit_value(self, unit_tags: Union[Iterable[int], Units,
                                                       Unit],
                                unit_value: int, value: float):
     """ Sets a "unit value" (Energy, Life or Shields) of the given units to the given value.
     Can't set the life of a unit to 0, use "debug_kill_unit" for that. Also can't set the life above the unit's maximum.
     The following example sets the health of all your workers to 1:
     await self.debug_set_unit_value(self.workers, 2, value=1) """
     if isinstance(unit_tags, Units):
         unit_tags = unit_tags.tags
     if isinstance(unit_tags, Unit):
         unit_tags = [unit_tags.tag]
     assert hasattr(
         unit_tags, "__iter__"
     ), f"unit_tags argument needs to be an iterable (list, dict, set, Units), given argument is {type(unit_tags).__name__}"
     assert (
         1 <= unit_value <= 3
     ), f"unit_value needs to be between 1 and 3 (1 for energy, 2 for life, 3 for shields), given argument is {unit_value}"
     assert all(
         tag > 0
         for tag in unit_tags), f"Unit tags have invalid value: {unit_tags}"
     assert isinstance(
         value, (int, float)), "Value needs to be of type int or float"
     assert value >= 0, "Value can't be negative"
     await self._execute(debug=sc_pb.RequestDebug(
         debug=(debug_pb.DebugCommand(unit_value=debug_pb.DebugSetUnitValue(
             unit_value=unit_value, value=float(value), unit_tag=unit_tag))
                for unit_tag in unit_tags)))
Пример #4
0
 async def debug_hang(self, delay_in_seconds: float):
     """ Freezes the SC2 client. Not recommended to be used. """
     delay_in_ms = int(round(delay_in_seconds * 1000))
     await self._execute(debug=sc_pb.RequestDebug(debug=[
         debug_pb.DebugCommand(test_process=debug_pb.DebugTestProcess(
             test=1, delay_ms=delay_in_ms))
     ]))
Пример #5
0
    async def debug_create_unit(
        self, unit_spawn_commands: List[List[Union[UnitTypeId, int, Point2,
                                                   Point3]]]):
        """ Usage example (will spawn 5 marines in the center of the map for player ID 1):
        await self._client.debug_create_unit([[UnitTypeId.MARINE, 5, self._game_info.map_center, 1]])

        :param unit_spawn_commands: """
        assert isinstance(unit_spawn_commands, list)
        assert unit_spawn_commands
        assert isinstance(unit_spawn_commands[0], list)
        assert len(unit_spawn_commands[0]) == 4
        assert isinstance(unit_spawn_commands[0][0], UnitTypeId)
        assert unit_spawn_commands[0][
            1] > 0  # careful, in realtime=True this function may create more units
        assert isinstance(unit_spawn_commands[0][2], (Point2, Point3))
        assert 1 <= unit_spawn_commands[0][3] <= 2

        await self._execute(debug=sc_pb.RequestDebug(
            debug=(debug_pb.DebugCommand(create_unit=debug_pb.DebugCreateUnit(
                unit_type=unit_type.value,
                owner=owner_id,
                pos=common_pb.Point2D(x=position.x, y=position.y),
                quantity=amount_of_units,
            )) for unit_type, amount_of_units, position, owner_id in
                   unit_spawn_commands)))
Пример #6
0
    async def debug_kill_unit(self, unit_tags: Union[Units, List[int], Set[int]]):
        if isinstance(unit_tags, Units):
            unit_tags = unit_tags.tags
        assert unit_tags

        await self._execute(
            debug=sc_pb.RequestDebug(debug=[debug_pb.DebugCommand(kill_unit=debug_pb.DebugKillUnit(tag=unit_tags))])
        )
Пример #7
0
    def kill_all_units(self):

        units_alive = [
            unit.tag for unit in self.agents.values() if unit.health > 0
        ] + [unit.tag for unit in self.enemies.values() if unit.health > 0]
        debug_command = [
            d_pb.DebugCommand(kill_unit=d_pb.DebugKillUnit(tag=units_alive))
        ]
        self.controller.debug(debug_command)
Пример #8
0
 async def send_debug(self):
     """ Sends the debug draw execution. Put this after your debug creation functions. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(draw=debug_pb.DebugDraw(
             text=self._debug_texts if len(self._debug_texts) > 0 else None,
             lines=self._debug_lines if len(self._debug_lines) > 0 else None,
             boxes=self._debug_boxes if len(self._debug_boxes) > 0 else None,
             spheres=self._debug_spheres if len(self._debug_spheres) > 0 else None
         ))]))
     self._debug_texts.clear()
     self._debug_lines.clear()
     self._debug_boxes.clear()
     self._debug_spheres.clear()
Пример #9
0
 async def _send_debug(self):
     """ Sends the debug draw execution. This is run by main.py now automatically, if there is any items in the list. You do not need to run this manually any longer. """
     if self._debug_texts or self._debug_lines or self._debug_boxes or self._debug_spheres:
         await self._execute(debug=sc_pb.RequestDebug(debug=[
             debug_pb.DebugCommand(draw=debug_pb.DebugDraw(
                 text=self._debug_texts if self._debug_texts else None,
                 lines=self._debug_lines if self._debug_lines else None,
                 boxes=self._debug_boxes if self._debug_boxes else None,
                 spheres=self._debug_spheres if self.
                 _debug_spheres else None,
             ))
         ]))
         self._debug_draw_last_frame = True
         self._debug_texts.clear()
         self._debug_lines.clear()
         self._debug_boxes.clear()
         self._debug_spheres.clear()
     elif self._debug_draw_last_frame:
         # Clear drawing if we drew last frame but nothing to draw this frame
         await self._execute(debug=sc_pb.RequestDebug(debug=[
             debug_pb.DebugCommand(draw=debug_pb.DebugDraw(
                 text=None, lines=None, boxes=None, spheres=None))
         ]))
         self._debug_draw_last_frame = False
Пример #10
0
    async def debug_text(self, texts, positions, color=(0, 255, 0)):
        if isinstance(positions, list):
            if not positions:
                return

            if isinstance(texts, str):
                texts = [texts] * len(positions)
            assert len(texts) == len(positions)

            await self._execute(debug=sc_pb.RequestDebug(
                debug=[debug_pb.DebugCommand(draw=debug_pb.DebugDraw(
                    text=[debug_pb.DebugText(
                        text=t,
                        color=debug_pb.Color(r=color[0], g=color[1], b=color[2]),
                        world_pos=common_pb.Point(x=p.x, y=p.y, z=p.z)
                    ) for t, p in zip(texts, positions)]
                ))]
            ))
        else:
            await self.debug_text([texts], [positions], color)
Пример #11
0
 async def debug_minerals(self):
     """ Gives 5000 minerals to the bot. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=7)]))
Пример #12
0
 async def debug_god(self):
     """ Your units and structures no longer take any damage. Using it a second time disables it again. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=6)]))
Пример #13
0
 async def debug_all_resources(self):
     """ Gives 5000 minerals and 5000 vespene to the bot. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=5)]))
Пример #14
0
 async def debug_fast_build(self):
     """ Sets the build time of units and structures and upgrades to zero. Using it a second time disables it again. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=12)]))
Пример #15
0
 async def debug_tech_tree(self):
     """ Removes all tech requirements (e.g. can build a factory without having a barracks). Using it a second time disables it again. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=10)]))
Пример #16
0
 async def debug_leave(self):
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(end_game=debug_pb.DebugEndGame())]))
Пример #17
0
    def test_multi_player(self):
        run_config = run_configs.get()
        map_inst = maps.get("Simple64")

        with run_config.start(want_rgb=False) as controller:

            create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap(
                map_path=map_inst.path, map_data=map_inst.data(run_config)))
            create.player_setup.add(type=sc_pb.Participant)
            create.player_setup.add(type=sc_pb.Computer,
                                    race=sc_common.Terran,
                                    difficulty=sc_pb.VeryEasy)
            join = sc_pb.RequestJoinGame(
                race=sc_common.Terran,
                options=sc_pb.InterfaceOptions(raw=True))

            controller.create_game(create)
            controller.join_game(join)

            info = controller.game_info()
            map_size = info.start_raw.map_size

            controller.step(2)

            obs = controller.observe()

            def get_marines(obs):
                return {
                    u.tag: u
                    for u in obs.observation.raw_data.units
                    if u.unit_type == units.Terran.Marine
                }

            self.assertEmpty(get_marines(obs))

            controller.debug(
                sc_debug.DebugCommand(create_unit=sc_debug.DebugCreateUnit(
                    unit_type=units.Terran.Marine,
                    owner=1,
                    pos=sc_common.Point2D(x=map_size.x // 2, y=map_size.y //
                                          2),
                    quantity=5)))

            controller.step(2)

            obs = controller.observe()

            marines = get_marines(obs)
            self.assertEqual(5, len(marines))

            tags = sorted(marines.keys())

            controller.debug([
                sc_debug.DebugCommand(kill_unit=sc_debug.DebugKillUnit(
                    tag=[tags[0]])),
                sc_debug.DebugCommand(unit_value=sc_debug.DebugSetUnitValue(
                    unit_value=sc_debug.DebugSetUnitValue.Life,
                    value=5,
                    unit_tag=tags[1])),
            ])

            controller.step(2)

            obs = controller.observe()

            marines = get_marines(obs)
            self.assertEqual(4, len(marines))
            self.assertNotIn(tags[0], marines)
            self.assertEqual(marines[tags[1]].health, 5)
Пример #18
0
 async def debug_gas(self):
     """ Gives 5000 vespene to the bot. This does not seem to be working. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=8)]))
Пример #19
0
 async def debug_cooldown(self):
     """ Disables cooldowns of unit abilities for the bot. Using it a second time disables it again. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=9)]))
Пример #20
0
 async def debug_show_map(self):
     """ Reveals the whole map for the bot. Using it a second time disables it again. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=1)]))
Пример #21
0
 async def debug_upgrade(self):
     """ Researches all currently available upgrades. E.g. using it once unlocks combat shield, stimpack and 1-1. Using it a second time unlocks 2-2 and all other upgrades stay researched. """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=11)]))
Пример #22
0
 async def debug_control_enemy(self):
     """ Allows control over enemy units and structures similar to team games control - does not allow the bot to spend the opponent's ressources. Using it a second time disables it again.  """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=2)]))
Пример #23
0
 def debug(self, player=0, **kwargs):
     self._controllers[player].debug([sc_debug.DebugCommand(**kwargs)])
Пример #24
0
def test_multi_player(agents, disable_fog):
    players = 2
    if len(agents) == 2:
        agent1, agent2 = agents
    run_config = run_configs.get()
    parallel = run_parallel.RunParallel()
    map_inst = maps.get(FLAGS.map)

    screen_size_px = point.Point(64, 64)
    minimap_size_px = point.Point(32, 32)
    interface = sc_pb.InterfaceOptions(raw=True, score=True)
    screen_size_px.assign_to(interface.feature_layer.resolution)
    minimap_size_px.assign_to(interface.feature_layer.minimap_resolution)

    # Reserve a whole bunch of ports for the weird multiplayer implementation.
    ports = [portpicker.pick_unused_port() for _ in range(1 + players * 2)]
    print("Valid Ports: %s", ports)

    # Actually launch the game processes.
    print("start")
    sc2_procs = [run_config.start(extra_ports=ports) for _ in range(players)]
    controllers = [p.controller for p in sc2_procs]

    try:
        # Save the maps so they can access it.
        map_path = os.path.basename(map_inst.path)
        print("save_map")
        parallel.run((c.save_map, map_path, run_config.map_data(map_inst.path))
                     for c in controllers)

        # Create the create request.
        real_time = True
        create = sc_pb.RequestCreateGame(
            local_map=sc_pb.LocalMap(map_path=map_path), realtime=real_time)
        for _ in range(players):
            create.player_setup.add(type=sc_pb.Participant)

        # Create the join request.
        join1 = sc_pb.RequestJoinGame(race=races[FLAGS.agent1_race],
                                      options=interface)
        join1.shared_port = ports.pop()
        join1.server_ports.game_port = ports.pop()
        join1.server_ports.base_port = ports.pop()
        join1.client_ports.add(game_port=ports.pop(), base_port=ports.pop())

        join2 = copy.copy(join1)
        join2.race = races[FLAGS.agent2_race]

        # This is where actually game plays
        # Create and Join
        print("create")
        controllers[0].create_game(create)
        print("join")
        parallel.run((c.join_game, join)
                     for c, join in zip(controllers, [join1, join2]))

        controllers[0]._client.send(debug=sc_pb.RequestDebug(
            debug=[debug_pb2.DebugCommand(game_state=1)]))
        if disable_fog[0]:
            controllers[0].disable_fog()
        if disable_fog[1]:
            controllers[1].disable_fog()

        print("run")
        game_info = controllers[0].game_info()
        extractors = features.Features(game_info)
        for game_loop in range(1, 100000):  # steps per episode
            # Step the game
            step_mul = FLAGS.step_mul
            if not real_time:
                parallel.run((c.step, step_mul) for c in controllers)
            else:
                time.sleep(FLAGS.sleep_time)

            # Observe
            obs = parallel.run(c.observe for c in controllers)
            agent_obs = [extractors.transform_obs(o.observation) for o in obs]
            game_info = [None for c in controllers]

            if not any(o.player_result for o in obs):  # Episode over.
                game_info = parallel.run(c.game_info for c in controllers)
            timesteps = tuple(
                environment.TimeStep(step_type=0,
                                     reward=0,
                                     discount=0,
                                     observation=o,
                                     game_info=info)
                for o, info in zip(agent_obs, game_info))

            # Act
            if agent1 is not None:
                actions1 = agent1.step(timesteps[0])
            else:
                actions1 = []
            actions2 = agent2.step(timesteps[1])
            actions = [actions1, actions2]
            funcs_with_args = [(c.acts, a)
                               for c, a in zip(controllers, actions)]
            parallel.run(funcs_with_args)

        # Done with the game.
        print("leave")
        parallel.run(c.leave for c in controllers)
    finally:
        print("quit")
        # Done, shut down. Don't depend on parallel since it might be broken.
        for c in controllers:
            c.quit()
        for p in sc2_procs:
            p.close()
Пример #25
0
 async def debug_food(self):
     """ Should disable food usage (does not seem to work?). Using it a second time disables it again.  """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=3)]))
Пример #26
0
 async def debug_free(self):
     """ Units, structures and upgrades are free of mineral and gas cost. Using it a second time disables it again.  """
     await self._execute(debug=sc_pb.RequestDebug(
         debug=[debug_pb.DebugCommand(game_state=4)]))