Unvalidated gen work
This commit is contained in:
@@ -1023,6 +1023,7 @@ class DungeonBuilder(object):
|
|||||||
self.flex = 0
|
self.flex = 0
|
||||||
self.key_door_proposal = None
|
self.key_door_proposal = None
|
||||||
|
|
||||||
|
self.allowance = None
|
||||||
if name in dungeon_dead_end_allowance.keys():
|
if name in dungeon_dead_end_allowance.keys():
|
||||||
self.allowance = dungeon_dead_end_allowance[name]
|
self.allowance = dungeon_dead_end_allowance[name]
|
||||||
elif 'Stonewall' in name:
|
elif 'Stonewall' in name:
|
||||||
@@ -1124,7 +1125,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge
|
|||||||
logger.info('-Assigning Chest Locations')
|
logger.info('-Assigning Chest Locations')
|
||||||
assign_location_sectors(dungeon_map, free_location_sectors, global_pole)
|
assign_location_sectors(dungeon_map, free_location_sectors, global_pole)
|
||||||
logger.info('-Assigning Crystal Switches and Barriers')
|
logger.info('-Assigning Crystal Switches and Barriers')
|
||||||
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, global_pole)
|
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers, global_pole)
|
||||||
for sector in leftover:
|
for sector in leftover:
|
||||||
if sector.polarity().is_neutral():
|
if sector.polarity().is_neutral():
|
||||||
neutral_sectors[sector] = None
|
neutral_sectors[sector] = None
|
||||||
@@ -1348,7 +1349,7 @@ def minimal_locations(dungeon_name):
|
|||||||
return 5
|
return 5
|
||||||
|
|
||||||
|
|
||||||
def assign_crystal_switch_sectors(dungeon_map, crystal_switches, global_pole, assign_one=False):
|
def assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers, global_pole, assign_one=False):
|
||||||
population = []
|
population = []
|
||||||
some_c_switches_present = False
|
some_c_switches_present = False
|
||||||
for name, builder in dungeon_map.items():
|
for name, builder in dungeon_map.items():
|
||||||
@@ -1358,6 +1359,8 @@ def assign_crystal_switch_sectors(dungeon_map, crystal_switches, global_pole, as
|
|||||||
some_c_switches_present = True
|
some_c_switches_present = True
|
||||||
if len(population) == 0: # nothing needs a switch
|
if len(population) == 0: # nothing needs a switch
|
||||||
if assign_one and not some_c_switches_present: # something should have one
|
if assign_one and not some_c_switches_present: # something should have one
|
||||||
|
if len(crystal_switches) == 0:
|
||||||
|
raise Exception('No crystal switches to assign. Ref %s' % next(iter(dungeon_map.keys())))
|
||||||
valid, builder_choice, switch_choice = False, None, None
|
valid, builder_choice, switch_choice = False, None, None
|
||||||
switch_candidates = list(crystal_switches)
|
switch_candidates = list(crystal_switches)
|
||||||
switch_choice = random.choice(switch_candidates)
|
switch_choice = random.choice(switch_candidates)
|
||||||
@@ -1373,7 +1376,9 @@ def assign_crystal_switch_sectors(dungeon_map, crystal_switches, global_pole, as
|
|||||||
choice = random.choice(builder_candidates)
|
choice = random.choice(builder_candidates)
|
||||||
builder_candidates.remove(choice)
|
builder_candidates.remove(choice)
|
||||||
builder_choice = dungeon_map[choice]
|
builder_choice = dungeon_map[choice]
|
||||||
valid = global_pole.is_valid_choice(dungeon_map, builder_choice, [switch_choice])
|
test_set = [switch_choice]
|
||||||
|
test_set.extend(crystal_barriers)
|
||||||
|
valid = global_pole.is_valid_choice(dungeon_map, builder_choice, test_set)
|
||||||
assign_sector(switch_choice, builder_choice, crystal_switches, global_pole)
|
assign_sector(switch_choice, builder_choice, crystal_switches, global_pole)
|
||||||
return crystal_switches
|
return crystal_switches
|
||||||
sector_list = list(crystal_switches)
|
sector_list = list(crystal_switches)
|
||||||
@@ -1400,45 +1405,48 @@ def assign_crystal_barrier_sectors(dungeon_map, crystal_barriers, global_pole):
|
|||||||
def identify_polarity_issues(dungeon_map):
|
def identify_polarity_issues(dungeon_map):
|
||||||
unconnected_builders = {}
|
unconnected_builders = {}
|
||||||
for name, builder in dungeon_map.items():
|
for name, builder in dungeon_map.items():
|
||||||
if len(builder.sectors) == 1:
|
identify_polarity_issues_internal(name, builder, unconnected_builders)
|
||||||
continue
|
return unconnected_builders
|
||||||
else:
|
|
||||||
def sector_filter(x, y):
|
|
||||||
return x != y
|
def identify_polarity_issues_internal(name, builder, unconnected_builders):
|
||||||
|
if len(builder.sectors) == 1:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
def sector_filter(x, y):
|
||||||
|
return x != y
|
||||||
# else:
|
# else:
|
||||||
# def sector_filter(x, y):
|
# def sector_filter(x, y):
|
||||||
# return x != y and (x.outflow() > 1 or is_entrance_sector(builder, x))
|
# return x != y and (x.outflow() > 1 or is_entrance_sector(builder, x))
|
||||||
connection_flags = {}
|
connection_flags = {}
|
||||||
for slot in PolSlot:
|
for slot in PolSlot:
|
||||||
connection_flags[slot] = {}
|
connection_flags[slot] = {}
|
||||||
for slot2 in PolSlot:
|
for slot2 in PolSlot:
|
||||||
connection_flags[slot][slot2] = False
|
connection_flags[slot][slot2] = False
|
||||||
for sector in builder.sectors:
|
for sector in builder.sectors:
|
||||||
others = [x for x in builder.sectors if sector_filter(x, sector)]
|
others = [x for x in builder.sectors if sector_filter(x, sector)]
|
||||||
other_mag = sum_magnitude(others)
|
other_mag = sum_magnitude(others)
|
||||||
sector_mag = sector.magnitude()
|
sector_mag = sector.magnitude()
|
||||||
check_flags(sector_mag, connection_flags)
|
check_flags(sector_mag, connection_flags)
|
||||||
unconnected_sector = True
|
unconnected_sector = True
|
||||||
|
for i in PolSlot:
|
||||||
|
if sector_mag[i.value] == 0 or other_mag[i.value] > 0 or self_connecting(sector, i, sector_mag):
|
||||||
|
unconnected_sector = False
|
||||||
|
break
|
||||||
|
if unconnected_sector:
|
||||||
for i in PolSlot:
|
for i in PolSlot:
|
||||||
if sector_mag[i.value] == 0 or other_mag[i.value] > 0 or self_connecting(sector, i, sector_mag):
|
if sector_mag[i.value] > 0 and other_mag[i.value] == 0 and not self_connecting(sector, i, sector_mag):
|
||||||
unconnected_sector = False
|
builder.mag_needed[i] = [x for x in PolSlot if other_mag[x.value] > 0]
|
||||||
break
|
|
||||||
if unconnected_sector:
|
|
||||||
for i in PolSlot:
|
|
||||||
if sector_mag[i.value] > 0 and other_mag[i.value] == 0 and not self_connecting(sector, i, sector_mag):
|
|
||||||
builder.mag_needed[i] = [x for x in PolSlot if other_mag[x.value] > 0]
|
|
||||||
if name not in unconnected_builders.keys():
|
|
||||||
unconnected_builders[name] = builder
|
|
||||||
ttl_mag = sum_magnitude(builder.sectors)
|
|
||||||
for slot in PolSlot:
|
|
||||||
for slot2 in PolSlot:
|
|
||||||
if ttl_mag[slot.value] > 0 and ttl_mag[slot2.value] > 0 and not connection_flags[slot][slot2]:
|
|
||||||
builder.mag_needed[slot] = [slot2]
|
|
||||||
builder.mag_needed[slot2] = [slot]
|
|
||||||
if name not in unconnected_builders.keys():
|
if name not in unconnected_builders.keys():
|
||||||
unconnected_builders[name] = builder
|
unconnected_builders[name] = builder
|
||||||
return unconnected_builders
|
ttl_mag = sum_magnitude(builder.sectors)
|
||||||
|
for slot in PolSlot:
|
||||||
|
for slot2 in PolSlot:
|
||||||
|
if ttl_mag[slot.value] > 0 and ttl_mag[slot2.value] > 0 and not connection_flags[slot][slot2]:
|
||||||
|
builder.mag_needed[slot] = [slot2]
|
||||||
|
builder.mag_needed[slot2] = [slot]
|
||||||
|
if name not in unconnected_builders.keys():
|
||||||
|
unconnected_builders[name] = builder
|
||||||
|
|
||||||
def self_connecting(sector, slot, magnitude):
|
def self_connecting(sector, slot, magnitude):
|
||||||
return sector.polarity()[slot.value] == 0 and sum(magnitude) > magnitude[slot.value]
|
return sector.polarity()[slot.value] == 0 and sum(magnitude) > magnitude[slot.value]
|
||||||
@@ -1518,7 +1526,7 @@ def filter_match_deps(candidate, match_deps):
|
|||||||
|
|
||||||
|
|
||||||
def sum_magnitude(sector_list):
|
def sum_magnitude(sector_list):
|
||||||
result = [0, 0, 0]
|
result = [0] * len(PolSlot)
|
||||||
for sector in sector_list:
|
for sector in sector_list:
|
||||||
vector = sector.magnitude()
|
vector = sector.magnitude()
|
||||||
for i in range(len(result)):
|
for i in range(len(result)):
|
||||||
@@ -1651,7 +1659,11 @@ def polarity_step_3(dungeon_map, polarized_sectors, global_pole, logger):
|
|||||||
sub_candidates = odd_candidates.pop(best_charge)
|
sub_candidates = odd_candidates.pop(best_charge)
|
||||||
candidate_list = random.choice(sub_candidates)
|
candidate_list = random.choice(sub_candidates)
|
||||||
sub_candidates.remove(candidate_list)
|
sub_candidates.remove(candidate_list)
|
||||||
valid = global_pole.is_valid_choice(dungeon_map, builder, candidate_list) and valid_branch_only(builder, candidate_list)
|
test_set = find_forced_connections(dungeon_map, candidate_list, polarized_sectors)
|
||||||
|
if ensure_test_set_connectedness(test_set, builder, polarized_sectors, dungeon_map, global_pole):
|
||||||
|
valid = global_pole.is_valid_choice(dungeon_map, builder, test_set) and valid_branch_only(builder, candidate_list)
|
||||||
|
else:
|
||||||
|
valid = False
|
||||||
for candidate in candidate_list:
|
for candidate in candidate_list:
|
||||||
assign_sector(candidate, builder, polarized_sectors, global_pole)
|
assign_sector(candidate, builder, polarized_sectors, global_pole)
|
||||||
|
|
||||||
@@ -1679,6 +1691,63 @@ def polarity_step_3(dungeon_map, polarized_sectors, global_pole, logger):
|
|||||||
assign_sector(sector, builder, polarized_sectors, global_pole)
|
assign_sector(sector, builder, polarized_sectors, global_pole)
|
||||||
|
|
||||||
|
|
||||||
|
def find_forced_connections(dungeon_map, candidate_list, polarized_sectors):
|
||||||
|
test_set = list(candidate_list)
|
||||||
|
other_sectors = [x for x in polarized_sectors if x not in candidate_list]
|
||||||
|
dungeon_hooks = defaultdict(int)
|
||||||
|
for name, builder in dungeon_map.items():
|
||||||
|
d_mag = sum_hook_magnitude(builder.sectors)
|
||||||
|
for val in Hook:
|
||||||
|
dungeon_hooks[val] += d_mag[val.value]
|
||||||
|
queue = deque(candidate_list)
|
||||||
|
while queue:
|
||||||
|
candidate = queue.pop()
|
||||||
|
c_mag = candidate.hook_magnitude()
|
||||||
|
other_candidates = [x for x in candidate_list if x != candidate]
|
||||||
|
for val in Hook:
|
||||||
|
if c_mag[val.value] > 0:
|
||||||
|
opp = opposite_h_type(val)
|
||||||
|
o_val = opp.value
|
||||||
|
if sum_hook_magnitude(other_candidates)[o_val] == 0 and dungeon_hooks[opp] == 0 and not valid_self(c_mag, val, opp):
|
||||||
|
forced_sector = []
|
||||||
|
for sec in other_sectors:
|
||||||
|
if sec.hook_magnitude()[o_val] > 0:
|
||||||
|
forced_sector.append(sec)
|
||||||
|
if len(forced_sector) > 1:
|
||||||
|
break
|
||||||
|
if len(forced_sector) == 1:
|
||||||
|
test_set.append(forced_sector[0])
|
||||||
|
return test_set
|
||||||
|
|
||||||
|
|
||||||
|
def valid_self(c_mag, val, opp):
|
||||||
|
if val == Hook.Stairs:
|
||||||
|
return c_mag[val.value] > 2
|
||||||
|
else:
|
||||||
|
return c_mag[opp.value] > 0 and sum(c_mag) > 2
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_test_set_connectedness(test_set, builder, polarized_sectors, dungeon_map, global_pole):
|
||||||
|
test_copy = list(test_set)
|
||||||
|
while not valid_connected_assignment(builder, test_copy):
|
||||||
|
dummy_builder = DungeonBuilder("Dummy Builder for " + builder.name)
|
||||||
|
dummy_builder.sectors = builder.sectors + test_copy
|
||||||
|
possibles = [x for x in polarized_sectors if x not in test_copy]
|
||||||
|
candidates = find_connected_candidates(possibles)
|
||||||
|
valid, sector = False, None
|
||||||
|
while not valid:
|
||||||
|
if len(candidates) == 0:
|
||||||
|
return False
|
||||||
|
sector = random.choice(candidates)
|
||||||
|
candidates.remove(sector)
|
||||||
|
t2 = test_copy+[sector]
|
||||||
|
valid = global_pole.is_valid_choice(dungeon_map, builder, t2) and valid_branch_only(builder, t2)
|
||||||
|
test_copy.append(sector)
|
||||||
|
dummy_builder.sectors = builder.sectors + test_copy
|
||||||
|
test_set[:] = test_copy
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class GlobalPolarity:
|
class GlobalPolarity:
|
||||||
|
|
||||||
def __init__(self, candidate_sectors):
|
def __init__(self, candidate_sectors):
|
||||||
@@ -1805,6 +1874,7 @@ def find_simple_branching_candidates(builder, sector_pool):
|
|||||||
candidates = defaultdict(list)
|
candidates = defaultdict(list)
|
||||||
charges = defaultdict(list)
|
charges = defaultdict(list)
|
||||||
outflow_needed = builder.dead_ends + builder.forced_loops * 2 > builder.branches + builder.allowance
|
outflow_needed = builder.dead_ends + builder.forced_loops * 2 > builder.branches + builder.allowance
|
||||||
|
total_needed = builder.dead_ends + builder.forced_loops * 2 - builder.branches + builder.allowance
|
||||||
original_lack = builder.total_conn_lack
|
original_lack = builder.total_conn_lack
|
||||||
best_lack = original_lack
|
best_lack = original_lack
|
||||||
for sector in sector_pool:
|
for sector in sector_pool:
|
||||||
@@ -1817,7 +1887,8 @@ def find_simple_branching_candidates(builder, sector_pool):
|
|||||||
if lack < 0:
|
if lack < 0:
|
||||||
ttl_lack += -lack
|
ttl_lack += -lack
|
||||||
forced_loops = calc_forced_loops(builder.sectors + [sector])
|
forced_loops = calc_forced_loops(builder.sectors + [sector])
|
||||||
valid_branches = builder.dead_ends + forced_loops * 2 + sector.dead_ends() <= builder.branches + builder.allowance + sector.branches()
|
net_outflow = builder.dead_ends + forced_loops * 2 + sector.dead_ends() - builder.branches - builder.allowance - sector.branches()
|
||||||
|
valid_branches = net_outflow < total_needed
|
||||||
if valid_branches and (ttl_lack < original_lack or original_lack >= 0):
|
if valid_branches and (ttl_lack < original_lack or original_lack >= 0):
|
||||||
candidates[ttl_lack].append(sector)
|
candidates[ttl_lack].append(sector)
|
||||||
charges[ttl_lack].append((builder.polarity()+sector.polarity()).charge())
|
charges[ttl_lack].append((builder.polarity()+sector.polarity()).charge())
|
||||||
@@ -1948,6 +2019,14 @@ def find_branching_candidates(builder, neutral_choices):
|
|||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
|
def find_connected_candidates(sector_pool):
|
||||||
|
candidates = []
|
||||||
|
for sector in sector_pool:
|
||||||
|
if sector.adj_outflow() >= 2:
|
||||||
|
candidates.append(sector)
|
||||||
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
def neutralize_the_rest(sector_pool):
|
def neutralize_the_rest(sector_pool):
|
||||||
neutral_choices = []
|
neutral_choices = []
|
||||||
main_pool = list(sector_pool)
|
main_pool = list(sector_pool)
|
||||||
@@ -2034,6 +2113,10 @@ def valid_assignment(builder, sector_list):
|
|||||||
return len(resolve_equations(builder, sector_list)) == 0
|
return len(resolve_equations(builder, sector_list)) == 0
|
||||||
|
|
||||||
|
|
||||||
|
def valid_equations(builder, sector_list):
|
||||||
|
return len(resolve_equations(builder, sector_list)) == 0
|
||||||
|
|
||||||
|
|
||||||
def valid_connected_assignment(builder, sector_list):
|
def valid_connected_assignment(builder, sector_list):
|
||||||
full_list = sector_list + builder.sectors
|
full_list = sector_list + builder.sectors
|
||||||
for sector in full_list:
|
for sector in full_list:
|
||||||
@@ -2073,13 +2156,35 @@ def valid_polarized_assignment(builder, sector_list):
|
|||||||
|
|
||||||
|
|
||||||
def assign_the_rest(dungeon_map, neutral_sectors, global_pole):
|
def assign_the_rest(dungeon_map, neutral_sectors, global_pole):
|
||||||
|
comb_w_replace = len(dungeon_map) ** len(neutral_sectors)
|
||||||
|
combinations = None
|
||||||
|
if comb_w_replace <= 1000:
|
||||||
|
combinations = list(itertools.product(dungeon_map.keys(), repeat=len(neutral_sectors)))
|
||||||
|
random.shuffle(combinations)
|
||||||
|
tries = 0
|
||||||
while len(neutral_sectors) > 0:
|
while len(neutral_sectors) > 0:
|
||||||
sector_list = list(neutral_sectors)
|
if tries > 1000 or (combinations and tries >= len(combinations)):
|
||||||
choices = random.choices(list(dungeon_map.keys()), k=len(sector_list))
|
raise Exception('No valid assignment found for "neutral" sectors. Ref: %s' % next(iter(dungeon_map.keys())))
|
||||||
|
# sector_list = list(neutral_sectors)
|
||||||
|
if combinations:
|
||||||
|
choices = combinations[tries]
|
||||||
|
else:
|
||||||
|
choices = random.choices(list(dungeon_map.keys()), k=len(neutral_sectors))
|
||||||
|
neutral_sector_list = list(neutral_sectors)
|
||||||
|
chosen_sectors = defaultdict(list)
|
||||||
for i, choice in enumerate(choices):
|
for i, choice in enumerate(choices):
|
||||||
builder = dungeon_map[choice]
|
chosen_sectors[choice].append(neutral_sector_list[i])
|
||||||
if valid_assignment(builder, [sector_list[i]]):
|
all_valid = True
|
||||||
assign_sector(sector_list[i], builder, neutral_sectors, global_pole)
|
for name, sector_list in chosen_sectors.items():
|
||||||
|
if not valid_assignment(dungeon_map[name], sector_list):
|
||||||
|
all_valid = False
|
||||||
|
break
|
||||||
|
if all_valid:
|
||||||
|
for name, sector_list in chosen_sectors.items():
|
||||||
|
builder = dungeon_map[name]
|
||||||
|
for sector in sector_list:
|
||||||
|
assign_sector(sector, builder, neutral_sectors, global_pole)
|
||||||
|
tries += 1
|
||||||
|
|
||||||
|
|
||||||
def split_dungeon_builder(builder, split_list):
|
def split_dungeon_builder(builder, split_list):
|
||||||
@@ -2103,8 +2208,10 @@ def balance_split(candidate_sectors, dungeon_map, global_pole):
|
|||||||
# categorize sectors
|
# categorize sectors
|
||||||
check_for_forced_dead_ends(dungeon_map, candidate_sectors, global_pole)
|
check_for_forced_dead_ends(dungeon_map, candidate_sectors, global_pole)
|
||||||
check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole)
|
check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole)
|
||||||
|
check_for_forced_crystal(dungeon_map, candidate_sectors, global_pole)
|
||||||
crystal_switches, crystal_barriers, neutral_sectors, polarized_sectors = categorize_sectors(candidate_sectors)
|
crystal_switches, crystal_barriers, neutral_sectors, polarized_sectors = categorize_sectors(candidate_sectors)
|
||||||
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, global_pole, len(crystal_barriers) > 0)
|
leftover = assign_crystal_switch_sectors(dungeon_map, crystal_switches, crystal_barriers,
|
||||||
|
global_pole, len(crystal_barriers) > 0)
|
||||||
for sector in leftover:
|
for sector in leftover:
|
||||||
if sector.polarity().is_neutral():
|
if sector.polarity().is_neutral():
|
||||||
neutral_sectors[sector] = None
|
neutral_sectors[sector] = None
|
||||||
@@ -2156,6 +2263,14 @@ def check_for_forced_dead_ends(dungeon_map, candidate_sectors, global_pole):
|
|||||||
builder.c_locked = True
|
builder.c_locked = True
|
||||||
|
|
||||||
|
|
||||||
|
def check_crystal(dead_end, entrance):
|
||||||
|
if dead_end.blue_barrier and not entrance.c_switch and not dead_end.c_switch:
|
||||||
|
return False
|
||||||
|
if entrance.blue_barrier and not entrance.c_switch and not dead_end.c_switch:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole):
|
def check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole):
|
||||||
done = False
|
done = False
|
||||||
while not done:
|
while not done:
|
||||||
@@ -2166,26 +2281,47 @@ def check_for_forced_assignments(dungeon_map, candidate_sectors, global_pole):
|
|||||||
dungeon_hooks[name] = sum_hook_magnitude(builder.sectors)
|
dungeon_hooks[name] = sum_hook_magnitude(builder.sectors)
|
||||||
for val in Hook:
|
for val in Hook:
|
||||||
if magnitude[val.value] == 1:
|
if magnitude[val.value] == 1:
|
||||||
found_hooks = []
|
forced_sector = None
|
||||||
|
for sec in candidate_sectors:
|
||||||
|
if sec.hook_magnitude()[val.value] > 0:
|
||||||
|
forced_sector = sec
|
||||||
|
break
|
||||||
opp = opposite_h_type(val).value
|
opp = opposite_h_type(val).value
|
||||||
for name, hooks in dungeon_hooks.items():
|
other_sectors = [x for x in candidate_sectors if x != forced_sector]
|
||||||
if hooks[opp] > 0 and not dungeon_map[name].c_locked:
|
if sum_hook_magnitude(other_sectors)[opp] == 0:
|
||||||
found_hooks.append(name)
|
found_hooks = []
|
||||||
if len(found_hooks) == 1:
|
for name, hooks in dungeon_hooks.items():
|
||||||
done = False
|
if hooks[opp] > 0 and not dungeon_map[name].c_locked:
|
||||||
forced_sector = None
|
found_hooks.append(name)
|
||||||
for sec in candidate_sectors:
|
if len(found_hooks) == 1:
|
||||||
if sec.hook_magnitude()[val.value] > 0:
|
done = False
|
||||||
forced_sector = sec
|
assign_sector(forced_sector, dungeon_map[found_hooks[0]], candidate_sectors, global_pole)
|
||||||
break
|
|
||||||
assign_sector(forced_sector, dungeon_map[found_hooks[0]], candidate_sectors, global_pole)
|
|
||||||
|
|
||||||
|
|
||||||
def check_crystal(dead_end, entrance):
|
def check_for_forced_crystal(dungeon_map, candidate_sectors, global_pole):
|
||||||
if dead_end.blue_barrier and not entrance.c_switch and not dead_end.c_switch:
|
for name, builder in dungeon_map.items():
|
||||||
return False
|
if check_for_forced_crystal_single(builder, candidate_sectors):
|
||||||
if entrance.blue_barrier and not entrance.c_switch and not dead_end.c_switch:
|
builder.c_switch_required = True
|
||||||
return False
|
|
||||||
|
|
||||||
|
def check_for_forced_crystal_single(builder, candidate_sectors):
|
||||||
|
builder_doors = defaultdict(dict)
|
||||||
|
for sector in builder.sectors:
|
||||||
|
for door in sector.outstanding_doors:
|
||||||
|
builder_doors[hook_from_door(door)][door] = sector
|
||||||
|
candidate_doors = defaultdict(dict)
|
||||||
|
for sector in candidate_sectors:
|
||||||
|
for door in sector.outstanding_doors:
|
||||||
|
candidate_doors[hook_from_door(door)][door] = sector
|
||||||
|
for hook in builder_doors.keys():
|
||||||
|
for door in builder_doors[hook].keys():
|
||||||
|
opp = opposite_h_type(hook)
|
||||||
|
for d, sector in builder_doors[opp].items():
|
||||||
|
if d != door and (not sector.blue_barrier or sector.c_switch):
|
||||||
|
return False
|
||||||
|
for d, sector in candidate_doors[opp].items():
|
||||||
|
if not sector.blue_barrier or sector.c_switch:
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -2348,7 +2484,7 @@ def find_priority_equation(equations, access_id, current_access):
|
|||||||
if best_local_profit is None or profit > best_local_profit:
|
if best_local_profit is None or profit > best_local_profit:
|
||||||
best_local_profit = profit
|
best_local_profit = profit
|
||||||
all_candidates.append((eq, eq_list, sector))
|
all_candidates.append((eq, eq_list, sector))
|
||||||
elif best_profit is None or profit >= best_profit:
|
elif (best_profit is None or profit >= best_profit) and profit > 0:
|
||||||
if best_profit is None or profit > best_profit:
|
if best_profit is None or profit > best_profit:
|
||||||
wanted_candidates = [eq]
|
wanted_candidates = [eq]
|
||||||
best_profit = profit
|
best_profit = profit
|
||||||
@@ -2401,7 +2537,24 @@ def find_priority_equation(equations, access_id, current_access):
|
|||||||
leads_to_profit = [x for x in good_local_candidates if can_enable_wanted(x[0], wanted_candidates)]
|
leads_to_profit = [x for x in good_local_candidates if can_enable_wanted(x[0], wanted_candidates)]
|
||||||
if len(leads_to_profit) == 0:
|
if len(leads_to_profit) == 0:
|
||||||
leads_to_profit = good_local_candidates
|
leads_to_profit = good_local_candidates
|
||||||
return leads_to_profit[0] # just pick one I guess
|
if len(leads_to_profit) == 1:
|
||||||
|
return leads_to_profit[0]
|
||||||
|
|
||||||
|
cost_point = {x[0]: find_cost_point(x, current_access) for x in leads_to_profit}
|
||||||
|
best_point = max(cost_point.values())
|
||||||
|
cost_point_candidates = [x for x in leads_to_profit if cost_point[x[0]] == best_point]
|
||||||
|
if len(cost_point_candidates) == 0:
|
||||||
|
cost_point_candidates = leads_to_profit
|
||||||
|
return cost_point_candidates[0] # just pick one I guess
|
||||||
|
|
||||||
|
|
||||||
|
def find_cost_point(eq_triplet, access):
|
||||||
|
cost_point = 0
|
||||||
|
for key, costs in eq_triplet[0].cost.items():
|
||||||
|
cost_count = len(costs)
|
||||||
|
if cost_count > 0:
|
||||||
|
cost_point += access[key] - cost_count
|
||||||
|
return cost_point
|
||||||
|
|
||||||
|
|
||||||
def find_greedy_equation(equations, access_id, current_access):
|
def find_greedy_equation(equations, access_id, current_access):
|
||||||
|
|||||||
Reference in New Issue
Block a user