untangle randomize_game

this heart of the randomizer, and it is the most complex function of the
bunch. it seems to function ok now, and the logic mostly makes sense,
but i wouldn't be surprised if there were one or two lingering errors.
master
magical 2024-02-03 01:58:33 -08:00
parent e7a5af202a
commit 20e24a40e3
1 changed files with 643 additions and 652 deletions

View File

@ -1869,40 +1869,26 @@ def randomize_game(graph):
'Mega Core-X': 0, 'Mega Core-X': 0,
'Box-2': 500} 'Box-2': 500}
print('Generating, please wait...') print('Generating, please wait...')
while True: while gameBeatable == False:
if not gameBeatable == False: if init == False:
if not init == False: if SeedSettings['SectorShuffle'] == True:
if not SeedSettings['SectorShuffle'] == True: areaDoors = {1:['S1-6B', 'S1-68'],
areaDoors = {1:[ 2:['S2-7F', 'S2-82'],
'S1-6B', 'S1-68'], 3:['S3-59', 'S3-56'],
2:[ 4:['S4-6C', 'S4-6A'],
'S2-7F', 'S2-82'], 5:['S5-02', 'S5-53'],
3:[ 6:['S6-51', 'S6-54']}
'S3-59', 'S3-56'],
4:[
'S4-6C', 'S4-6A'],
5:[
'S5-02', 'S5-53'],
6:[
'S6-51', 'S6-54']}
areaLayout = random.sample(range(1, 7), 6) areaLayout = random.sample(range(1, 7), 6)
if SeedSettings['MajorMinor'] == True: if SeedSettings['MajorMinor'] == True:
if areaLayout[2] != 1: while areaLayout[2] != 1 and areaLayout[2] != 2 and areaLayout[3] != 1 and areaLayout[3] != 2:
if areaLayout[2] != 2:
if areaLayout[3] != 1:
if areaLayout[3] != 2:
attemptedLayouts.append(areaLayout) attemptedLayouts.append(areaLayout)
while True:
if areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
while True:
pass
while areaLayout in attemptedLayouts: while areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6) areaLayout = random.sample(range(1, 7), 6)
else:
while areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
attemptedLayouts.append(areaLayout) attemptedLayouts.append(areaLayout)
for area in areaLayout: for area in areaLayout:
elevator = areaLayout.index(area) elevator = areaLayout.index(area)
if elevator == 0: if elevator == 0:
@ -2160,6 +2146,7 @@ def randomize_game(graph):
graph.UpdateDoorConnection(source, destination) graph.UpdateDoorConnection(source, destination)
graph.ConnectAllNodes() graph.ConnectAllNodes()
PlacedETanks = PlacedMissiles = PlacedPowerBombs = 0 PlacedETanks = PlacedMissiles = PlacedPowerBombs = 0
if SeedSettings['DamageRuns']: if SeedSettings['DamageRuns']:
Energy = PlacedETanks * 100 + 99 Energy = PlacedETanks * 100 + 99
@ -2235,7 +2222,7 @@ def randomize_game(graph):
break break
if path == None: if path == None:
print('Path: No accessible locations found with this start, try changing your game settings.') sys.exit('No accessible locations found with this start, try changing your game settings.')
else: else:
for item in MajorItems: for item in MajorItems:
enable_item(graph, item) enable_item(graph, item)
@ -2260,8 +2247,10 @@ def randomize_game(graph):
disable_item(graph, 'RedDoors') disable_item(graph, 'RedDoors')
weightInit = True weightInit = True
if len(availableItems) < 1: if len(availableItems) < 1:
print('Items: No accessible locations found with this start, try changing your game settings.') sys.exit('No accessible locations found with this start, try changing your game settings.')
find_available_areas(graph) find_available_areas(graph)
for location in MajorLocations: for location in MajorLocations:
path = graph.get_path(StartLocation, location) path = graph.get_path(StartLocation, location)
@ -2289,8 +2278,7 @@ def randomize_game(graph):
path = None path = None
if SeedSettings['DamageRuns']: if SeedSettings['DamageRuns']:
Energy = Energy / 2 Energy = Energy / 2
while True: while path == None:
if not path == None:
location = random.choice(AccessibleLocations) location = random.choice(AccessibleLocations)
path = graph.get_path(location, StartLocation) path = graph.get_path(location, StartLocation)
if path != None: if path != None:
@ -2320,24 +2308,29 @@ def randomize_game(graph):
if SeedSettings['PowerBombsWithoutBombs'] == False: if SeedSettings['PowerBombsWithoutBombs'] == False:
MajorList.append('MainPowerBombs') MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs')) MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
init = True init = True
if SeedSettings['DamageRuns']: if SeedSettings['DamageRuns']:
Energy = PlacedETanks * 100 + 99 Energy = PlacedETanks * 100 + 99
find_available_areas(graph) find_available_areas(graph)
path = graph.get_path(StartLocation, 'End-of-Game') path = graph.get_path(StartLocation, 'End-of-Game')
if path != None: if path != None:
path = graph.get_path('End-of-Game', 'S0-00') path = graph.get_path('End-of-Game', 'S0-00')
if path != None: if path != None:
gameBeatable = True gameBeatable = True
if not gameBeatable == False:
if gameBeatable == False:
newLocations.clear() newLocations.clear()
locationWeights.clear() locationWeights.clear()
for location in MajorLocations: for location in MajorLocations:
path = None path = None
if location not in UsedLocations: if location not in UsedLocations:
if location not in AccessibleLocations: if location not in AccessibleLocations:
if not location == 'Data S0' or location == 'Item S0-05-16': if location == 'Data S0' or location == 'Item S0-05-16':
path = graph.get_path(location, StartLocation, depth=250) path = graph.get_path(location, StartLocation, depth=250)
else:
for area in range(0, 7): for area in range(0, 7):
if location in AreaItemLocations[area]: if location in AreaItemLocations[area]:
if AreaOpen[area]: if AreaOpen[area]:
@ -2347,7 +2340,6 @@ def randomize_game(graph):
AccessibleLocations.append(location) AccessibleLocations.append(location)
MajorLocations.remove(location) MajorLocations.remove(location)
newLocations.append(location) newLocations.append(location)
for area in range(0, 7): for area in range(0, 7):
if location in AreaItemLocations[area]: if location in AreaItemLocations[area]:
if location not in locationsPerArea[area]: if location not in locationsPerArea[area]:
@ -2365,24 +2357,23 @@ def randomize_game(graph):
if location in AreaItemLocations[area]: if location in AreaItemLocations[area]:
if location in newLocations: if location in newLocations:
locationWeights.append(areaWeights[area] * 1.8) locationWeights.append(areaWeights[area] * 1.8)
else: elif location in BossLocations and SeedSettings['MajorMinor'] == False:
if location in BossLocations:
if SeedSettings['MajorMinor'] == False:
locationWeights.append(areaWeights[area] * 1.5) locationWeights.append(areaWeights[area] * 1.5)
else:
locationWeights.append(areaWeights[area]) locationWeights.append(areaWeights[area])
if not len(MajorList) > 0: if len(MajorList) > 0:
itemLocation = None itemLocation = None
path = None path = None
item = random.choices(MajorList, weights=MajorWeights, k=1)[0] item = random.choices(MajorList, weights=MajorWeights, k=1)[0]
currentItemWeight = MajorWeights.pop(MajorList.index(item)) currentItemWeight = MajorWeights.pop(MajorList.index(item))
MajorList.remove(item) MajorList.remove(item)
enable_item(graph, item) enable_item(graph, item)
if SeedSettings['DamageRuns']: if SeedSettings['DamageRuns']:
Energy = Energy / 2 Energy = Energy / 2
while True:
if not path == None: while path == None and len(AccessibleLocations) > 0:
if not len(AccessibleLocations) > 0:
itemLocation = random.choices(AccessibleLocations, weights=locationWeights, k=1)[0] itemLocation = random.choices(AccessibleLocations, weights=locationWeights, k=1)[0]
oldLocationWeight = locationWeights.pop(AccessibleLocations.index(itemLocation)) oldLocationWeight = locationWeights.pop(AccessibleLocations.index(itemLocation))
AccessibleLocations.remove(itemLocation) AccessibleLocations.remove(itemLocation)
@ -2394,12 +2385,10 @@ def randomize_game(graph):
if AreaOpen[area]: if AreaOpen[area]:
path = graph.get_path(itemLocation, AreaOpen[area], True) path = graph.get_path(itemLocation, AreaOpen[area], True)
break break
if itemLocation in BossLocations:
if not itemLocation in BossLocations: if path != None:
if not path != None:
disable_item(graph, item) disable_item(graph, item)
if ChargeBeam == False: if ChargeBeam == False and SeedSettings['Difficulty'] > 0:
if SeedSettings['Difficulty'] > 0:
healthCheck = BossHealths.get(itemLocation) healthCheck = BossHealths.get(itemLocation)
if SeedSettings['Difficulty'] > 4: if SeedSettings['Difficulty'] > 4:
healthCheck = healthCheck * 1.02 healthCheck = healthCheck * 1.02
@ -2430,12 +2419,12 @@ def randomize_game(graph):
break break
if missilePath != None: if missilePath != None:
PossibleMissileTanks.append(missileLocation) PossibleMissileTanks.append(missileLocation)
else: else:
for missileLocation in AccessibleLocations: for missileLocation in AccessibleLocations:
missilePath = None missilePath = None
if not missileLocation == 'Data S0' or missileLocation == 'Item S0-05-16': if missileLocation == 'Data S0' or missileLocation == 'Item S0-05-16':
missilePath = graph.get_path(missileLocation, StartLocation, depth=250) missilePath = graph.get_path(missileLocation, StartLocation, depth=250)
else:
for area in range(0, 7): for area in range(0, 7):
if missileLocation in AreaItemLocations[area]: if missileLocation in AreaItemLocations[area]:
if AreaOpen[area]: if AreaOpen[area]:
@ -2463,6 +2452,7 @@ def randomize_game(graph):
else: else:
path = None path = None
enable_item(graph, item) enable_item(graph, item)
if path == None: if path == None:
oldLocations.append(itemLocation) oldLocations.append(itemLocation)
oldWeights.append(oldLocationWeight) oldWeights.append(oldLocationWeight)
@ -2499,7 +2489,7 @@ def randomize_game(graph):
if itemLocation not in AreaItemLocations[area]: if itemLocation not in AreaItemLocations[area]:
weightValue[area] += 1 weightValue[area] += 1
elif item == 'MainMissiles': if item == 'MainMissiles':
if SeedSettings['MissilesWithoutMainData'] == False: if SeedSettings['MissilesWithoutMainData'] == False:
MajorList.append('IceMissileItem') MajorList.append('IceMissileItem')
MajorWeights.append(WeightedMajors.get('IceMissileItem')) MajorWeights.append(WeightedMajors.get('IceMissileItem'))
@ -2517,8 +2507,9 @@ def randomize_game(graph):
if SeedSettings['PowerBombsWithoutBombs'] == False: if SeedSettings['PowerBombsWithoutBombs'] == False:
MajorList.append('MainPowerBombs') MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs')) MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
if SeedSettings['MajorMinor'] == False: if SeedSettings['MajorMinor'] == False:
if not len(AccessibleLocations) > 3: if len(AccessibleLocations) > 3:
if PlacedETanks < MaxETanks: if PlacedETanks < MaxETanks:
itemLocation = random.choice(AccessibleLocations) itemLocation = random.choice(AccessibleLocations)
locationWeights.pop(AccessibleLocations.index(itemLocation)) locationWeights.pop(AccessibleLocations.index(itemLocation))
@ -2526,6 +2517,7 @@ def randomize_game(graph):
UsedLocations.append(itemLocation) UsedLocations.append(itemLocation)
PlacedItems.append('Energy Tank') PlacedItems.append('Energy Tank')
PlacedETanks += 1 PlacedETanks += 1
else:
for item in MajorItems: for item in MajorItems:
disable_item(graph, item) disable_item(graph, item)
@ -2575,17 +2567,16 @@ def randomize_game(graph):
PlacedETanks += 1 PlacedETanks += 1
if PlacedETanks >= MaxETanks: if PlacedETanks >= MaxETanks:
MinorItems.remove('Energy Tank') MinorItems.remove('Energy Tank')
else: elif item == 'Missile Tank':
if item == 'Missile Tank':
PlacedMissiles += 1 PlacedMissiles += 1
if not PlacedMissiles >= MaxMissiles: if PlacedMissiles >= MaxMissiles:
MinorItems.remove('Missile Tank') MinorItems.remove('Missile Tank')
if item == 'Power Bomb Tank': elif item == 'Power Bomb Tank':
PlacedPowerBombs += 1 PlacedPowerBombs += 1
if PlacedPowerBombs >= MaxPowerBombs: if PlacedPowerBombs >= MaxPowerBombs:
MinorItems.remove('Power Bomb Tank') MinorItems.remove('Power Bomb Tank')
patch_game()
patch_game()
def patch_game(): def patch_game():
global FileName, BaseName global FileName, BaseName