Last active
October 18, 2018 06:48
-
-
Save tweakimp/03197f664078d52b89fc865c3f777b07 to your computer and use it in GitHub Desktop.
New distribute workers?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async def scv_distribute_workers(self): | |
workers_to_distribute = [scv for scv in self.scvs.idle] | |
workers_must_distribute = [scv for scv in self.scvs.idle] | |
deficit_bases = [] | |
deficit_refineries = [] | |
mining_bases = self.get_mining_bases() | |
refinery_tags = { | |
ref.tag | |
for ref in self.units(REFINERY).ready.filter( | |
lambda ref: any([ref.position.distance_to_point2(base.position) <= 10 for base in mining_bases]) | |
) | |
} | |
mineral_tags = { | |
mf.tag | |
for mf in self.state.mineral_field.filter( | |
lambda field: any([field.position.distance_to_point2(base.position) <= 10 for base in mining_bases]) | |
) | |
} | |
far_refinery_tags = { | |
ref.tag | |
for ref in self.units(REFINERY).ready.filter( | |
lambda ref: all([ref.position.distance_to_point2(base.position) > 10 for base in mining_bases]) | |
) | |
} | |
far_mineral_tags = { | |
mf.tag | |
for mf in self.state.mineral_field.filter( | |
lambda field: all([field.position.distance_to_point2(base.position) > 10 for base in mining_bases]) | |
) | |
} | |
mineral_fields = self.state.mineral_field.filter( | |
lambda field: any([field.position.distance_to_point2(base.position) <= 10 for base in mining_bases]) | |
) | |
for scv in self.scvs: | |
if scv.order_target in far_refinery_tags | far_mineral_tags: | |
# print(scv.order_target) | |
# print(refinery_tags | mineral_tags) | |
workers_to_distribute.append(scv) | |
# check places to collect from whether there are not optimal worker counts | |
for mining_place in mining_bases | self.units(REFINERY).ready.filter( | |
lambda ref: any([ref.position.distance_to_point2(base.position) <= 10 for base in mining_bases]) | |
): | |
difference = mining_place.surplus_harvesters | |
# if too many workers, put extra workers in workers_to_distribute | |
if difference > 0: | |
for _ in range(difference): | |
if mining_place.name == "Refinery": | |
moving_scv = self.scvs.filter( | |
lambda x: x.order_target in refinery_tags and x not in workers_to_distribute | |
) | |
else: | |
moving_scv = self.scvs.filter( | |
lambda x: x.order_target in mineral_tags and x not in workers_to_distribute | |
) | |
if moving_scv: | |
workers_to_distribute.append(moving_scv.closest_to(mining_place)) | |
# too few workers, put place to mine in deficit list | |
elif difference < 0: | |
if mining_place.name == "Refinery": | |
deficit_refineries.append([mining_place, difference]) | |
else: | |
deficit_bases.append([mining_place, difference]) | |
if len(deficit_bases) + len(deficit_refineries) == 0: | |
# no deficits so only move idle workers, not surplus and idle | |
for scv in self.scvs.idle: | |
mf = mineral_fields.closest_to(scv) | |
self.actions.append(scv.gather(mf)) | |
return | |
# list of current targets to check later | |
worker_order_targets = {worker.order_target for worker in self.scvs.collecting} | |
# order mineral fields for scvs to prefer the ones with no worker and most minerals | |
if deficit_bases and workers_to_distribute: | |
mineral_fields_deficit = [mf for mf in mineral_fields.closer_than(8, deficit_bases[0][0])] | |
# order target mineral fields, first by if someone is there already, second by mineral content | |
mineral_fields_deficit = sorted( | |
mineral_fields_deficit, | |
key=lambda mineral_field: ( | |
mineral_field.tag not in worker_order_targets, | |
mineral_field.mineral_contents, | |
), | |
) | |
mineral_fields_all = [mf for mf in [mineral_fields.closer_than(8, base) for base in mining_bases][0]] | |
if len(workers_to_distribute) > len(deficit_bases) + len(deficit_refineries): | |
# order target mineral fields, first by if someone is there already, second by mineral content) | |
mineral_fields_all = sorted( | |
mineral_fields_all, | |
key=lambda mineral_field: ( | |
mineral_field.tag not in worker_order_targets, | |
-mineral_field.mineral_contents, | |
), | |
) | |
for worker in workers_to_distribute: | |
# distribute to refineries | |
if ( | |
self.units(REFINERY).ready.filter( | |
lambda ref: any([ref.position.distance_to_point2(base.position) <= 10 for base in mining_bases]) | |
) | |
and deficit_refineries | |
): | |
self.actions.append(worker.gather(deficit_refineries[0][0])) | |
deficit_refineries[0][1] += 1 | |
if deficit_refineries[0][1] == 0: | |
del deficit_refineries[0] | |
# distribute to mineral fields | |
elif mining_bases and deficit_bases: | |
scv_target = mineral_fields_deficit[0] | |
if len(mineral_fields_deficit) >= 2: | |
del mineral_fields_deficit[0] | |
self.actions.append(worker.gather(scv_target)) | |
deficit_bases[0][1] += 1 | |
if deficit_bases[0][1] == 0: | |
del deficit_bases[0] | |
else: | |
workers_must_distribute.append(worker) | |
# extra workers on other mineral fields | |
for worker in workers_must_distribute: | |
if mineral_fields_all: | |
scv_target = mineral_fields_all[0] | |
if len(mineral_fields_all) >= 2: | |
del mineral_fields_all[0] | |
self.actions.append(worker.gather(scv_target)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment