Skip to content

Commit

Permalink
feat: add new safe opening
Browse files Browse the repository at this point in the history
  • Loading branch information
raspersc2 committed Jul 10, 2023
1 parent 45678a2 commit 33b4864
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 16 deletions.
62 changes: 54 additions & 8 deletions bot/production_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from ares import AresBot
from ares.consts import UnitRole
from ares.cython_extensions.general_utils import cy_unit_pending
from ares.cython_extensions.geometry import cy_towards
from ares.cython_extensions.geometry import cy_towards, cy_distance_to
from ares.cython_extensions.units_utils import cy_closest_to
from sc2.ids.ability_id import AbilityId
from sc2.ids.unit_typeid import UnitTypeId as UnitID
Expand All @@ -16,6 +16,7 @@
from bot.terrain_manager import TerrainManager
from bot.unit_manager import UnitManager

MAX_SPINES: int = 4
REQUIRED_UPGRADES: List[AbilityId] = [
AbilityId.RESEARCH_ZERGMISSILEWEAPONSLEVEL1,
AbilityId.RESEARCH_ZERGMISSILEWEAPONSLEVEL2,
Expand All @@ -38,6 +39,7 @@ def __init__(
self.unit_manager: UnitManager = unit_manager

self._added_third_hatch: bool = False
self._chosen_opening: str = self.bot.build_order_runner.chosen_opening.upper()

@property
def need_overlord(self) -> bool:
Expand Down Expand Up @@ -79,10 +81,7 @@ async def update(self, iteration: int) -> None:
return

# add 3rd hatch to track soon as standard BO is done
if (
not self._added_third_hatch
and "STANDARD" in self.bot.build_order_runner.chosen_opening.upper()
):
if not self._added_third_hatch and "STANDARD" in self._chosen_opening:
loc: Point2 = self.bot.mediator.get_defensive_third
if worker := self.bot.mediator.select_worker(target_position=loc):
self.bot.mediator.build_with_specific_worker(
Expand All @@ -91,6 +90,9 @@ async def update(self, iteration: int) -> None:
self.bot.mediator.assign_role(tag=worker.tag, role=UnitRole.BUILDING)
self._added_third_hatch = True

if "SAFE" in self._chosen_opening and self.bot.time < 360.0:
await self._manage_spines()

idle_townhalls: Units = self.bot.townhalls.filter(
lambda s: s.is_ready and s.is_idle
)
Expand Down Expand Up @@ -136,7 +138,7 @@ async def _manage_larva_production(self, idle_townhalls: Units) -> None:
self.bot.larva.first.train(UnitID.OVERLORD)
# build workers
if self.bot.supply_left >= 1 and self.bot.minerals < 800:
max_workers: int = 35 if self.bot.townhalls.amount <= 3 else 65
max_workers: int = 38 if self.bot.townhalls.amount <= 2 else 65
if (
self.num_workers <= max_workers
and self.bot.can_afford(UnitID.DRONE)
Expand Down Expand Up @@ -187,8 +189,12 @@ async def _morph_core_structures(self) -> None:
)

# expand
can_expand: bool = (
False if self._chosen_opening == "SAFE" and self.bot.time < 300.0 else True
)
if (
self.bot.can_afford(UnitID.HATCHERY)
and can_expand
and UnitID.HATCHERY not in self.bot.mediator.get_building_counter
):
if location := await self.bot.get_next_expansion():
Expand All @@ -198,8 +204,9 @@ async def _morph_core_structures(self) -> None:

# evo chambers
max_evos: int = 2
worker_limit: int = 32 if self._chosen_opening == "SAFE" else 56
if (
self.num_workers > 56
self.num_workers > worker_limit
and self.bot.structures(UnitID.EVOLUTIONCHAMBER).amount < max_evos
and self.bot.can_afford(UnitID.EVOLUTIONCHAMBER)
and not self.bot.already_pending(UnitID.EVOLUTIONCHAMBER)
Expand All @@ -215,7 +222,8 @@ async def _morph_core_structures(self) -> None:
)

# extractors
max_extractors: int = 2 if self.num_workers >= 38 else 0
min_worker = 30 if self._chosen_opening == "SAFE" else 38
max_extractors: int = 2 if self.num_workers >= min_worker else 0
if (
self.bot.gas_buildings.amount < max_extractors
and self.bot.can_afford(UnitID.EXTRACTOR)
Expand Down Expand Up @@ -313,3 +321,41 @@ async def _place_nydus_worm(self) -> None:
)
if placement:
networks.first(AbilityId.BUILD_NYDUSWORM, placement)

async def _manage_spines(self):
if self.bot.time < 135.0:
return

own_structures_dict: dict[
UnitID, Units
] = self.bot.mediator.get_own_structures_dict
if UnitID.SPAWNINGPOOL not in own_structures_dict:
return

if own_structures_dict[UnitID.SPAWNINGPOOL].ready:
own_nat: Point2 = self.bot.mediator.get_own_nat
hatch_at_nat: list[Unit] = [
h
for h in self.bot.townhalls
if cy_distance_to(h.position, own_nat) < 5.0 and h.is_ready
]
if len(hatch_at_nat) == 0:
return

num_current_spines: int = self.bot.mediator.get_building_counter[
UnitID.SPINECRAWLER
]
# only have one drone on journey to position at a time
if num_current_spines > 0:
return

if UnitID.SPINECRAWLER in own_structures_dict:
num_current_spines += len(own_structures_dict[UnitID.SPINECRAWLER])

if num_current_spines >= MAX_SPINES:
return

await self._build_structure(
UnitID.SPINECRAWLER,
own_nat.towards(self.bot.game_info.map_center, 5.9),
)
54 changes: 48 additions & 6 deletions bot/unit_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,53 @@ def __init__(
self.offensive: bool = False
self.ol_spots_index: int = 0

@property
def defensive_queen_policy(self) -> Dict:
return {
"creep_queens": {
"active": True,
"distance_between_queen_tumors": 3,
"first_tumor_position": self.terrain_manager.natural_location.towards(
self.bot.game_info.map_center, 9
),
"priority": True,
"prioritize_creep": lambda: True,
"max": 1,
"defend_against_ground": True,
"rally_point": self.terrain_manager.natural_location,
"priority_defence_list": {
UnitID.ZERGLING,
UnitID.MARINE,
UnitID.ZEALOT,
},
},
"creep_dropperlord_queens": {
"active": True,
"priority": True,
"max": 1,
"pass_own_threats": True,
"target_expansions": [
el[0] for el in self.terrain_manager.expansions[-6:-3]
],
},
"defence_queens": {
"attack_condition": lambda: self.offensive,
"rally_point": self.terrain_manager.natural_location,
},
"inject_queens": {"active": False},
"nydus_queens": {
"active": True,
"max": 12,
"steal_from": {QueenRoles.Defence},
},
}

@property
def early_game_queen_policy(self) -> Dict:
return {
"creep_queens": {
"active": True,
"distance_between_queen_tumors": 3,
"distance_between_existing_tumors": 5,
"first_tumor_position": self.terrain_manager.natural_location.towards(
self.bot.game_info.map_center, 9
),
Expand Down Expand Up @@ -105,7 +145,6 @@ def mid_game_queen_policy(self) -> Dict:
"priority": True,
"defend_against_ground": True,
"distance_between_queen_tumors": 3,
"distance_between_existing_tumors": 5,
"priority_defence_list": {
UnitID.BATTLECRUISER,
UnitID.LIBERATOR,
Expand Down Expand Up @@ -134,11 +173,17 @@ def mid_game_queen_policy(self) -> Dict:
}

def _on_first_iteration(self) -> None:
policy = (
self.defensive_queen_policy
if self.bot.build_order_runner.chosen_opening == "Safe"
else self.early_game_queen_policy
)

# initiating queens-sc2` here
self.queens = Queens(
self.bot,
debug=False,
queen_policy=self.early_game_queen_policy,
queen_policy=policy,
map_data=self.map_data,
)
self.bot.units(UnitID.OVERLORD).first.move(self.bot.mediator.get_own_nat)
Expand Down Expand Up @@ -534,9 +579,6 @@ async def _morph_overseer(self, overlords: Units) -> Optional[int]:
return overlord.tag

def _manage_queen_policy(self, iteration: int) -> None:
if iteration == 0:
self.queens.set_new_policy(self.early_game_queen_policy, reset_roles=True)

if not self.switched_queen_policy and self.bot.time > 420:
self.switched_queen_policy = True
self.queens.set_new_policy(self.mid_game_queen_policy, reset_roles=True)
Expand Down
2 changes: 1 addition & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ MyBotRace: Zerg
UseData: False
Debug: False
GameStep: 2
DebugGameStep: 2
DebugGameStep: 4

DebugOptions:
# one of: Air, AirVsGround, Ground, GroundAvoidance, AirAvoidance
Expand Down
22 changes: 21 additions & 1 deletion zerg_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,53 @@ BuildChoices:
test_123:
BotName: Test
Cycle:
- Standard
- Safe

Protoss:
BotName: ProtossRace
Cycle:
- Standard
- Greed
- Safe

Random:
BotName: RandomRace
Cycle:
- Standard
- Greed
- Safe

Terran:
BotName: TerranRace
Cycle:
- Standard
- Greed
- Safe

Zerg:
BotName: ZergRace
Cycle:
- Standard
- Greed
- Safe

Builds:
Safe:
# Build constant workers till x supply
ConstantWorkerProductionTill: 0
OpeningBuildOrder:
- 12 drone
- 13 overlord
- 13 drone
- 14 drone
- 15 drone
- 16 expand
- 15 drone
- 16 drone
- 17 drone
- 18 spawningpool
- 17 drone

Standard:
# Build constant workers till x supply
ConstantWorkerProductionTill: 0
Expand Down

0 comments on commit 33b4864

Please sign in to comment.