Skip to content

Instantly share code, notes, and snippets.

@tweakimp
Last active October 18, 2018 06:48
Show Gist options
  • Save tweakimp/03197f664078d52b89fc865c3f777b07 to your computer and use it in GitHub Desktop.
Save tweakimp/03197f664078d52b89fc865c3f777b07 to your computer and use it in GitHub Desktop.
New distribute workers?
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