Generation Fix

* Added step to adjust parity before complete neutralization
This commit is contained in:
aerinon
2020-02-28 15:00:02 -07:00
parent 06562ed3ea
commit 6daa436f08
2 changed files with 37 additions and 1 deletions

View File

@@ -1540,9 +1540,30 @@ def assign_polarized_sectors(dungeon_map, polarized_sectors, global_pole, logger
def polarity_step_3(dungeon_map, polarized_sectors, global_pole, logger): def polarity_step_3(dungeon_map, polarized_sectors, global_pole, logger):
# step 3a: fix odd builders
odd_builders = [x for x in dungeon_map.values() if sum_polarity(x.sectors).charge() % 2 != 0]
random.shuffle(odd_builders)
for builder in odd_builders:
while sum_polarity(builder.sectors).charge() % 2 != 0:
odd_candidates = find_odd_sectors_ranked_by_charge(builder, polarized_sectors)
sub_candidates, valid, best_charge, candidate = [], False, min(list(odd_candidates.keys())), None
while not valid:
if len(sub_candidates) == 0:
if len(odd_candidates) == 0:
raise NeutralizingException('Unable to fix dungeon parity: %s' % builder.name)
while best_charge not in odd_candidates.keys():
best_charge += 2
sub_candidates = odd_candidates.pop(best_charge)
candidate = random.choice(sub_candidates)
sub_candidates.remove(candidate)
valid = global_pole.is_valid_choice(dungeon_map, builder, [candidate])
assign_sector(candidate, builder, polarized_sectors, global_pole)
# step 3b: neutralize all builders
builder_order = list(dungeon_map.values()) builder_order = list(dungeon_map.values())
random.shuffle(builder_order) random.shuffle(builder_order)
for builder in builder_order: for builder in builder_order:
# global_pole.check_odd_polarities(polarized_sectors, dungeon_map)
logger.info('--Balancing %s', builder.name) logger.info('--Balancing %s', builder.name)
while not builder.polarity().is_neutral(): while not builder.polarity().is_neutral():
rejects = [] rejects = []
@@ -1659,6 +1680,12 @@ class GlobalPolarity:
proposal.consume(sector) proposal.consume(sector)
return proposal._check_parity(non_neutral_polarities) and proposal._is_valid_polarities(non_neutral_polarities) return proposal._check_parity(non_neutral_polarities) and proposal._is_valid_polarities(non_neutral_polarities)
# def check_odd_polarities(self, candidate_sectors, dungeon_map):
# odd_candidates = [x for x in candidate_sectors if x.polarity().charge() % 2 != 0]
# odd_map = {n: x for (n, x) in dungeon_map.items() if sum_polarity(x.sectors).charge() % 2 != 0}
# gp = GlobalPolarity(odd_candidates)
# return gp.is_valid(odd_map)
def find_connection_candidates(mag_needed, sector_pool): def find_connection_candidates(mag_needed, sector_pool):
candidates = [] candidates = []
@@ -1715,6 +1742,15 @@ def calc_sector_balance(sector): # todo: move to base class?
sector.conn_balance[hanger_from_door(door)] += 1 sector.conn_balance[hanger_from_door(door)] += 1
def find_odd_sectors_ranked_by_charge(builder, polarized_sectors):
polarity = builder.polarity()
candidates = defaultdict(list)
for candidate in [x for x in polarized_sectors if x.polarity().charge() % 2 != 0]:
p_charge = (polarity + candidate.polarity()).charge()
candidates[p_charge].append(candidate)
return candidates
# todo: refactor to return prioritized lists # todo: refactor to return prioritized lists
def find_neutralizing_candidates(builder, sector_pool, rejects): def find_neutralizing_candidates(builder, sector_pool, rejects):
polarity = builder.polarity() polarity = builder.polarity()

View File

@@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
from ItemList import generate_itempool, difficulties, fill_prizes from ItemList import generate_itempool, difficulties, fill_prizes
from Utils import output_path, parse_player_names from Utils import output_path, parse_player_names
__version__ = '0.0.e-dev' __version__ = '0.0.f-dev'
def main(args, seed=None): def main(args, seed=None):