Advertisement
imbued

SRM Chain Solver 15

Dec 24th, 2019
353
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 312.43 KB | None | 0 0
  1. from copy import copy
  2. import itertools
  3. import numpy as np
  4.  
  5. """
  6.  
  7. - This script does NOT handle spawners (except for rupee clusters)
  8. - This script does NOT handle scarecrow memory leak
  9.  
  10. - This script does not account for ISoT memory leak for solution options
  11.  
  12.  
  13. FOR DEKU PALACE, THIS DOES NOT ACCOUNT FOR POTENTIALLY NEEDING TO BREAK A POT FOR THE SUPERSLIDE
  14.  
  15. THIS SCRIPT DOES NOT ACCOUNT FOR GOLD SKULLTULA TOKENS
  16.  
  17.  
  18. """
  19.  
  20.  
  21.  
  22. """
  23.  
  24. Note: Node size is 0x10 = 16 on English and 0x30 = 48 on JP
  25.  
  26. """
  27.  
  28. version = 'English'
  29.  
  30. if version == 'English':
  31.     node_size = 0x10
  32. elif version == 'JP':
  33.     nodesize = 0x30
  34. else:
  35.     print('Error: Invalid Version (choose "English" or "JP" )')
  36.  
  37.  
  38.  
  39. class Actor:
  40.    
  41.     """
  42.    
  43.    name: name of the actor, some string
  44.    
  45.    Id: Actor id, string of 4 integers
  46.    
  47.    size: the size of an actor instance for this actor (number of bytes, in decimal)
  48.    
  49.    category: the actor category (category 5 is treated differently than others)
  50.              For now, giving everything not category 5 a category of 0
  51.  
  52.    overlay_type: determines where the AF loads in the heap
  53.    
  54.    unloadable: a boolean for whether or not it is possible to deallocate this actor without changing rooms
  55.    
  56.    address: the memory address of the actor in decimal (can convert to a hex string for output)
  57.             Note: The earliest address we handle is 0x40B150 = 4239696. All addresses must be multiples of 16
  58.            
  59.    room_number: the number of the room these actors are associated with; if the actor is a transition (i..e Plane
  60.                or Door), then set room_numer = False
  61.                
  62.    
  63.    priority: an index to differentiate copies of the same instance
  64.    
  65.    from_spawner: True or False (True if it is from a spawner, like rupees from a cluster; False otherwise)
  66.    
  67.    transition: False is the actor is not a Loading Plane or a Door. Otherwise, it is a list of the rooms that the transition actor connects, ordered from least to greatest room number
  68.    
  69.    clearable: True if it is possible to set a flag to make this actor not respawn upon reloading the room (though, unless it it Category 5, it will attempt to reload and then immediately deallocate), False otherwise
  70.    
  71.    cleared: True if the flag was set to clear this actor, False otherwise
  72.    
  73.    """
  74.    
  75.     def __init__(self, name, Id, size, category, overlay_type, unloadable, address, room_number, priority, from_spawner, transition, clearable, cleared):
  76.         self.name = name
  77.         self.Id = Id
  78.         self.size = size
  79.         self.category = category
  80.         self.overlay_type = overlay_type
  81.         self.unloadable = unloadable
  82.         self.address = address
  83.         self.room_number = room_number
  84.         self.priority = priority
  85.         self.from_spawner = from_spawner
  86.         self.transition = transition
  87.         self.clearable = clearable
  88.         self.cleared = cleared
  89.  
  90. class Room:
  91.    
  92.     """
  93.    
  94.    number: the room number (i.e. Room 0 has number 0)
  95.    
  96.    priority_queue: this will be the list of actor instances of the room, in order
  97.    
  98.    clock_exists: boolean for whether or not the clock is an actor in the queue
  99.    
  100.    clock_priority: if clock_exists == False, then clock_priority will be a number
  101.                    to determine where in the queue the clock should be loaded, for
  102.                    example, if clock_priority is 2, then it means that the clock
  103.                    should be the 3rd actor to appear in the queue (first index is 0)
  104.    
  105.    """
  106.    
  107.     def __init__(self, number, priority_queue, clock_exists, clock_priority):
  108.         self.number = number
  109.         self.priority_queue = priority_queue
  110.         self.clock_exists = clock_exists
  111.         self.clock_priority = clock_priority
  112.  
  113. class Node:
  114.    
  115.     """
  116.    address: which address in memory the node is at (as a base-10 integer for now)
  117.    
  118.    size: nodes should be 16 bytes (english), so input 16
  119.    
  120.    """
  121.    
  122.     def __init__(self, address, size):
  123.         self.address = address
  124.         self.size = size
  125.  
  126. class Overlay:
  127.    
  128.     def __init__(self, address, Id, size):
  129.         self.address = address
  130.         self.Id = Id
  131.         self.size = size
  132.  
  133.  
  134. """
  135.  
  136. We define the Clock actor ahead of time as it is not necessarily present in each room
  137.  
  138. """
  139.  
  140.  
  141. Clock = Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  142.  
  143. ###############################################################################
  144.  
  145. Oceanside_Room3_queue = [
  146.         Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[3,4], clearable=False, cleared=False),
  147.         Actor(name='Wooden Door', Id='0005', size=0x1CC, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[2,3], clearable=False, cleared=False),
  148.         Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  149.         Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  150.         Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  151.         Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
  152.         Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  153.         Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  154.         Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  155.         Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  156.         Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  157.         Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
  158.         Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
  159.         Actor(name='Spiderweb', Id='0125', size=0x2FC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
  160.         Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
  161.         Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  162.         Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
  163.         Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  164.         Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
  165.         Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  166.         Actor(name='Tent-Shaped Spider Web', Id='01F4', size=0x3CC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
  167.         Actor(name='Oceanside Spider House Fireplace Grate', Id='020F', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  168.         Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
  169.         Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False)
  170.         ]
  171.  
  172.  
  173. Oceanside_Room4_queue = [
  174.         Oceanside_Room3_queue[0],
  175.         Actor(name='Skulltula', Id='0024', size=0x550, category=5, overlay_type='A', unloadable=True, address=0, room_number=4, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  176.         Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=4, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  177.         ]
  178.  
  179.  
  180.  
  181.  
  182.  
  183. ###############################################################################
  184.  
  185. Room0_queue = [
  186.         Actor(name='Wooden Door', Id='0005', size=460, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[0,3], clearable=False, cleared=False),
  187.         Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[0,1], clearable=False, cleared=False),
  188.         Actor(name='Rupee Cluster', Id='00E8', size=360, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
  189.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  190.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  191.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  192.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  193.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  194.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  195.         Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  196.         ]
  197.  
  198.  
  199. Room1_queue = [
  200.         Actor(name='Door Shutter', Id='001E', size=360, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[1,2], clearable=False, cleared=False),
  201.         Room0_queue[1],
  202.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
  203.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
  204.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
  205.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
  206.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
  207.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False),
  208.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=6, from_spawner=False, transition=False, clearable=True, cleared=False),
  209.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=7, from_spawner=False, transition=False, clearable=True, cleared=False),
  210.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=8, from_spawner=False, transition=False, clearable=True, cleared=False),
  211.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=9, from_spawner=False, transition=False, clearable=True, cleared=False),
  212.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=10, from_spawner=False, transition=False, clearable=True, cleared=False),
  213.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=11, from_spawner=False, transition=False, clearable=True, cleared=False),
  214.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=12, from_spawner=False, transition=False, clearable=True, cleared=False),
  215.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=13, from_spawner=False, transition=False, clearable=True, cleared=False),
  216.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=14, from_spawner=False, transition=False, clearable=True, cleared=False),
  217.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=15, from_spawner=False, transition=False, clearable=True, cleared=False),
  218.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=16, from_spawner=False, transition=False, clearable=True, cleared=False),
  219.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=17, from_spawner=False, transition=False, clearable=True, cleared=False),
  220.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=18, from_spawner=False, transition=False, clearable=True, cleared=False),
  221.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=19, from_spawner=False, transition=False, clearable=True, cleared=False),
  222.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  223.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  224.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  225.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
  226.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
  227.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
  228.         Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  229.         ]
  230.  
  231. ###############################################################################
  232.  
  233. Room0 = Room(0, Room0_queue, False, 2)
  234. Room1 = Room(1, Room1_queue, False, 2)
  235.  
  236.  
  237. Oceanside_Room3 = Room(3, Oceanside_Room3_queue, False, 2)
  238. Oceanside_Room4 = Room(4, Oceanside_Room4_queue, False, 1)
  239.  
  240. """
  241.  
  242. Define the list of Rooms that we consider
  243.  
  244. """
  245.  
  246. Room_List = [Room0, Room1]
  247.  
  248. Oceanside_Room_List = [Oceanside_Room3, Oceanside_Room4]
  249.  
  250.  
  251. """
  252.  
  253. In Overlay_dict we collect all of the Overlays of Type A, where the keys are
  254. the corresponding actor ids
  255.  
  256. """
  257.  
  258. # NOTE: This must be named "Overlay_dict" because it is hardcoded in some functions, like the Deallocate() function
  259. Overlay_dict = {
  260.         '015A' : Overlay(address=0, Id='015A', size=6000),
  261.         '00E8' : Overlay(address=0, Id='00E8', size=1984),
  262.         '0170' : Overlay(address=0, Id='0170', size=10688),
  263.         '0039' : Overlay(address=0, Id='0039', size=3552),
  264.         '0082' : Overlay(address=0, Id='0082', size=9040),
  265.         '0158' : Overlay(address=0, Id='0158', size=1104),
  266.         '015B' : Overlay(address=0, Id='015B', size=6048),
  267.         '0006' : Overlay(address=0, Id='0006', size=8640),
  268.         '0017' : Overlay(address=0, Id='0017', size=10432),
  269.         '017B' : Overlay(address=0, Id='017B', size=14320),
  270.         '007B' : Overlay(address=0, Id='007B', size=5104),
  271.         '00A2' : Overlay(address=0, Id='00A2', size=24448),
  272.         '02A5' : Overlay(address=0, Id='02A5', size=0x2660),
  273.         '0210' : Overlay(address=0, Id='0210', size=0xB90),
  274.         '0050' : Overlay(address=0, Id='0050', size=0x3540),
  275.         '0125' : Overlay(address=0, Id='0125', size=0x1490),
  276.         '01E7' : Overlay(address=0, Id='01E7', size=0x450),
  277.         '01F4' : Overlay(address=0, Id='01F4', size=0x1A80),
  278.         '020F' : Overlay(address=0, Id='020F', size=0x780),
  279.         '0024' : Overlay(address=0, Id='0024', size=0x28E0),
  280.         '00E3' : Overlay(address=0, Id='00E3', size=0x420)
  281.             }
  282.  
  283. """
  284.  
  285. Here we collect a list of the actors that we allow ourselves to spawn
  286.  
  287. Notes:
  288.    'Zora Fins' means 2 fins
  289.    'Bugs' means a set of 3 bugs
  290.    
  291.  
  292. """
  293.  
  294. Allocation_List = [
  295.         'Nothing',
  296.         'Bomb',
  297.         'Smoke',
  298.         'Arrow',
  299.         'Hookshot',
  300.         'Charged Spin Attack',
  301.         'Chu',
  302.         'Zora Fins',
  303.         'Fish',
  304.         'Bugs'
  305.         ]
  306.  
  307. ######
  308.  
  309.  
  310. """
  311.  
  312. NOTE: We NEED to have 'Hookshot' and 'Charged Spin Attack' as the last two options
  313. in order to consider all cases
  314.  
  315. Don't have 'Bomb' before 'Smoke' to ensure that the Smoke always gets allocated first
  316.  
  317. maybe in the future you could jumble/randomize the order of things in this list at each step
  318. of the solver
  319.  
  320. """
  321. Hardcoded_Allocation_List = [
  322.         'Smoke',
  323.         'Smoke',
  324.         'Smoke',
  325.         'Chu',
  326.         'Chu',
  327.         'Chu',
  328.         'Arrow',
  329.         'Arrow',
  330.         'Arrow',
  331.         'Arrow',
  332.         'Arrow',
  333.         'Bomb',
  334.         'Bomb',
  335.         'Bomb',
  336.         'Zora Fins',
  337.         'Fish',
  338.         'Fish',
  339.         'Bugs',
  340.         'Bugs',
  341.         'Hookshot',
  342.         'Charged Spin Attack'
  343.         ]
  344.  
  345. """
  346.  
  347. Here we collect a list of the Ids grabbable actors that we can use for superslide SRM
  348. So far this includes:
  349.    
  350.    0082: Pot
  351.  
  352. """
  353.  
  354. Grabbable_Actors = ['0082']
  355.  
  356.  
  357. """
  358.  
  359. Here we collect a list of Actor Ids for spawners. So far this includes:
  360.    
  361.    00E8: Rupee Cluster
  362.  
  363. """
  364.  
  365. Spawner_Ids = ['00E8']
  366.  
  367.  
  368. """
  369.  
  370. We initialize the Heap as a list, putting a node with address 0x40B140 in the 0th entry
  371. and we place a dummy node at the end of the Heap so that there will always exist two
  372. consecutive nodes for us to define a condition for which free space in the Heap exists
  373.  
  374. Keep in mind that the 0x5FFFFF address in the dummy node will not reflect the actual
  375. address of the corresponding node in-game, but it also isn't relevant to heap manipulation
  376. since it is so far down
  377.  
  378. """
  379.  
  380.  
  381. Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
  382.  
  383.  
  384.  
  385. def Overlay_In_Heap(Heap, overlay):
  386.    
  387.     """
  388.    
  389.    Overlay is the overlay that we want to check whether or not it is in the Heap
  390.    
  391.    This function will return True if Overlay is in the Heap and False otherwise
  392.    
  393.    """
  394.    
  395.     overlay_in_heap = False
  396.    
  397.     for entry in Heap:
  398.        
  399.         if type(entry) == Overlay and entry.Id == overlay.Id:
  400.            
  401.             overlay_in_heap = True
  402.        
  403.     return overlay_in_heap
  404.  
  405.  
  406. def Actor_Id_In_Heap(Heap, actor_id):
  407.    
  408.     """
  409.    
  410.    actor_id is the Id that we want to check for
  411.    
  412.    This function will return True if there exists an Actor in the Heap that
  413.    has actor_id as its Id and it will return False otherwise
  414.    
  415.    """
  416.    
  417.     actor_id_in_heap = False
  418.    
  419.     for entry in Heap:
  420.        
  421.         if type(entry) == Actor and entry.Id == actor_id:
  422.            
  423.             actor_id_in_heap = True
  424.    
  425.     return actor_id_in_heap
  426.  
  427.  
  428. def Find_Gaps(Heap):
  429.    
  430.     """
  431.    
  432.    This function will find all consecutive nodes and output a list of 4-tuples
  433.    where the first two entries correspond to the indices of each node in the list
  434.    and the last two entries correspond to the addresses of each node
  435.    
  436.    The list should be in order, from the start of the Heap to the end of the Heap
  437.    
  438.    """
  439.    
  440.     consecutive_node_count = 0
  441.    
  442.     node_1_address = 0
  443.     node_2_address = 0
  444.     node_1_index = 0
  445.     node_2_index = 0
  446.    
  447.     consecutive_node_list = []
  448.     for entry in Heap:
  449.         if type(entry) == Node and consecutive_node_count == 0:
  450.             node_1_address = entry.address
  451.             node_1_index = Heap.index(entry)
  452.             consecutive_node_count += 1
  453.         elif type(entry) == Node and consecutive_node_count == 1:
  454.             node_2_address = entry.address
  455.             node_2_index = Heap.index(entry)
  456.            
  457.             consecutive_node_list.append((node_1_index, node_2_index, node_1_address, node_2_address))
  458.            
  459.             consecutive_node_count += 1
  460.         elif type(entry) != Node:
  461.             consecutive_node_count = 0
  462.         elif type(entry) == Node and consecutive_node_count > 1:
  463.             consecutive_node_count += 1
  464.             print("ERROR: More than 2 consecutive nodes!! (Find_Gaps() Error Message)")
  465.        
  466.    
  467.     return consecutive_node_list
  468.    
  469.  
  470.  
  471.  
  472. def Allocate(Heap, actor, Overlay_Dict):
  473.    
  474.     """
  475.    
  476.    actor is the actor that we want to allocate into the Heap
  477.    
  478.    Overlay_Dict is a dictionary where the keys are the actor ids which point to the corresponding Overlays
  479.    
  480.    This function will account for placing nodes and overlays
  481.    
  482.    """
  483.    
  484.    
  485.     #Overlay = Overlay_Dict[actor.Id]
  486.    
  487.     #Overlay_Allocated = False
  488.    
  489.     #if Overlay_In_Heap(Heap, Overlay) == True:
  490.     #    Overlay_Allocated = True
  491.    
  492.     Actor_Allocated = False
  493.    
  494.     """
  495.    ##### Not yet defined, not sure if I will bother; not really necessary. Probably should for debugging
  496.    if Actor_In_Heap == True:
  497.        print('Error: This Actor is already allocated!! (Error message from Allocate() function)')
  498.    """
  499.    
  500.     gap_list = Find_Gaps(Heap)
  501.    
  502.     # Because we initialize the Heap with 2 nodes, there should always be at least one gap
  503.     if len(gap_list) < 1:
  504.         print('ERROR: len(gap_list) < 1 in Allocate() function')
  505.    
  506.    
  507.     # If the Overlay is type A and the Overlay is not already in the Heap, then we want to allocate the overlay first
  508.     if actor.overlay_type == 'A':
  509.        
  510.         ##### We only define Overlay for Type A overlays because Overlay_Dict only has Type A overlays
  511.         Overlay = Overlay_Dict[actor.Id]
  512.         Overlay_Allocated = False
  513.        
  514.         if Overlay_In_Heap(Heap, Overlay) == True:
  515.             Overlay_Allocated = True
  516.        
  517.        
  518.         if Overlay_In_Heap(Heap, Overlay) == False:
  519.        
  520.             for gap in gap_list:
  521.                
  522.                 if Overlay_Allocated == True:
  523.                     break ##### This ensures we don't add in the same Overlay multiple times
  524.                
  525.                 node_2_index = gap[1]
  526.                 node_1_address = gap[2]
  527.                 node_2_address = gap[3]
  528.                
  529.                 gap_size = node_2_address - node_1_address - node_size
  530.                
  531.                 ##### Case 1: the Overlay can fit, but there is NOT enough space for an extra node
  532.                 # Note that gap_size is always a multiple of 16
  533.                
  534.                 if Overlay.size <= gap_size and Overlay.size > gap_size - 2*node_size:
  535.                    
  536.                     Overlay.address = node_1_address + node_size
  537.                     Heap.insert(node_2_index, Overlay)
  538.                     Overlay_Allocated = True
  539.                    
  540.                
  541.                 ##### Case 2: the Overlay can fit and a new node can also fit
  542.                
  543.                 elif Overlay.size <= gap_size and Overlay.size <= gap_size - 2*node_size:
  544.                    
  545.                     Overlay.address = node_1_address + node_size
  546.                     Heap.insert(node_2_index, Overlay)
  547.                    
  548.                     ########### ADD IN THE NODE HERE
  549.                     if Overlay.size%16 > 0:
  550.                         Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size + (16 - Overlay.size%16), size=node_size))
  551.                     elif Overlay.size%16 == 0:
  552.                         Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size, size=node_size))
  553.                        
  554.                     Overlay_Allocated = True
  555.                
  556.     ############ Now the overlay (if applicable) has been allocated. Now we need to allocate the actor.
  557.    
  558.     ##### We need to update the gaps_list to account for the overlay being allocated in the Heap already
  559.     gap_list = Find_Gaps(Heap)
  560.    
  561.     for gap in gap_list:
  562.        
  563.         if Actor_Allocated == True:
  564.             break ##### This ensures we don't add in the same Actor multiple times
  565.        
  566.         node_2_index = gap[1]
  567.         node_1_address = gap[2]
  568.         node_2_address = gap[3]
  569.        
  570.         gap_size = node_2_address - node_1_address - node_size
  571.        
  572.         ##### Case 1: the Actor can fit, but there is NOT enough space for an extra node
  573.         # Note that gap_size is always a multiple of 16
  574.        
  575.         if actor.size <= gap_size and actor.size > gap_size - 2*node_size:
  576.            
  577.             actor.address = node_1_address + node_size
  578.             Heap.insert(node_2_index, actor)
  579.             Actor_Allocated = True
  580.            
  581.        
  582.         ##### Case 2: the Actor can fit and a new node can also fit
  583.        
  584.         elif actor.size <= gap_size and actor.size <= gap_size - 2*node_size:
  585.            
  586.             actor.address = node_1_address + node_size
  587.             Heap.insert(node_2_index, actor)
  588.            
  589.             ########### ADD IN THE NODE HERE
  590.             if actor.size%16 > 0:
  591.                 Heap.insert(node_2_index + 1, Node(address=actor.address + actor.size + (16 - actor.size%16), size=node_size))
  592.             elif actor.size%16 == 0:
  593.                 Heap.insert(node_2_index + 1, Node(address=actor.address + actor.size, size=node_size))
  594.                    
  595.             Actor_Allocated = True
  596.  
  597. def Borders_Node(Heap, entry):
  598.    
  599.     """
  600.    
  601.    This function takes an entry of the Heap as input and determines whether or
  602.    not this entry is adjacent to a node in the heap (the purpose of this is to
  603.    check if a node is bordering another node since actors and overlays should
  604.    be bordering two nodes under every circumstance)
  605.    
  606.    Returns True if the entry is bordering a node, returns False otherwise    
  607.    
  608.    """
  609.    
  610.     borders_node = False
  611.    
  612.     entry_index = Heap.index(entry)
  613.    
  614.     border_1_is_node = False
  615.     border_2_is_node = False
  616.    
  617.     if entry_index != 0:
  618.         border_1 = Heap[entry_index - 1]
  619.         if type(border_1) == Node:
  620.             border_1_is_node = True
  621.    
  622.     if entry_index != len(Heap) - 1:
  623.         border_2 = Heap[entry_index + 1]
  624.         if type(border_2) == Node:
  625.             border_2_is_node = True
  626.    
  627.     if border_1_is_node == True or border_2_is_node == True:
  628.         borders_node = True
  629.    
  630.     return borders_node
  631.        
  632.  
  633.  
  634. def Deallocate(Heap, actor, Overlay_dict):
  635.    
  636.    
  637.     """
  638.    
  639.    actor is the actor that we want to be deallocated from the Heap
  640.    
  641.    This function will account for removing nodes and overlays
  642.    
  643.    ##### Remove the actor AND node if applicable
  644.    ##### Check if any actors with the same Id are still in the Heap
  645.    ##### if not (and the actor has overlay Type A), then remove the overlay
  646.    
  647.    We only remove a node if it is part of a gap before deallocating the actor
  648.    That is, we only remove a node if it borders another node before the actor is deallocated
  649.    
  650.    """
  651.    
  652.     if type(actor) != Actor:
  653.         print("ERROR: Attempted to deallocate something other than an Actor (Deallocate() function error message)")
  654.    
  655.     # The index of where the actor is in the Heap before being deallocated; this will change after we remove the first node
  656.     actor_index = Heap.index(actor)
  657.    
  658.     ##### First check the node above the actor in the Heap
  659.     node_1 = Heap[actor_index - 1]
  660.     if type(node_1) != Node:
  661.         print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
  662.    
  663.     if Borders_Node(Heap, node_1) == True:
  664.         Heap.remove(node_1)
  665.        
  666.     ########## Now the first node has been removed and the indices of the Heap shift
  667.    
  668.     ##### Now we check the node below the actor in the Heap
  669.    
  670.     # The index of where the actor is in the Heap before being deallocated; this will change after we remove the first node
  671.     actor_index = Heap.index(actor)
  672.    
  673.     node_2 = Heap[actor_index + 1]
  674.     if type(node_2) != Node:
  675.         print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
  676.    
  677.     if Borders_Node(Heap, node_2) == True:
  678.         Heap.remove(node_2)
  679.    
  680.     ###########################################################################
  681.     ##### Now we have removed both of the nodes, if applicable and we must remove the actor itself
  682.    
  683.     Heap.remove(actor)
  684.    
  685.     """
  686.    
  687.    Now if the actor has a Type A overlay, then we must check if the Heap contains
  688.    any other actors that have the same Id as actor and if not, then we must also
  689.    remove its overlay from the Heap
  690.    
  691.    We must also account for removing the nodes around the overlay, if applicable
  692.    
  693.    """
  694.    
  695.     if actor.overlay_type == 'A' and Actor_Id_In_Heap(Heap, actor.Id) == False:
  696.        
  697.         ##### First check the node above the overlay
  698.         overlay_index = Heap.index(Overlay_dict[actor.Id])
  699.         node1 = Heap[overlay_index - 1]
  700.        
  701.         if type(node1) != Node:
  702.             print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
  703.        
  704.         if Borders_Node(Heap, node1) == True:
  705.             Heap.remove(node1)
  706.        
  707.        
  708.         ##### Now we check the node below the overlay
  709.         overlay_index = Heap.index(Overlay_dict[actor.Id])
  710.         node2 = Heap[overlay_index + 1]
  711.        
  712.         if type(node2) != Node:
  713.             print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
  714.        
  715.         if Borders_Node(Heap, node2) == True:
  716.             Heap.remove(node2)
  717.        
  718.         ###########################################################################
  719.         ##### Now we have removed both of the nodes, if applicable and we must remove the overlay itself
  720.        
  721.         Heap.remove(Overlay_dict[actor.Id])
  722.  
  723.  
  724.  
  725. def Load_Scene(Heap, room, Overlay_dict):
  726.    
  727.     if len(Heap) != 2:
  728.         print("ERROR: Attempted to use Load_Scene() with an inappropriate Heap")
  729.    
  730.     entry_count = 0
  731.     for entry in room.priority_queue:
  732.        
  733.         ##### If the clock is not in the room's set of actors, then we must allocate the clock at the appropriate time when we load the scene
  734.         if entry_count == room.clock_priority and room.clock_exists == False:
  735.            
  736.             ##### Allocate the 3-Day Clock actor
  737.             Allocate(Heap, Clock, Overlay_dict)
  738.             entry_count += 1
  739.        
  740.         ##### Allocate the entry in the room's priority queue
  741.         Allocate(Heap, entry, Overlay_dict)
  742.        
  743.         entry_count += 1
  744.    
  745.     ##### Now that all of the actors have been allocated, we want to add in all of the actors that the spawners spawn
  746.    
  747.     """
  748.    
  749.    NOTE: THIS DOES NOT HANDLE SPAWNERS OTHER THAN RUPEE CLUSTERS AT THE MOMENT
  750.    
  751.    In the future, it will need to be considered how the actors created by spawners
  752.    prioritize over each other... Spring MV is maybe the only place where this really matters
  753.    
  754.    """
  755.    
  756.     ##### Check for Rupee Cluster
  757.     if Overlay_In_Heap(Heap, Overlay_dict['00E8']) == True:
  758.        
  759.         for j in range(7):
  760.             rupee = Actor(name='Collectible (Rupee from Rupee Cluster)', Id='000E', size=424, category=0, overlay_type='B', unloadable=True, address=0, room_number=room.number, priority=j, from_spawner=True, transition=False, clearable=True, cleared=False)
  761.            
  762.             Allocate(Heap, rupee, Overlay_dict)
  763.  
  764.  
  765.  
  766. def Actor_From_Room_In_Heap(Heap, Room_Number):
  767.    
  768.     """
  769.    
  770.    This function takes the Heap and the number of the Room in question as input
  771.    It returns True if there exists an Actor in the Heap with the inputted Room_Number and False otherwise
  772.    
  773.    """
  774.    
  775.     actor_from_room_in_heap = False
  776.    
  777.     for entry in Heap:
  778.        
  779.         if type(entry) == Actor and entry.room_number is Room_Number:
  780.            
  781.             actor_from_room_in_heap = True
  782.    
  783.     return actor_from_room_in_heap
  784.  
  785. def Cleared_Actor_In_Heap(Heap):
  786.    
  787.     """
  788.    
  789.    This function returns True if there is a cleared actor in the Heap and False otherwise
  790.    
  791.    """
  792.    
  793.     cleared_actor_in_heap = False
  794.    
  795.     for entry in Heap:
  796.        
  797.         if type(entry) == Actor and entry.cleared == True:
  798.            
  799.             cleared_actor_in_heap = True
  800.        
  801.     return cleared_actor_in_heap
  802.  
  803.  
  804. def Shared_Transition_Count(Heap, Room_Number_1, Room_Number_2):
  805.    
  806.     """
  807.    
  808.    This function returns the number of transitions (Planes/Doors) that are shared between
  809.    the two rooms with room numbers Room_Number_1 and Room_Number_2
  810.    
  811.    """
  812.    
  813.     shared_transition_count = 0
  814.    
  815.     for entry in Heap:
  816.        
  817.         if type(entry) == Actor and entry.transition != False:
  818.            
  819.             if (entry.transition[0] == Room_Number_1 and entry.transition[1] == Room_Number_2) or (entry.transition[0] == Room_Number_2 and entry.transition[1] == Room_Number_1):
  820.                
  821.                 shared_transition_count += 1
  822.    
  823.     return shared_transition_count
  824.  
  825. def Is_Shared_Transition(actor, Room_Number_1, Room_Number_2):
  826.    
  827.     """
  828.    
  829.    If actor is a transition shared between Rooms with numbers Room_Number_1 and Room_Number_2,
  830.    then this function returns True. Otherwise it returns False
  831.    
  832.    """
  833.    
  834.     is_shared_transition = False
  835.    
  836.     if type(actor) == Actor and actor.transition != False:
  837.        
  838.         if (actor.transition[0] == Room_Number_1 and actor.transition[1] == Room_Number_2) or (actor.transition[0] == Room_Number_2 and actor.transition[1] == Room_Number_1):
  839.            
  840.             is_shared_transition = True
  841.    
  842.     return is_shared_transition
  843.        
  844.  
  845. def Transition_Is_In_Room(actor, Room_Number):
  846.    
  847.     transition_is_in_room = False
  848.    
  849.     if type(actor) == Actor and actor.transition != False:
  850.        
  851.         if actor.transition[0] == Room_Number or actor.transition[1] == Room_Number:
  852.            
  853.             transition_is_in_room = True
  854.    
  855.     return transition_is_in_room
  856.  
  857.  
  858. def Find_Clock_List(Heap):
  859.    
  860.     """
  861.    
  862.    This function finds all clock actor instances in the Heap and returns a list of them, in order
  863.    
  864.    """
  865.    
  866.     clock_list = []
  867.    
  868.     for entry in Heap:
  869.        
  870.         if type(entry) == Actor and entry.Id == '015A':
  871.            
  872.             clock_list.append(entry)
  873.    
  874.     return clock_list
  875.    
  876.  
  877. def Load_Room(Heap, room, transition, Overlay_dict):
  878.    
  879.    
  880.     """
  881.    
  882.    This function updates the Heap after you enter room through transition
  883.    For example, you might enter Room0 through Plane1 or Door3
  884.    
  885.    Before executing the script, should probably define Plane1, Plane2, ...
  886.    Door1, Door2, ..., etc. as the corresponding entries from the room queues.
  887.    This will make the code more readable when looking for solutions
  888.    
  889.    
  890.    * First we load all of the actors from the new room
  891.    * Next, we deallocate everything (well, not literally everything...) from the previous room
  892.    
  893.    
  894.    Things that this function needs to handle:
  895.        
  896.        - make sure that you check if each actor was cleared or not (if clearable == True, otherwise it isn't applicable)
  897.        and then check if it is Category 5 to determine if it loads and immediately deallocates or not
  898.        
  899.        - checking which clock to deallocate (i.e. deallocate the one that comes later
  900.        on in the Heap if there are more than one). Maybe define a Find_Clocks function
  901.        
  902.        - make sure transition never deallocates and never attempts to allocate
  903.        
  904.        - make sure that the other Transitions unload and then reload (if applicable) after all of
  905.        the stuff from the previous room deallocated
  906.        
  907.        - when deallocating stuff from the room that isn't the room you're entering, be sure
  908.        not to deallocate the clock. Also be careful of relevant Transitions as they don't have
  909.        actual room numbers (replaced with False)
  910.        
  911.        - allocate stuff from spawners after the fact (even after planes)
  912.        
  913.    
  914.    """
  915.    
  916.     if transition not in Heap:
  917.         print('2222222222')
  918.        
  919.     if transition not in room.priority_queue:
  920.         print('44444444')
  921.    
  922.     if (transition not in Heap) or (transition not in room.priority_queue):
  923.         print("ERROR: Attempted to use Load_Room() with an invalid transition")
  924.    
  925.     current_room_number = -1
  926.     new_room_number = room.number
  927.    
  928.     if transition.transition[0] == room.number:
  929.         current_room_number = transition.transition[1]
  930.     elif transition.transition[1] == room.number:
  931.         current_room_number = transition.transition[0]
  932.     else:
  933.         print("ERROR: Error with transition list (Load_Room() error message)")
  934.    
  935.     """
  936.    First we load all of the actors from the new room, EXCEPT for: the plane/door
  937.    we pass through AND any other shared transitions AND any actors with both
  938.    cleared == True and Category == 5 (these ones never attempt to load)
  939.    """
  940.    
  941.     for actor in room.priority_queue:
  942.        
  943.         ### If the actor is not a Transition OR if the actor is a transition but doesn't connect to the current room
  944.         if (actor.transition == False) or (actor.transition != False and actor.transition[0] != current_room_number and actor.transition[1] != current_room_number):
  945.            
  946.             ### If the actor is Category 5, then only attempt to load it if it has not been cleared
  947.             if actor.category != 5 or actor.cleared == False:
  948.                
  949.                 Allocate(Heap, actor, Overlay_dict)
  950.    
  951.     """
  952.    - Now all of the relevant actors from the new room have been allocated
  953.    - Now we need to immediately deallocate any actors with Clearable == True and Cleared == True
  954.    - We also need to deallocate any transitions which are shared between the current room and the new room
  955.      EXCEPT for transition itself (the transition that we passed through to get to the new room)
  956.    - We also need to deallocate the second clock actor in the Heap if it exists (do this after everything else for simplicity)
  957.      
  958.      Note that "current_room_number" is the room number of the room we were in before loading the new room
  959.    """
  960.  
  961.     while Actor_From_Room_In_Heap(Heap, current_room_number) == True or Cleared_Actor_In_Heap(Heap) == True or Shared_Transition_Count(Heap, current_room_number, new_room_number) > 1:
  962.        
  963.         for entry in Heap:
  964.            
  965.             if (type(entry) == Actor) and (entry.room_number is current_room_number or entry.cleared == True or Is_Shared_Transition(entry, current_room_number, new_room_number) == True or  (entry.transition != False and Transition_Is_In_Room(entry, new_room_number) == False )  ) and (entry != transition):
  966.                
  967.                 Deallocate(Heap, entry, Overlay_dict)
  968.    
  969.     ########## Now we will find all of the clocks and deallocate the second clock if it exists (and report error if more than two clocks)
  970.    
  971.     Clock_List = Find_Clock_List(Heap)
  972.    
  973.     if len(Clock_List) > 2:
  974.         print("ERROR: More than 2 Clocks in the Actor Heap (Load_Room() Error Message)")
  975.     elif len(Clock_List) < 1:
  976.         print("ERROR: No Clock Actor Instance in the Actor Heap (Load_Room() Error Message)")
  977.    
  978.     ##### If there are two clocks, then we deallocate the second clock that appears in the Heap
  979.     if len(Clock_List) > 1:
  980.        
  981.         Deallocate(Heap, Clock_List[1], Overlay_dict)
  982.    
  983.    
  984.     ##### Now we allocate any shared transitions EXCEPT for transition itself (the door/plane we entered to get into this room)
  985.    
  986.     for entry in room.priority_queue:
  987.        
  988.         # If entry is a shared transition and is NOT the transition that we passed through
  989.         if (type(entry) == Actor) and (entry.transition != False) and Is_Shared_Transition(entry, current_room_number, new_room_number) == True and (entry != transition):
  990.            
  991.             Allocate(Heap, entry, Overlay_dict)
  992.    
  993.     ###################################### Now we only have to account for allocating things from spawners
  994.    
  995.    
  996.     """
  997.    
  998.    NOTE: THIS DOES NOT HANDLE SPAWNERS OTHER THAN RUPEE CLUSTERS AT THE MOMENT
  999.    
  1000.    In the future, it will need to be considered how the actors created by spawners
  1001.    prioritize over each other... Spring MV is maybe the only place where this really matters
  1002.    
  1003.    """
  1004.    
  1005.     ##### Check for Rupee Cluster
  1006.     if Overlay_In_Heap(Heap, Overlay_dict['00E8']) == True:
  1007.        
  1008.         for j in range(7):
  1009.             rupee = Actor(name='Collectible (Rupee from Rupee Cluster)', Id='000E', size=424, category=0, overlay_type='B', unloadable=True, address=0, room_number=room.number, priority=j, from_spawner=True, transition=False, clearable=True, cleared=False)
  1010.            
  1011.             Allocate(Heap, rupee, Overlay_dict)
  1012.        
  1013.  
  1014.  
  1015.  
  1016.  
  1017. def Display_Heap(Heap):
  1018.    
  1019.     for entry in Heap:
  1020.        
  1021.         if type(entry) == Node:
  1022.            
  1023.             print(hex(entry.address) + '-----' + 'NODE-----------------')
  1024.            
  1025.         elif type(entry) == Overlay:
  1026.            
  1027.             print(hex(entry.address) + '     ' + entry.Id + '     ' + 'OVERLAY')
  1028.        
  1029.         elif type(entry) == Actor:
  1030.            
  1031.             print(hex(entry.address) + '     ' + entry.Id + '     ' + 'INSTANCE')
  1032.        
  1033.         else:
  1034.             print("ERROR!!! Unexpected Entry Type in Heap!!!!!!!!!")
  1035.  
  1036.  
  1037. ###############################################################################
  1038. ###############################################################################
  1039. ###############################################################################
  1040. ###############################################################################
  1041. ###############################################################################
  1042. ###############################################################################
  1043.  
  1044. def Allocate_Fish(Heap, Room_Number, Overlay_dict):
  1045.    
  1046.     Fish = Actor(name='Fish', Id='0017', size=636, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1047.    
  1048.     Allocate(Heap, Fish, Overlay_dict)
  1049.  
  1050.  
  1051. def Allocate_Bugs(Heap, Room_Number, Overlay_dict):
  1052.    
  1053.     """
  1054.    
  1055.    This function allocates a set of 3 bugs to the Heap
  1056.    
  1057.    """
  1058.    
  1059.     for i in range(3):
  1060.         Bug = Actor(name='Bug', Id='017B', size=884, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=i, from_spawner=False, transition=False, clearable=False, cleared=False)
  1061.    
  1062.         Allocate(Heap, Bug, Overlay_dict)
  1063.  
  1064.  
  1065. def Allocate_Bomb(Heap, Room_Number, Overlay_dict):
  1066.    
  1067.     Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1068.    
  1069.     Allocate(Heap, Bomb, Overlay_dict)
  1070.  
  1071.  
  1072. def Allocate_Smoke(Heap, Room_Number, Overlay_dict):
  1073.    
  1074.     """
  1075.    
  1076.    This function allocates a bomb, then allocates smoke (this happens when the bomb explodes)
  1077.    and then deallocates the bomb (we bothered allocating the bomb to ensure that the smoke
  1078.    appears in the right spot in the Heap)
  1079.    
  1080.    Note that we should never allow ourselves to allocate smoke AFTER calling Allocate_Bomb()
  1081.    because in reality the first bomb would explode first (this isn't strictly true, but we should
  1082.    do it this way at least in the simple script)
  1083.    
  1084.    """
  1085.    
  1086.     Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1087.    
  1088.     Allocate(Heap, Bomb, Overlay_dict)
  1089.    
  1090.     Smoke = Actor(name='Smoke', Id='00A2', size=11908, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1091.    
  1092.     Allocate(Heap, Smoke, Overlay_dict)
  1093.    
  1094.     Deallocate(Heap, Bomb, Overlay_dict)
  1095.  
  1096. def Allocate_Arrow(Heap, Room_Number, Overlay_dict):
  1097.    
  1098.     """
  1099.    
  1100.    This function allocates an arrow into the heap. Note that Deku Bubbles are
  1101.    the same actor as arrows (in that they're both 000F)
  1102.    
  1103.    """
  1104.    
  1105.     Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1106.    
  1107.     Allocate(Heap, Arrow, Overlay_dict)
  1108.  
  1109.  
  1110. def Allocate_Hookshot(Heap, Room_Number, Overlay_dict):
  1111.    
  1112.     Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1113.    
  1114.     Allocate(Heap, Hookshot, Overlay_dict)
  1115.  
  1116.  
  1117. def Allocate_Chu(Heap, Room_Number, Overlay_dict):
  1118.    
  1119.     Chu = Actor(name='Chu', Id='006A', size=480, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1120.    
  1121.     Allocate(Heap, Chu, Overlay_dict)
  1122.  
  1123.  
  1124. def Allocate_Zora_Fins(Heap, Room_Number, Overlay_dict):
  1125.    
  1126.     """
  1127.    
  1128.    This function allocates 2 Zora Fin actor instances
  1129.    
  1130.    """
  1131.    
  1132.     for i in range(2):
  1133.        
  1134.         Zora_Fin = Actor(name='Zora Fin', Id='0020', size=500, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1135.        
  1136.         Allocate(Heap, Zora_Fin, Overlay_dict)
  1137.  
  1138.  
  1139. def Allocate_Charged_Spin_Attack(Heap, Room_Number, Overlay_dict):
  1140.    
  1141.     """
  1142.    
  1143.    This functions allocates the Spin Attack & Sword Beam Effects and then the
  1144.    Spin Attack Charge Particles (This is the order they get allocated in when
  1145.    you charge a spin attack)
  1146.    
  1147.    """
  1148.    
  1149.     Spin_Attack_and_Sword_Beam_Effects = Actor(name='Spin Attack & Sword Beam Effects', Id='0035', size=452, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1150.    
  1151.     Allocate(Heap, Spin_Attack_and_Sword_Beam_Effects, Overlay_dict)
  1152.    
  1153.     Spin_Attack_Charge_Particles = Actor(name='Spin Attack Charge Particles', Id='007B', size=1367, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1154.    
  1155.     Allocate(Heap, Spin_Attack_Charge_Particles, Overlay_dict)
  1156.  
  1157.  
  1158.  
  1159.  
  1160. def Allocate_Gold_Skulltula_With_Hookshot(Heap, Room_Number, Overlay_dict):
  1161.    
  1162.     """
  1163.    
  1164.    This function allocates a gold skulltula (for example, if you shoot a skull-
  1165.    kid painting that reveals a gold skulltula, it allocates a gold skulltula)
  1166.    
  1167.    It first allocates an hookshot, then the gold skulltula, then deallocates the hookshot
  1168.    
  1169.    THIS FUNCTION HARDCODES THE PRIORITY OF THE GOLD SKULLTULA TO BE 5 BECAUSE
  1170.    I ONLY CARE ABOUT ROOM 3 OF OCEANSIDE SPIDERHOUSE
  1171.    
  1172.    """
  1173.    
  1174.     Gold_Skulltula = Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False)
  1175.    
  1176.     if Gold_Skulltula.room_number != 3:
  1177.         print("ERROR: Gold_Skulltula has room_number != 3 ?????? (Allocate_Gold_Skulltula() Error Message)")
  1178.    
  1179.    
  1180.     Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1181.    
  1182.     Allocate(Heap, Hookshot, Overlay_dict)
  1183.    
  1184.     Allocate(Heap, Gold_Skulltula, Overlay_dict)
  1185.    
  1186.     Deallocate(Heap, Hookshot, Overlay_dict)
  1187.  
  1188.  
  1189. def Allocate_Gold_Skulltula_With_Arrow(Heap, Room_Number, Overlay_dict):
  1190.    
  1191.     """
  1192.    
  1193.    This function allocates a gold skulltula (for example, if you shoot a skull-
  1194.    kid painting that reveals a gold skulltula, it allocates a gold skulltula)
  1195.    
  1196.    It first allocates an arrow, then the gold skulltula, then deallocates the arrow
  1197.    
  1198.    THIS FUNCTION HARDCODES THE PRIORITY OF THE GOLD SKULLTULA TO BE 5 BECAUSE
  1199.    I ONLY CARE ABOUT ROOM 3 OF OCEANSIDE SPIDERHOUSE
  1200.    
  1201.    """
  1202.    
  1203.     Gold_Skulltula = Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False)
  1204.    
  1205.     if Gold_Skulltula.room_number != 3:
  1206.         print("ERROR: Gold_Skulltula has room_number != 3 ?????? (Allocate_Gold_Skulltula() Error Message)")
  1207.    
  1208.    
  1209.     Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1210.    
  1211.     Allocate(Heap, Arrow, Overlay_dict)
  1212.    
  1213.     Allocate(Heap, Gold_Skulltula, Overlay_dict)
  1214.    
  1215.     Deallocate(Heap, Arrow, Overlay_dict)
  1216.    
  1217.  
  1218. def Kill_Gold_Skulltula(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
  1219.    
  1220.     """
  1221.    
  1222.    TODO: can implement this for more oceanside possibilties
  1223.    
  1224.    This function kills a gold skulltula to spawn a gold skulltula token
  1225.    WITHOUT using something that spawns an actor (like hookshot or an arrow)
  1226.    
  1227.    
  1228.    it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
  1229.    
  1230.    """
  1231.    
  1232.     if Gold_Skulltula.Id != '0050':
  1233.         print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula() Error Message)")
  1234.    
  1235.     Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
  1236.    
  1237.     Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
  1238.    
  1239.     Deallocate(Heap, Gold_Skulltula, Overlay_dict)
  1240.    
  1241.  
  1242. def Kill_Gold_Skulltula_With_Hookshot(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
  1243.    
  1244.     """
  1245.    
  1246.    TODO: can implement this for more oceanside possibilties
  1247.    
  1248.    This function kills a gold skulltula to spawn a gold skulltula token with hookshot
  1249.    
  1250.    
  1251.    it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
  1252.    
  1253.    """
  1254.    
  1255.     if Gold_Skulltula.Id != '0050':
  1256.         print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula_With_Hookshot() Error Message)")
  1257.    
  1258.     Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
  1259.    
  1260.     Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1261.    
  1262.     Allocate(Heap, Hookshot, Overlay_dict)
  1263.    
  1264.     Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
  1265.    
  1266.     Deallocate(Heap, Gold_Skulltula, Overlay_dict)
  1267.    
  1268.     Deallocate(Heap, Hookshot, Overlay_dict)
  1269.  
  1270.  
  1271. def Kill_Gold_Skulltula_With_Arrow(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
  1272.    
  1273.     """
  1274.    
  1275.    TODO: can implement this for more oceanside possibilties
  1276.    
  1277.    This function kills a gold skulltula to spawn a gold skulltula token with hookshot
  1278.    
  1279.    
  1280.    it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
  1281.    
  1282.    """
  1283.    
  1284.     if Gold_Skulltula.Id != '0050':
  1285.         print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula_With_Arrow() Error Message)")
  1286.    
  1287.     Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
  1288.    
  1289.     Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  1290.    
  1291.     Allocate(Heap, Arrow, Overlay_dict)
  1292.    
  1293.     Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
  1294.    
  1295.     Deallocate(Heap, Gold_Skulltula, Overlay_dict)
  1296.    
  1297.     Deallocate(Heap, Arrow, Overlay_dict)
  1298.  
  1299.    
  1300.  
  1301. """
  1302.  
  1303. Before proceeding, we should define all of the transitions we plan on passing through
  1304.  
  1305. Since "Beneath the Graveyard" is relatively simple and I currently only want to consider
  1306. passing through a single plane, I will just define Plane_1 to be the plane shared between
  1307. Room0 and Room1
  1308.  
  1309. This loading plane happens the be the second element in Room0_queue, so I will define it based on that
  1310.  
  1311. """
  1312.  
  1313. Plane_1 = Room0_queue[1]
  1314.  
  1315.  
  1316. Transition_List= [Plane_1]
  1317.  
  1318.  
  1319. """
  1320.  
  1321.    Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
  1322.    we want to attempt to use for superslide SRM where the keys are the grabbable
  1323.    actors and the values are lists with 3-bit strings where each bit means:
  1324.        
  1325.        100 : Possible to enter Plane with both Bomb and Smoke loaded
  1326.        010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
  1327.        001 : Possible to enter Plane with no Smoke loaded
  1328.    
  1329.    and Transitions, where the transitions are the ones you can superslide through
  1330.    
  1331.    
  1332.    
  1333. """
  1334.  
  1335. Grabbable_dict = {
  1336.         Room0_queue[6] : ['100', Plane_1],
  1337.         Room0_queue[7] : ['100', Plane_1],
  1338.         Room1_queue[25] : ['110', Plane_1],
  1339.         Room1_queue[26] : ['100', Plane_1],
  1340.         Room1_queue[27] : ['011', Plane_1]
  1341.         }
  1342.  
  1343.  
  1344. """
  1345.  
  1346. Below this we can consider a sequence of Room loads and then display the Heap
  1347.  
  1348. """
  1349.  
  1350.  
  1351. #Load_Scene(Heap, Room0)
  1352.  
  1353.  
  1354. #Load_Room(Heap, Room1, Plane_1, Overlay_dict)
  1355.  
  1356. #Load_Room(Heap, Room0, Plane_1, Overlay_dict)
  1357.  
  1358. #Load_Room(Heap, Room1, Plane_1, Overlay_dict)
  1359.  
  1360. #Load_Room(Heap, Room0, Plane_1, Overlay_dict)
  1361.  
  1362.  
  1363. #Display_Heap(Heap)
  1364.  
  1365. ###############################################################################
  1366. ###############################################################################
  1367. ###############################################################################
  1368. ###############################################################################
  1369. ###############################################################################
  1370. ###############################################################################
  1371.  
  1372.  
  1373. def Grabbable_In_Room(room, grabbable_actor_list):
  1374.    
  1375.     """
  1376.    
  1377.    This function checks the inputted room to see if it contains a grabbale actor
  1378.    that we can use for the superslide for SRM (in theory at least...)
  1379.    
  1380.    """
  1381.    
  1382.     grabbable_in_room = False
  1383.    
  1384.     for actor in room.priority_queue:
  1385.        
  1386.         if type(actor) == Actor and actor.Id in grabbable_actor_list:
  1387.            
  1388.             grabbable_in_room = True
  1389.    
  1390.     return grabbable_in_room
  1391.  
  1392.  
  1393. def Valid_Grabbable_In_Room(room, grabbable_actor_dict):
  1394.    
  1395.     """
  1396.    
  1397.    This function checks the inputted room to see if it contains a grabbale actor
  1398.    that we can use for the superslide for SRM
  1399.    
  1400.    """
  1401.    
  1402.     valid_grabbable_in_room = False
  1403.    
  1404.     for actor in room.priority_queue:
  1405.        
  1406.         if actor in grabbable_actor_dict.keys():
  1407.            
  1408.             valid_grabbable_in_room = True
  1409.    
  1410.     return valid_grabbable_in_room
  1411.  
  1412.  
  1413. def Chest_In_Room(room):
  1414.    
  1415.     """
  1416.    
  1417.    This function checks the inputted room to see if it contains a chest
  1418.    
  1419.    """
  1420.    
  1421.     chest_in_room = False
  1422.    
  1423.     for actor in room.priority_queue:
  1424.        
  1425.         if type(actor) == Actor and actor.Id == '0006':
  1426.            
  1427.             chest_in_room = True
  1428.    
  1429.     return chest_in_room
  1430.  
  1431.  
  1432. def Deku_Guard_In_Room(room):
  1433.    
  1434.     """
  1435.    
  1436.    This function checks the inputted room to see if it contains a Deku Guard
  1437.    
  1438.    """
  1439.    
  1440.     deku_guard_in_room = False
  1441.    
  1442.     for actor in room.priority_queue:
  1443.        
  1444.         if type(actor) == Actor and actor.Id == '017A':
  1445.            
  1446.             deku_guard_in_room = True
  1447.    
  1448.     return deku_guard_in_room
  1449.  
  1450.  
  1451. def Transition_List(room):
  1452.    
  1453.     """
  1454.    
  1455.    This function takes a room as input and returns a list of all of its transitions
  1456.    (i.e. doors/loading planes that lead to other rooms)
  1457.    
  1458.    """
  1459.    
  1460.     transition_list = []
  1461.    
  1462.     for actor in room.priority_queue:
  1463.        
  1464.         if actor.transition != False:
  1465.            
  1466.             transition_list.append(actor)
  1467.            
  1468.     return transition_list
  1469.    
  1470.  
  1471. def Shared_Transitions(room1, room2):
  1472.    
  1473.     """
  1474.    
  1475.    This function takes two Rooms as input and returns a list of their shared transitions
  1476.    (essentially returns the edges connecting these rooms if we view the rooms are nodes
  1477.    in a graph)
  1478.    
  1479.    """
  1480.    
  1481.     shared_transitions = []
  1482.    
  1483.     for transition in Transition_List(room1):
  1484.        
  1485.         if Is_Shared_Transition(transition, room1.number, room2.number) == True:
  1486.            
  1487.             shared_transitions.append(transition)
  1488.    
  1489.     return shared_transitions
  1490.  
  1491.  
  1492. def Shared_Transition_Exists(room1, room2):
  1493.    
  1494.     """
  1495.    
  1496.    This function takes two Rooms as input and returns True if they share a transition
  1497.    and False otherwise
  1498.    
  1499.    """
  1500.    
  1501.     shared_transition_exists = False
  1502.    
  1503.     for transition in Transition_List(room1):
  1504.        
  1505.         if Is_Shared_Transition(transition, room1.number, room2.number) == True:
  1506.            
  1507.             shared_transition_exists = True
  1508.    
  1509.     return shared_transition_exists
  1510.  
  1511.  
  1512. def Neighbors(room, Room_List):
  1513.    
  1514.     """
  1515.    
  1516.    This function takes a room as input along with a list of all potential rooms
  1517.    and returns a list of all rooms that share a transition with this room (excluding itself)
  1518.    
  1519.    """
  1520.    
  1521.     neighbors = []
  1522.    
  1523.     for ROOM in Room_List:
  1524.        
  1525.         if ROOM != room and Shared_Transition_Exists(room, ROOM) == True:
  1526.            
  1527.             neighbors.append(ROOM)
  1528.    
  1529.     return neighbors
  1530.    
  1531.  
  1532. def New_Room(room, transition, Room_List):
  1533.    
  1534.     """
  1535.    
  1536.    This function takes a room, a transition, and a list of all available rooms
  1537.    as input and returns the room that you would be in if you started in room
  1538.    and passed through transition
  1539.    
  1540.    """
  1541.    
  1542.     if transition not in Transition_List(room):
  1543.         print("ERROR: Invalid input into New_Room() function; transition is not in room")
  1544.        
  1545.     for ROOM in Room_List:
  1546.        
  1547.         if ROOM != room and (transition.transition[0] == ROOM.number or transition.transition[1] == ROOM.number) and ROOM.number != room.number:
  1548.            
  1549.             new_room = ROOM
  1550.    
  1551.     return new_room
  1552.  
  1553.    
  1554. def Current_Room(Room_Load_Permutation, Room_List):
  1555.    
  1556.     """
  1557.    
  1558.    Room_Load_Permutation is a list whose first element is the initial room that is started at
  1559.    
  1560.    All subsequent entries are transitions (Actor class objects with transition != False)
  1561.    
  1562.    
  1563.    Room_List is a list of all available Rooms
  1564.    
  1565.    
  1566.    This function returns what Room you would be in after entering every transition listed in
  1567.    the permutation, assuming that you start in the initial room
  1568.    
  1569.    """
  1570.    
  1571.     if type(Room_Load_Permutation[0]) != Room:
  1572.         print("ERROR: no initial room in permutation (Current_Room() function error message)")
  1573.    
  1574.     current_room = Room_Load_Permutation[0]
  1575.    
  1576.     if len(Room_Load_Permutation) > 1:
  1577.    
  1578.         for transition in Room_Load_Permutation[1:len(Room_Load_Permutation)]:
  1579.            
  1580.             current_room = New_Room(current_room, transition, Room_List)
  1581.    
  1582.     return current_room
  1583.  
  1584.  
  1585. def Room_Order_List(Room_Load_Permutation, Room_List):
  1586.    
  1587.     """
  1588.    
  1589.    Room_Load_Permutation is a list whose first element is the initial room that is started at
  1590.    
  1591.    All subsequent entries are transitions (Actor class objects with transition != False)
  1592.    
  1593.    
  1594.    Room_List is a list of all available Rooms
  1595.    
  1596.    
  1597.    This function returns a list of what Room you would be in at each step of
  1598.    entering transitions
  1599.    
  1600.    """
  1601.    
  1602.     if type(Room_Load_Permutation[0]) != Room:
  1603.         print("ERROR: no initial room in permutation (Get_Room_Load_List() function error message)")
  1604.    
  1605.     room_order_list = []
  1606.    
  1607.     for i in range(0, len(Room_Load_Permutation)):
  1608.        
  1609.         current_room = Current_Room(Room_Load_Permutation[0:i+1], Room_List)
  1610.        
  1611.         room_order_list.append(current_room)
  1612.    
  1613.     return room_order_list
  1614.  
  1615.  
  1616. def Generate_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
  1617.    
  1618.     """
  1619.    
  1620.    TODO: Debug this function... try calling: Generate_Room_Load_Permutations(Room0, Room_List, 1)
  1621.    
  1622.    
  1623.    This function seems to run for now, but it is untested for when we have multiple planes
  1624.    I will test this once I do Deku Palace input
  1625.    
  1626.    """
  1627.    
  1628.     """
  1629.    
  1630.    This function takes as input the initial room (Initial_Room) that the scene was loaded in
  1631.    the list of all Rooms we want to consider visiting (Room_List), and Max_Transition_Count
  1632.    which is the maximum number of times we want to allow ourselves to load a new room
  1633.    
  1634.    This function returns a list of all permutations of ways to enter new rooms after starting
  1635.    from the initial room (while limiting the number of room loads we do to be exactly Max_Transition_Count)
  1636.    where each permutation is a list in the form [Initial_Room, Transition1, Transition2, Transition3, ..., TransitionX]
  1637.    for X = Max_Transition_Count (so to get all permutations for X <= Max_Transition_Count, just
  1638.    use a for loop and call this function in each iteration of the foor loop and concatenate the lists)
  1639.    
  1640.    """
  1641.    
  1642.     if Max_Transition_Count == 0:
  1643.        
  1644.         new_permutation_list = [[Initial_Room]]
  1645.        
  1646.         return new_permutation_list
  1647.  
  1648.    
  1649.     else:
  1650.        
  1651.         new_permutation_list = []
  1652.         permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count - 1)
  1653.        
  1654.         for permutation in permutation_list:
  1655.             for room in Neighbors(Current_Room(permutation, Room_List), Room_List):
  1656.                 for transition in Shared_Transitions(Current_Room(permutation, Room_List), room):
  1657.                     new_permutation = copy(permutation)
  1658.                     new_permutation.append(transition)
  1659.                     #permutation_list.append(new_permutation)
  1660.                     new_permutation_list.append(new_permutation)
  1661.                    
  1662.         return new_permutation_list
  1663.  
  1664.  
  1665. def Generate_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
  1666.    
  1667.     """
  1668.    
  1669.    This function returns all permutations of ways to load a room starting from the initial room
  1670.    where the number of room loads is <= Max_Transition_Count
  1671.    
  1672.    """
  1673.    
  1674.     permutation_list = []
  1675.    
  1676.     for N in range(Max_Transition_Count):
  1677.        
  1678.         new_permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, N)
  1679.         permutation_list = permutation_list + new_permutation_list
  1680.    
  1681.     return permutation_list
  1682.  
  1683.  
  1684. def Generate_Almost_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
  1685.    
  1686.     """
  1687.    
  1688.    This function returns all permutations of ways to load a room starting from the initial room
  1689.    where the number of room loads is <= Max_Transition_Count
  1690.    
  1691.    this will always output a list with length at least 2, which is why it is different
  1692.    from Generate_All_Room_Load_Permutations
  1693.    
  1694.    """
  1695.    
  1696.     permutation_list = []
  1697.    
  1698.     for N in range(1, Max_Transition_Count):
  1699.        
  1700.         new_permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, N)
  1701.         permutation_list = permutation_list + new_permutation_list
  1702.    
  1703.     return permutation_list
  1704.  
  1705.  
  1706. def Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count):
  1707.    
  1708.     """
  1709.    
  1710.    This function returns all permutations of ways to traverse through rooms, starting
  1711.    from the initial room where the number of room loads is <= Max_Transition_Count
  1712.    
  1713.    The distinction between this and Generate_All_Room_Load_Permutations is that
  1714.    this will, instead of listing transitions, list the Room you're currently in
  1715.    at each step
  1716.    
  1717.    """
  1718.    
  1719.     room_order_permutation_list = []
  1720.    
  1721.     room_load_permutation_list = Generate_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count)
  1722.    
  1723.    
  1724.     iteration_count = 0
  1725.     for room_load_permutation in room_load_permutation_list:
  1726.        
  1727.         print("Generate_All_Room_Order_Lists: %d out of %d" %(iteration_count, len(room_load_permutation_list)))
  1728.         iteration_count += 1
  1729.        
  1730.         room_order_list = Room_Order_List(room_load_permutation, Room_List)
  1731.        
  1732.         room_order_permutation_list.append(room_order_list)
  1733.    
  1734.     return room_order_permutation_list
  1735.        
  1736.  
  1737. def Generate_Allocation_Permutations(allocation_list):
  1738.    
  1739.     """
  1740.    
  1741.    Whatever, I'm just hardcoding a list of all of the actor names I want to allow
  1742.    and then using itertools to make a list of all of the permutations
  1743.    
  1744.    """
  1745.    
  1746.     """
  1747.    
  1748.    TODO: Finish this function, also generalize it in the future
  1749.    
  1750.    """
  1751.    
  1752.     """
  1753.    
  1754.    THIS FUNCTION IS SIMPLIFIED AT THE MOMENT AND COULD BE IMPROVED TO GENERATE
  1755.    EVEN MORE POSSIBLE PERMUTATIONS
  1756.    
  1757.    allocation_list is a list of strings of things to allocate
  1758.    
  1759.    for example:
  1760.        
  1761.        allocation_list = [
  1762.        'Nothing',
  1763.        'Bomb',
  1764.        'Smoke',
  1765.        'Arrow',
  1766.        'Hookshot',
  1767.        'Charged Spin Attack',
  1768.        'Chu',
  1769.        'Zora Fins',
  1770.        'Fish',
  1771.        'Bugs'
  1772.        ]
  1773.    
  1774.    """
  1775.    
  1776.     allocation_permutation_list = []
  1777.    
  1778.    
  1779.     for i in range(len(allocation_list) + 1):
  1780.        
  1781.         print("Generate_Allocation_Permutations: %d out of %d" %(i, len(allocation_list)))
  1782.        
  1783.        
  1784.         Permutations = list(itertools.permutations(allocation_list, i))
  1785.        
  1786.         allocation_permutation_list = allocation_permutation_list + Permutations
  1787.    
  1788.     return allocation_permutation_list
  1789.  
  1790.  
  1791. def Clear_Instances(actor_id, room):
  1792.    
  1793.     """
  1794.    
  1795.    This function takes an actor_id and room as input and sets actor.cleared = True
  1796.    for all actors with actor.id == actor_id in room
  1797.    
  1798.    Call this before loading the scene or anything if you want some specific
  1799.    actor cleared already. For example, I'd call Clear_Instances('015B', Room1)
  1800.    to clear all of the bad bats in Beneath the Graveyard
  1801.    
  1802.    """
  1803.    
  1804.     for actor in room.priority_queue:
  1805.        
  1806.         if actor.Id == actor_id and actor.clearable == True:
  1807.            
  1808.             actor.cleared = True
  1809.  
  1810.  
  1811. def Clear_Instance(actor, room):
  1812.    
  1813.     """
  1814.    
  1815.    This function takes a specific actor in a room as input and sets
  1816.    actor.cleared = True
  1817.    
  1818.    """
  1819.    
  1820.     if actor.clearable == True:
  1821.        
  1822.         actor.cleared = True
  1823.  
  1824.  
  1825. def Generate_Deallocation_Combinations(room):
  1826.    
  1827.     """
  1828.    ##### Note: we actually get combinations instead of permutations because
  1829.    the order in which we deallocate actors doesn't matter
  1830.    
  1831.    This function returns a list of combinations (stored as tuples of Actors)
  1832.    
  1833.    
  1834.    
  1835.    Some things this (or maybe some other) function needs to account for:
  1836.        
  1837.        if any rupee from a rupee cluster is deallocated in a deallocation step,
  1838.        then clear the rupee cluster actor instance (00E8) [note that there is
  1839.        at most one rupee cluster instance in every room in the game, so there is
  1840.        no need to check which cluster the rupees are associated with]
  1841.        
  1842.        if all bad bats are deallocated on the same deallocation step, then they
  1843.        must all be cleared... actually, stronger: if all Category 5 actors with
  1844.        the same Id in a given room are deallocated on the same deallocation step,
  1845.        then clear all instances... actually this isn't good enough (need to add
  1846.        this into the input I believe or just treat bad bats as a special case)
  1847.        
  1848.    
  1849.    """
  1850.    
  1851.     deallocation_list = []
  1852.    
  1853.     for actor in room.priority_queue:
  1854.        
  1855.         if actor.cleared == False and actor.unloadable == True:
  1856.            
  1857.             deallocation_list.append(actor)
  1858.    
  1859.     ##### Now we have a list of all actors in room that we have the option of deallocationg
  1860.    
  1861.     ##### Now want want to generate a list of permutations
  1862.     ########## ACTUALLY, order doesn't matter for deallocation, so all combinations suffices
  1863.    
  1864.     combination_list = []
  1865.    
  1866.     for i in range(len(deallocation_list) + 1):
  1867.        
  1868.         Combinations = list(itertools.combinations(deallocation_list, i))
  1869.        
  1870.         combination_list = combination_list + Combinations
  1871.        
  1872.     return combination_list
  1873.  
  1874.  
  1875.  
  1876.  
  1877. def Build_Room_Deallocation_Combination_Graph(room_order_list):
  1878.    
  1879.    
  1880.     """
  1881.    
  1882.    This function takes a room_order_list as input (that is, a list in the form
  1883.    [initial_room, Room1, Room2, Room3, ..., RoomN] which describes the order we
  1884.    visit rooms in (note that Roomi could be equal to Roomj even for i =/= j)) and
  1885.    returns a dictionary where the keys are vertices whose values are lists of the
  1886.    other vertices that they are connected to. Each vertex represents a deallocation
  1887.    combination for the room that it corresponds to.
  1888.    
  1889.    If the edges are directed, then this can be viewed as a multitree with some
  1890.    dummy root vertex and then each generation corresponds to a Room.
  1891.    
  1892.    """
  1893.    
  1894.     room_count = 0
  1895.    
  1896.     #### Encode a dummy root node to make finding paths easier
  1897.     graph = {('root', room_count - 1) : []}
  1898.    
  1899.    
  1900.     iteration_count = 0
  1901.     ### for all rooms except for the last one
  1902.     for room in room_order_list[0:len(room_order_list)-1]:
  1903.        
  1904.         print("Build_Room_Deallocation_Combination_Graph: %d out of %d" %(iteration_count, len(room_order_list) - 1))
  1905.         iteration_count += 1
  1906.        
  1907.         combination_list = Generate_Deallocation_Combinations(room)
  1908.        
  1909.         for combination in combination_list:
  1910.            
  1911.             for key in graph.keys():
  1912.                
  1913.                 ### If the key is from the previous generation, then append every combination to its list
  1914.                 if key[1] == room_count - 1:
  1915.                    
  1916.                     graph[key].append(combination)
  1917.            
  1918.             graph[(combination, room_count)] = []
  1919.        
  1920.         room_count += 1
  1921.            
  1922.     return graph
  1923.  
  1924.  
  1925. def Find_Leaves(graph):
  1926.    
  1927.     """
  1928.    
  1929.    This function takes a graph (really a dictionary) created by Build_Room_Deallocation_Combination_Graph()
  1930.    and returns a list of all of its leaves
  1931.    
  1932.    """
  1933.    
  1934.     leaf_list = []
  1935.  
  1936.     for key in graph:
  1937.         # only leaves will point to empty lists
  1938.         if graph[key] == []:
  1939.             leaf_list.append(key)
  1940.    
  1941.     return leaf_list
  1942.  
  1943.  
  1944. def Find_All_Paths(graph, start, end, path=[]):
  1945.        
  1946.         """
  1947.        
  1948.        This function takes a graph (really a dictionary) and start and end vertices
  1949.        as input and returns a list of all paths from start to end
  1950.        
  1951.        TODO: maybe don't rely on hardcoding what the root's key is and instead write
  1952.        a function to find it (though hardcode is prob faster if you don't make mistakes)
  1953.        
  1954.        I will use this to find all paths from ('root', -1) [note that I am hardcoding
  1955.        this instead of just finding a root without any parent] to a given lead, and
  1956.        I will do this for all leafs (which I can get by doing Find_Leaves(graph))
  1957.        
  1958.        """
  1959.        
  1960.        
  1961.         path = path + [start]
  1962.         if start == end:
  1963.             return [path]
  1964.         if not (start in graph):
  1965.             return []
  1966.         paths = []
  1967.         for vertex in graph[start]:
  1968.             if vertex not in path:
  1969.                 newpaths = Find_All_Paths(graph, vertex, end, path)
  1970.                 for newpath in newpaths:
  1971.                     paths.append(newpath)
  1972.         return paths
  1973.  
  1974.  
  1975. def Find_All_Deallocation_Combination_Paths(graph):
  1976.    
  1977.     """
  1978.    
  1979.    TODO: Note that I hardcode what the key of the root vertex is: ('root', -1)
  1980.    
  1981.    This returns a list of all (n-1)-permutations of deallocation combinations
  1982.    for a given room_order_list (where we assume there are n rooms we travel to
  1983.    including the initial room). This gives us the thing we called D1
  1984.    
  1985.    """
  1986.    
  1987.     all_deallocation_combination_paths = []
  1988.    
  1989.     leaf_list = Find_Leaves(graph)
  1990.    
  1991.     iteration_count = 0
  1992.     for leaf in leaf_list:
  1993.        
  1994.         print("Find_All_Deallocation_Combination_Paths: %d out of %d" %(iteration_count, len(leaf_list)))
  1995.         iteration_count += 1
  1996.        
  1997.         # I hardcode the root key to be ('root', -1)
  1998.         path_to_leaf = Find_All_Paths(graph, ('root', -1), leaf)
  1999.        
  2000.         all_deallocation_combination_paths = all_deallocation_combination_paths + path_to_leaf
  2001.        
  2002.        
  2003.     ##### Since every key is a tuple in the form (combination, number), get rid of number part
  2004.     for path in all_deallocation_combination_paths:
  2005.         for vertex in path:
  2006.             path[path.index(vertex)] = vertex[0]
  2007.    
  2008.     return all_deallocation_combination_paths
  2009.  
  2010.  
  2011.  
  2012.  
  2013. def Generate_Action_Permutations(room_order_list, allocation_list):
  2014.    
  2015.     """
  2016.    
  2017.    THIS IS THE FUNCTION THAT FINALLY GIVES US ALL OF THE PERMUTATIONS OF THINGS
  2018.    TO DO FOR A GIVEN room_order_list and the allocation_list.
  2019.    
  2020.    
  2021.    
  2022.    WE WILL RUN THIS FUNCTION ON EVERY PERMUTATION OF ROOM ORDER LISTS USING
  2023.    Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count)
  2024.    
  2025.    
  2026.    ONCE WE DO THAT WE WILL HAVE EVERY SINGLE PERMUTATION THAT WE WANT TO TEST
  2027.    
  2028.    """
  2029.    
  2030.     allocation_permutations = Generate_Allocation_Permutations(allocation_list)
  2031.    
  2032.     ##### Now we want all (n-1)-permutations of allocation permutations
  2033.     A1 = list(itertools.permutations(allocation_permutations, len(room_order_list) - 1))
  2034.    
  2035.     #### deallocation combination graph
  2036.     graph = Build_Room_Deallocation_Combination_Graph(room_order_list)
  2037.    
  2038.     D1 = Find_All_Deallocation_Combination_Paths(graph)
  2039.    
  2040.     ###########################################################################
  2041.    
  2042.     # create output list o
  2043.     o = []
  2044.     for i in range(len(A1)):
  2045.        
  2046.         print("Generate_Action_Permutations: %d out of %d" %(i, len(A1)))
  2047.        
  2048.         for j in range(len(D1)):
  2049.             for b in range(2**(len(room_order_list) - 1)):
  2050.                 # create new empty list p
  2051.                 p = []
  2052.                 for k in range(len(room_order_list) - 1):
  2053.                     p.append(room_order_list[k])
  2054.                    
  2055.                     if bin(b)[2:].zfill(len(room_order_list)-1) == 1:
  2056.                        
  2057.                         # add each element of A1[i][k] to p
  2058.                         for element in A1[i][k]:
  2059.                             p.append(element)
  2060.                         # add each element of D1[j][k] to p
  2061.                         for element in D1[j][k]:
  2062.                             p.append(element)
  2063.                            
  2064.                     elif bin(b)[2:].zfill(len(room_order_list)-1) == 0:
  2065.                        
  2066.                         # add each element of D1[j][k] to p
  2067.                         for element in D1[j][k]:
  2068.                             p.append(element)
  2069.                         # add each element of A1[i][k] to p
  2070.                         for element in A1[i][k]:
  2071.                             p.append(element)
  2072.                
  2073.                 # Add the last room to p
  2074.                 p.append(room_order_list[len(room_order_list)-1])
  2075.                 # append p to o
  2076.                 o = o + p
  2077.    
  2078.     return o
  2079.  
  2080.  
  2081.  
  2082. def Generate_Heap_Permutations(Initial_Room, Room_List, Max_Transition_Count, allocation_list):
  2083.    
  2084.     """
  2085.    
  2086.    This function takes the initial room, the Room List, the Maximum Number of Transitions
  2087.    that we want to allow, and the allocation list as input and returns every permutation
  2088.    for heap manip setups to try (possibilities currently mostly limited by allocation_list)
  2089.    
  2090.    WE WILL USE THIS FUNCTION IN THE HEAP MANIP SOLVER
  2091.    
  2092.    """
  2093.    
  2094.     heap_permutations = []
  2095.    
  2096.     All_Room_Order_Lists = Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count)
  2097.    
  2098.     iteration_count= 0
  2099.     for room_order_list in All_Room_Order_Lists:
  2100.        
  2101.         print("Iteration %d out of %d" %(iteration_count, len(All_Room_Order_Lists)))
  2102.        
  2103.         action_permutations = Generate_Action_Permutations(room_order_list, allocation_list)
  2104.        
  2105.         heap_permutations = heap_permutations + action_permutations
  2106.        
  2107.         iteration_count += 1
  2108.    
  2109.    
  2110.     print("HEAP PERMUTATION GENERATION COMPLETE")
  2111.    
  2112.     return heap_permutations
  2113.        
  2114.    
  2115.  
  2116. ###############################################################################
  2117. ###############################################################################
  2118. ###############################################################################
  2119. ###############################################################################
  2120. ###############################################################################
  2121. ###############################################################################
  2122. ###############################################################################
  2123.    
  2124. def Actor_Is_In_Heap(Heap, actor):
  2125.    
  2126.     """
  2127.    
  2128.    actor is the Actor that we want to check for
  2129.    
  2130.    This function will return True if this Actor is in the Heap and False otherwise
  2131.    
  2132.    """
  2133.    
  2134.     actor_is_in_heap = False
  2135.    
  2136.     for entry in Heap:
  2137.        
  2138.         if type(entry) == Actor and entry == actor:
  2139.            
  2140.             actor_is_in_heap = True
  2141.    
  2142.     return actor_is_in_heap
  2143.  
  2144. def Actor_Is_In_Room(room, actor):
  2145.        
  2146.     """
  2147.    
  2148.    actor is the Actor that we want to check for
  2149.    
  2150.    This function will return True if this Actor is in the room and False otherwise
  2151.    
  2152.    """
  2153.    
  2154.     actor_is_in_room = False
  2155.    
  2156.     for entry in room.priority_queue:
  2157.        
  2158.         if type(entry) == Actor and entry == actor:
  2159.            
  2160.             actor_is_in_room = True
  2161.            
  2162.     return actor_is_in_room
  2163.  
  2164.  
  2165.  
  2166. def Bomb_And_Smoke_Superslide(Heap, Room_Number, Overlay_dict):
  2167.    
  2168.     """
  2169.    
  2170.    This function allocates a bomb, then allocates smoke (this happens when the bomb explodes)
  2171.    
  2172.    """
  2173.    
  2174.     Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  2175.    
  2176.     Allocate(Heap, Bomb, Overlay_dict)
  2177.    
  2178.     Smoke = Actor(name='Smoke', Id='00A2', size=11908, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
  2179.    
  2180.     Allocate(Heap, Smoke, Overlay_dict)
  2181.    
  2182.  
  2183.  
  2184.  
  2185.  
  2186. def Copy_Room_List(Room_List):
  2187.    
  2188.     """
  2189.    
  2190.    This function takes a list of all Rooms, Room_List, as input
  2191.    and returns a list of copies of all of the Rooms in Room_List
  2192.    
  2193.    """
  2194.    
  2195.     ##### First we want a list of all shared entries between the Room priority queues
  2196.    
  2197.     shared_actor_list = []
  2198.    
  2199.     for room1 in Room_List:
  2200.         for room2 in Room_List:
  2201.            
  2202.             if room2 != room1:
  2203.                
  2204.                 for actor1 in room1.priority_queue:
  2205.                     for actor2 in room2.priority_queue:
  2206.                         if (actor1 == actor2) and (actor1 not in shared_actor_list):
  2207.                            
  2208.                             shared_actor_list.append(actor1)
  2209.                            
  2210.     ##### Now make a list of copies of each entry of the above list
  2211.    
  2212.     shared_actor_copy_list = []
  2213.     for actor in shared_actor_list:
  2214.         shared_actor_copy_list.append(copy(actor))
  2215.    
  2216.     Room_List_Copy = []
  2217.    
  2218.     for room in Room_List:
  2219.        
  2220.         priority_queue_copy = []
  2221.        
  2222.         for actor in room.priority_queue:
  2223.            
  2224.             if actor not in shared_actor_list:
  2225.                
  2226.                 priority_queue_copy.append(copy(actor))
  2227.                
  2228.             elif actor in shared_actor_list:
  2229.                 append_count = 0
  2230.                 for actor2 in shared_actor_copy_list:
  2231.                    
  2232.                     # If all attributes of the actor and the copy are the same, then assume they are copies of each other
  2233.                     if actor2.name == actor.name and actor2.Id == actor.Id and actor2.size == actor.size and actor2.category == actor.category and actor2.overlay_type == actor.overlay_type and actor2.unloadable == actor.unloadable and actor2.address == actor.address and actor2.room_number == actor.room_number and actor2.priority == actor.priority and actor2.from_spawner == actor.from_spawner and actor2.transition == actor.transition and actor2.clearable == actor.clearable and actor2.cleared == actor.cleared:
  2234.                         # append the copy  
  2235.                         priority_queue_copy.append(actor2)
  2236.                         append_count += 1
  2237.                        
  2238.                         if append_count > 1:
  2239.                             print("ERROR: There were two or more copies of the same Actor in shared_actor_copy_list (Copy_Room_List() error message)")
  2240.        
  2241.        
  2242.         room_copy = Room(number=room.number, priority_queue=priority_queue_copy, clock_exists=room.clock_exists, clock_priority=room.clock_priority)
  2243.        
  2244.         Room_List_Copy.append(room_copy)
  2245.    
  2246.     return Room_List_Copy
  2247.  
  2248.  
  2249.  
  2250.  
  2251. def Main_Actor_Attributes_Match(actor1, actor2):
  2252.    
  2253.     """
  2254.    
  2255.    This function returns True is the two Actors taken as input have the same
  2256.    values for all of their main attributes and False otherwise
  2257.    
  2258.    the main attributes do not include things like "address" and such that can
  2259.    change as the state updates
  2260.    
  2261.    """
  2262.    
  2263.     main_actor_attributes_match = False
  2264.    
  2265.     if actor1.name == actor2.name and actor1.Id == actor2.Id and actor1.size == actor2.size and actor1.category == actor2.category and actor1.overlay_type == actor2.overlay_type and actor1.unloadable == actor2.unloadable and actor1.room_number is actor2.room_number and actor1.priority is actor2.priority and actor1.from_spawner == actor2.from_spawner and actor1.transition == actor2.transition and actor1.clearable == actor2.clearable:
  2266.         main_actor_attributes_match = True
  2267.    
  2268.     return main_actor_attributes_match
  2269.  
  2270.  
  2271. def Main_Overlay_Attributes_Match(overlay1, overlay2):
  2272.    
  2273.     main_overlay_attributes_match = False
  2274.    
  2275.     if overlay1.Id == overlay2.Id and overlay1.size == overlay2.size:
  2276.         main_overlay_attributes_match = True
  2277.    
  2278.     return main_overlay_attributes_match
  2279.    
  2280.  
  2281. def Copy_Overlay_Dict(Overlay_Dict):
  2282.    
  2283.     overlay_dict_copy = {}
  2284.    
  2285.     for key in Overlay_Dict:
  2286.         overlay_dict_copy[key] = copy(Overlay_Dict[key])
  2287.    
  2288.     return overlay_dict_copy
  2289.        
  2290.  
  2291. def Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy):
  2292.    
  2293.     """
  2294.    
  2295.    This function takes the Heap as input and returns a copy of the Heap where
  2296.    every actor copy in the Heap copy is the same class instance as each corresponding
  2297.    actor in the room list copy priority queues (same for Overlay_Dict_Copy)
  2298.    
  2299.    """
  2300.    
  2301.     Heap_Copy = []
  2302.    
  2303.     for entry in Heap:
  2304.        
  2305.         entry_allocated = False
  2306.         not_allocated_count = 0
  2307.         while entry_allocated is False:
  2308.            
  2309.             if not_allocated_count > 4:
  2310.                 print("UHHHHHHHHHHHHHHHHHHHHHHHH (Copy_Heap() Error Message)")
  2311.        
  2312.             if type(entry) == Node:
  2313.                
  2314.                 Heap_Copy.append(copy(entry))
  2315.                 entry_allocated = True
  2316.                
  2317.             elif type(entry) == Overlay:
  2318.                
  2319.                 for key in Overlay_Dict_Copy:
  2320.                     if Main_Overlay_Attributes_Match(Overlay_Dict_Copy[key], entry) == True:
  2321.                         Heap_Copy.append(Overlay_Dict_Copy[key])
  2322.                         entry_allocated = True
  2323.            
  2324.             elif type(entry) == Actor:
  2325.                
  2326.                 allocated_count = 0
  2327.                 for room in Room_List_Copy:
  2328.                    
  2329.                     if entry_allocated == True:
  2330.                         break
  2331.                    
  2332.                     for actor in room.priority_queue:
  2333.                        
  2334.                         if allocated_count > 1:
  2335.                             print("ERROR: tried to allocate multiple copies (Copy_Heap() Error Message)")
  2336.                        
  2337.                         if Main_Actor_Attributes_Match(entry, actor) == True:
  2338.                             Heap_Copy.append(actor)
  2339.                             allocated_count += 1
  2340.                             entry_allocated = True
  2341.                             break
  2342.                
  2343.                 # If it isn't in any of the priority queues, then it must be something you spawned
  2344.                 if entry_allocated == False:
  2345.                     Heap_Copy.append(copy(entry))
  2346.                     entry_allocated = True
  2347.                
  2348.             else:
  2349.                 print("ERROR: entry in Heap is not an Actor, Node, or Overlay (Copy_Heap() error message)")
  2350.            
  2351.             not_allocated_count += 1
  2352.     return Heap_Copy
  2353.  
  2354.  
  2355. def Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy):
  2356.    
  2357.     """
  2358.    
  2359.    This function takes the Grabbable_Dict as input and returns a copy of the it where
  2360.    each transition in it is a the same Actor class instance copy as the ones used in
  2361.    the priority queues of the Rooms in Room_List_Copy
  2362.    
  2363.    """
  2364.    
  2365.     grabbable_dict_copy = {}
  2366.    
  2367.     for pot in Grabbable_Dict:
  2368.        
  2369.         pot_in_dict = False
  2370.  
  2371.            
  2372.         for room in Room_List_Copy:
  2373.             if pot_in_dict == True:
  2374.                 break
  2375.             for actor in room.priority_queue:
  2376.                 if Main_Actor_Attributes_Match(pot, actor) == True:
  2377.                    
  2378.                     key = actor
  2379.                    
  2380.                     for room1 in Room_List_Copy:
  2381.                         if pot_in_dict == True:
  2382.                             break
  2383.                         for actor1 in room1.priority_queue:
  2384.                            
  2385.                             # Finding the transition
  2386.                             if Main_Actor_Attributes_Match(Grabbable_Dict[pot][1], actor1):
  2387.                                
  2388.                                 grabbable_dict_copy[key] = [Grabbable_Dict[pot][0], actor1]
  2389.                                 pot_in_dict = True
  2390.                                    
  2391.     return grabbable_dict_copy
  2392.    
  2393.  
  2394. def Find_Actor_Copy(actor, Room_List_Copy):
  2395.    
  2396.     """
  2397.    
  2398.    This function takes an Actor as input (actor) and a copy of the list of rooms
  2399.    (Room_List_Copy) and returns the copy of the inputted actor that is found in
  2400.    the priority queue of a Room in Room_List_Copy
  2401.    
  2402.    """
  2403.    
  2404.     actor_copy = None
  2405.    
  2406.     copy_found = False
  2407.     for room in Room_List_Copy:
  2408.         if copy_found == True:
  2409.             break
  2410.         for actor1 in room.priority_queue:
  2411.             if Main_Actor_Attributes_Match(actor1, actor):
  2412.                 actor_copy = actor1
  2413.                 copy_found = True
  2414.                 break
  2415.    
  2416.     return actor_copy
  2417.            
  2418.  
  2419. """
  2420.  
  2421. TODO: Make the solver take the initial heap layout as input so that it is easy
  2422. to test successive heap manip setups in the future
  2423.  
  2424. DO NOT FORGET TO CLEAR ALL OF THE BAD BATS IF YOU THINK THAT THAT IS SOMETHING
  2425. THAT YOU WANT TO DO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2426.  
  2427. ALSO IGNORE THAT FUNCTION BELOW, COMPLETELY REWRITE FROM SCRATCH BUT MAYBE READ
  2428. IT FIRST TO SEE IF IT REMINDS YOU OF ANY IDEAS YOU HAD
  2429.  
  2430. """
  2431.  
  2432.  
  2433. def Randomized_Solver(Initial_Room, Room_List, Max_Transition_Count, allocation_list_dict, Grabbable_Dict, Overlay_Dict, filename, Offset_List, Initial_Heap):
  2434.    
  2435.     """
  2436.    
  2437.    This function does not currently account for the possibility that you might need to break
  2438.    another pot in order to superslide off of a given pot. While this might not be strictly
  2439.    true for the pot we currently use in deku palace, it would be good at add more information
  2440.    to Grabbable_Dict to account for this
  2441.    
  2442.    """
  2443.    
  2444.     """
  2445.    
  2446.    Okay, the Initial_Heap argument will not work as I initially intended because of things
  2447.    like rupee clusters being cleared, etc. So if I want to test a Heap from an initial Heap
  2448.    distribution, then I will have to hardcode it to perform the necessary steps to get to it each time
  2449.    
  2450.    """
  2451.    
  2452.     """
  2453.    
  2454.    filename is the complete name (i.e. including the path) that we want to write to
  2455.    
  2456.    This function will randomly choose solutions to test (it may have repeats)
  2457.    
  2458.    Offset_List is a list of offsets that we want to check for. The grabbable object (e.g. a pot)
  2459.    will be first when calculating the offset. So if doing chest SRM, we want
  2460.    pot - chest = 0x160 or pot - chest = 0x1F0, so we want Offset_List = [0x160, 0x1F0]
  2461.    We make this Offset_List by default
  2462.    
  2463.    Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
  2464.    we want to attempt to use for superslide SRM where the keys are the grabbable
  2465.    actors and the values are 3-bit strings where each bit means:
  2466.        
  2467.        100 : Possible to enter Plane with both Bomb and Smoke loaded
  2468.        010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
  2469.        001 : Possible to enter Plane with no Smoke loaded
  2470.    
  2471.    """
  2472.    
  2473.     angle_solution_count = 0
  2474.     position_solution_count = 0
  2475.     permutation_count = 0
  2476.    
  2477.     ### Keep doing this forever (infinite loop so we keep trying new permutations)
  2478.     while True:
  2479.        
  2480.         all_room_load_lists = Generate_Almost_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count)
  2481.        
  2482.         for room_load_list in all_room_load_lists:
  2483.            
  2484.             if permutation_count%500 == 0:
  2485.                 print("%d Permutations Tested     %d Angle Solutions     %d Position Solutions" %(permutation_count, angle_solution_count, position_solution_count))
  2486.             permutation_count += 1
  2487.            
  2488.             Heap = copy(Initial_Heap)
  2489.            
  2490.             ##### Initialize the actor addresses and other attributes each time
  2491.        
  2492.             for room in Room_List:
  2493.                
  2494.                 for actor in room.priority_queue:
  2495.                    
  2496.                     actor.address = 0
  2497.                     actor.cleared = False
  2498.                    
  2499.                     ##### Clear all bad bats (optional, but I want to do this for beneath the graveyard)
  2500.                     Clear_Instances('015B', room)
  2501.             ###################################################################
  2502.            
  2503.             #####
  2504.             ##### Perform seuqence of steps here if you want to initialize your heap to something
  2505.             #####
  2506.            
  2507.             Load_Scene(Heap, Room_List[0], Overlay_Dict)
  2508.             Allocate_Hookshot(Heap, 0, Overlay_Dict) # 0 is the room_number of Room0
  2509.             Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[1], Overlay_Dict)
  2510.             Allocate_Bomb(Heap, 1, Overlay_Dict) # 1 is the room_number of Room1
  2511.             Allocate_Bomb(Heap, 1, Overlay_Dict) # 1 is the room_number of Room1
  2512.             Allocate_Charged_Spin_Attack(Heap, 1, Overlay_Dict) # 1 is the room_number of Room1
  2513.             Load_Room(Heap, Room_List[0], Room_List[0].priority_queue[1], Overlay_Dict)
  2514.             Allocate_Charged_Spin_Attack(Heap, 0, Overlay_Dict)
  2515.             Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[1], Overlay_Dict)
  2516.             Allocate_Smoke(Heap, 1, Overlay_Dict) # superslide with smoke still allocated
  2517.             Load_Room(Heap, Room_List[0], Room_List[0].priority_queue[1], Overlay_Dict)
  2518.             Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[1], Overlay_Dict)
  2519.            
  2520.             ###################################################################
  2521.            
  2522.            
  2523.             # We will use this to collect things we do in the permutation to help output the solution
  2524.             action_list = []
  2525.            
  2526.             room_count = 0
  2527.             # NOTE: the first "transition" is actually not a transition; it is the initial room
  2528.             for transition in room_load_list[0:len(room_load_list)-1]:
  2529.                
  2530.                 room = Current_Room(room_load_list[0:room_count + 1], Room_List)
  2531.                
  2532.                 # If this is the Initial_Room AND the Heap is empty, then we want to load the scene
  2533.                 if (room_count is 0) and (len(Heap) == 2):
  2534.                    
  2535.                     if room != Initial_Room:
  2536.                         print("ERROR: first entry in room_load_list is not Initial_Room (Randomnized_Solver() Error Message)")
  2537.                    
  2538.                     Load_Scene(Heap, Initial_Room, Overlay_Dict)
  2539.                     action_list.append("Load Scene: Room %d" %(Initial_Room.number))
  2540.                    
  2541.                     ##### NOW WE DO DEALLOCATION/ALLOCATION STEPS AFTER LOADING THE SCENE
  2542.                    
  2543.                    
  2544.                     """
  2545.                    
  2546.                    Now randomly (with some chosen distribution) choose things to allocate
  2547.                    and/or things to deallocate (in your current room). Make it so that
  2548.                    you can only choose a specific action once. For example, if allocation_list
  2549.                    has ['bomb', 'bomb, 'bomb', 'fish'] in it, then make it so you can only use
  2550.                    fish once, but you can use bomb 3 times
  2551.                    
  2552.                    Somehow try to encode that hookshot/charged spin are mutually exclusive
  2553.                    and that if either of them exist then they must be the last action
  2554.                    
  2555.                    Allow yourself to deallocate things before allocating things even
  2556.                    though it might be impossible or slow in some cases
  2557.                    
  2558.                    """
  2559.                    
  2560.                     # Do a coinflip to decide between allocating or deallocating first
  2561.                     #decision_coin_flip = np.random.uniform(0,1)
  2562.                     ##### Deterministically do deallocation step first
  2563.                     decision_coin_flip = 0
  2564.                    
  2565.                     # With probability 1/2, we allocate first and deallocate second
  2566.                     # if we allocate first, don't allow 'Charged Spin Attack'
  2567.                     if decision_coin_flip > .5:
  2568.                        
  2569.                         explosive_count = 0
  2570.                         droppable_count = 0
  2571.                        
  2572.                         ##### ALLOCATION
  2573.                         for action in allocation_list_dict[room.number]:
  2574.                            
  2575.                             # whether or not we add an action is based off of this
  2576.                             coin_flip = np.random.uniform(0,1)
  2577.                            
  2578.                             if action == 'Smoke' and coin_flip > .5:
  2579.                                
  2580.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  2581.                                 action_list.append("Allocate: Smoke")
  2582.                                
  2583.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  2584.                                
  2585.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  2586.                                 action_list.append("Allocate: Chu")
  2587.                                 explosive_count += 1
  2588.                                
  2589.                             elif action == 'Arrow' and coin_flip > .5:
  2590.                                
  2591.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  2592.                                 action_list.append("Allocate: Arrow")
  2593.                            
  2594.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  2595.                                
  2596.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  2597.                                 action_list.append("Allocate: Bomb")
  2598.                                 explosive_count += 1
  2599.                                
  2600.                             elif action == 'Zora Fins' and coin_flip > .5:
  2601.                                
  2602.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  2603.                                 action_list.append("Allocate: Zora Fins")
  2604.                            
  2605.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  2606.                                
  2607.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  2608.                                 action_list.append("Allocate: Fish")
  2609.                                 droppable_count += 1
  2610.                                
  2611.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  2612.                                
  2613.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  2614.                                 action_list.append("Allocate: Bugs")
  2615.                                 droppable_count += 1
  2616.                            
  2617.                             elif action == 'Hookshot' and coin_flip > .5:
  2618.                                
  2619.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  2620.                                 action_list.append("Allocate: Hookshot")
  2621.                            
  2622.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  2623.                                
  2624.                                 projectile_coin_flip = np.random.uniform(0,1)
  2625.                                
  2626.                                 if projectile_coin_flip > .5:
  2627.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  2628.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  2629.                                    
  2630.                                 elif projectile_coin_flip <= .5:
  2631.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  2632.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  2633.                                    
  2634.                             ### We don't include 'Charged Spin Attack' in this
  2635.                        
  2636.                         ##### DEALLOCATION
  2637.                         for actor in room.priority_queue:
  2638.                            
  2639.                             # whether or not we deallocate an actor is based off of this
  2640.                             coin_flip = np.random.uniform(0,1)
  2641.                            
  2642.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  2643.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  2644.                                
  2645.                                
  2646.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  2647.                                    
  2648.                                     Deallocate(Heap, actor, Overlay_Dict)
  2649.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  2650.                                     Clear_Instances('00E8', room)
  2651.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2652.                                
  2653.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  2654.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  2655.                                    
  2656.                                     table_bonk_deallocation_count = 0
  2657.                                     for entry in Heap:
  2658.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  2659.                                             Deallocate(Heap, entry, Overlay_Dict)
  2660.                                             table_bonk_deallocation_count += 1
  2661.                                    
  2662.                                     for entry in Heap:
  2663.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  2664.                                             Deallocate(Heap, entry, Overlay_Dict)
  2665.                                             table_bonk_deallocation_count += 1
  2666.                                            
  2667.                                     for entry in Heap:
  2668.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  2669.                                             Deallocate(Heap, entry, Overlay_Dict)
  2670.                                             table_bonk_deallocation_count += 1
  2671.                                    
  2672.                                     if table_bonk_deallocation_count != 3:
  2673.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  2674.                                    
  2675.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  2676.                                
  2677.                                
  2678.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  2679.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  2680.                                    
  2681.                                     Deallocate(Heap, actor, Overlay_Dict)
  2682.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2683.                                     # CLEAR THE ACTOR
  2684.                                     Clear_Instance(actor, room)
  2685.                                    
  2686.                                 else:
  2687.                                    
  2688.                                     Deallocate(Heap, actor, Overlay_Dict)
  2689.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2690.                        
  2691.                    
  2692.                     # With probability 1/2, we deallocate first and allocate second
  2693.                     elif decision_coin_flip <= .5:
  2694.                    
  2695.                         explosive_count = 0
  2696.                         droppable_count = 0
  2697.                         hookshot_exists = False
  2698.                        
  2699.                         ##### DEALLOCATION
  2700.                         for actor in room.priority_queue:
  2701.                            
  2702.                             # whether or not we deallocate an actor is based off of this
  2703.                             coin_flip = np.random.uniform(0,1)
  2704.                            
  2705.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  2706.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  2707.                                
  2708.                                
  2709.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  2710.                                    
  2711.                                     Deallocate(Heap, actor, Overlay_Dict)
  2712.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  2713.                                     Clear_Instances('00E8', room)
  2714.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2715.                                
  2716.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  2717.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  2718.                                    
  2719.                                     table_bonk_deallocation_count = 0
  2720.                                     for entry in Heap:
  2721.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  2722.                                             Deallocate(Heap, entry, Overlay_Dict)
  2723.                                             table_bonk_deallocation_count += 1
  2724.                                    
  2725.                                     for entry in Heap:
  2726.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  2727.                                             Deallocate(Heap, entry, Overlay_Dict)
  2728.                                             table_bonk_deallocation_count += 1
  2729.                                            
  2730.                                     for entry in Heap:
  2731.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  2732.                                             Deallocate(Heap, entry, Overlay_Dict)
  2733.                                             table_bonk_deallocation_count += 1
  2734.                                    
  2735.                                     if table_bonk_deallocation_count != 3:
  2736.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  2737.                                    
  2738.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  2739.                                
  2740.                                
  2741.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  2742.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  2743.                                    
  2744.                                     Deallocate(Heap, actor, Overlay_Dict)
  2745.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2746.                                     # CLEAR THE ACTOR
  2747.                                     Clear_Instance(actor, room)
  2748.                                    
  2749.                                 else:
  2750.                                    
  2751.                                     Deallocate(Heap, actor, Overlay_Dict)
  2752.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2753.                        
  2754.  
  2755.                         ##### ALLOCATION
  2756.                         for action in allocation_list_dict[room.number]:
  2757.                            
  2758.                             # whether or not we add an action is based off of this
  2759.                             coin_flip = np.random.uniform(0,1)
  2760.                            
  2761.                             if action == 'Smoke' and coin_flip > .5:
  2762.                                
  2763.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  2764.                                 action_list.append("Allocate: Smoke")
  2765.                                
  2766.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  2767.                                
  2768.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  2769.                                 action_list.append("Allocate: Chu")
  2770.                                 explosive_count += 1
  2771.                                
  2772.                             elif action == 'Arrow' and coin_flip > .5:
  2773.                                
  2774.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  2775.                                 action_list.append("Allocate: Arrow")
  2776.                            
  2777.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  2778.                                
  2779.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  2780.                                 action_list.append("Allocate: Bomb")
  2781.                                 explosive_count += 1
  2782.                                
  2783.                             elif action == 'Zora Fins' and coin_flip > .5:
  2784.                                
  2785.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  2786.                                 action_list.append("Allocate: Zora Fins")
  2787.                            
  2788.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  2789.                                
  2790.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  2791.                                 action_list.append("Allocate: Fish")
  2792.                                 droppable_count += 1
  2793.                                
  2794.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  2795.                                
  2796.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  2797.                                 action_list.append("Allocate: Bugs")
  2798.                                 droppable_count += 1
  2799.                            
  2800.                             elif action == 'Hookshot' and coin_flip > .5:
  2801.                                
  2802.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  2803.                                 action_list.append("Allocate: Hookshot")
  2804.                                 hookshot_exists = True
  2805.                                
  2806.                             elif action == 'Charged Spin Attack' and (hookshot_exists is False) and coin_flip > .5:
  2807.                                
  2808.                                 Allocate_Charged_Spin_Attack(Heap, room.number, Overlay_Dict)
  2809.                                 action_list.append("Allocate: Charged Spin Attack")
  2810.                                
  2811.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  2812.                                
  2813.                                 projectile_coin_flip = np.random.uniform(0,1)
  2814.                                
  2815.                                 if projectile_coin_flip > .5:
  2816.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  2817.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  2818.                                    
  2819.                                 elif projectile_coin_flip <= .5:
  2820.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  2821.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  2822.                
  2823.                 elif room_count == 0 and len(Heap) > 2:
  2824.                    
  2825.                     """
  2826.                    
  2827.                    In this case we are assuming that we are starting after a specific
  2828.                    sequence of actions has taken place and thus the Room that we are
  2829.                    in is already loaded, so we don't want to load the Room. All we want
  2830.                    to do is perform deallocation/allocation steps
  2831.                    
  2832.                    """
  2833.                    
  2834.                    
  2835.                     """
  2836.                    
  2837.                    Now randomly (with some chosen distribution) choose things to allocate
  2838.                    and/or things to deallocate (in your current room). Make it so that
  2839.                    you can only choose a specific action once. For example, if allocation_list
  2840.                    has ['bomb', 'bomb, 'bomb', 'fish'] in it, then make it so you can only use
  2841.                    fish once, but you can use bomb 3 times
  2842.                    
  2843.                    Somehow try to encode that hookshot/charged spin are mutually exclusive
  2844.                    and that if either of them exist then they must be the last action
  2845.                    
  2846.                    Allow yourself to deallocate things before allocating things even
  2847.                    though it might be impossible or slow in some cases
  2848.                    
  2849.                    """
  2850.                    
  2851.                     # Do a coinflip to decide between allocating or deallocating first
  2852.                     #decision_coin_flip = np.random.uniform(0,1)
  2853.                     ##### Deterministically do deallocation step first
  2854.                     decision_coin_flip = 0
  2855.                    
  2856.                     # With probability 1/2, we allocate first and deallocate second
  2857.                     # if we allocate first, don't allow 'Charged Spin Attack'
  2858.                     if decision_coin_flip > .5:
  2859.                        
  2860.                         explosive_count = 0
  2861.                         droppable_count = 0
  2862.                        
  2863.                         ##### ALLOCATION
  2864.                         for action in allocation_list_dict[room.number]:
  2865.                            
  2866.                             # whether or not we add an action is based off of this
  2867.                             coin_flip = np.random.uniform(0,1)
  2868.                            
  2869.                             if action == 'Smoke' and coin_flip > .5:
  2870.                                
  2871.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  2872.                                 action_list.append("Allocate: Smoke")
  2873.                                
  2874.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  2875.                                
  2876.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  2877.                                 action_list.append("Allocate: Chu")
  2878.                                 explosive_count += 1
  2879.                                
  2880.                             elif action == 'Arrow' and coin_flip > .5:
  2881.                                
  2882.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  2883.                                 action_list.append("Allocate: Arrow")
  2884.                            
  2885.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  2886.                                
  2887.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  2888.                                 action_list.append("Allocate: Bomb")
  2889.                                 explosive_count += 1
  2890.                                
  2891.                             elif action == 'Zora Fins' and coin_flip > .5:
  2892.                                
  2893.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  2894.                                 action_list.append("Allocate: Zora Fins")
  2895.                            
  2896.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  2897.                                
  2898.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  2899.                                 action_list.append("Allocate: Fish")
  2900.                                 droppable_count += 1
  2901.                                
  2902.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  2903.                                
  2904.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  2905.                                 action_list.append("Allocate: Bugs")
  2906.                                 droppable_count += 1
  2907.                            
  2908.                             elif action == 'Hookshot' and coin_flip > .5:
  2909.                                
  2910.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  2911.                                 action_list.append("Allocate: Hookshot")
  2912.                            
  2913.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  2914.                                
  2915.                                 projectile_coin_flip = np.random.uniform(0,1)
  2916.                                
  2917.                                 if projectile_coin_flip > .5:
  2918.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  2919.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  2920.                                    
  2921.                                 elif projectile_coin_flip <= .5:
  2922.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  2923.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  2924.                        
  2925.                             ### We don't include 'Charged Spin Attack' in this
  2926.                        
  2927.                         ##### DEALLOCATION
  2928.                         for actor in room.priority_queue:
  2929.                            
  2930.                             # whether or not we deallocate an actor is based off of this
  2931.                             coin_flip = np.random.uniform(0,1)
  2932.                            
  2933.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  2934.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  2935.                                
  2936.                                
  2937.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  2938.                                    
  2939.                                     Deallocate(Heap, actor, Overlay_Dict)
  2940.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  2941.                                     Clear_Instances('00E8', room)
  2942.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2943.                                
  2944.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  2945.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  2946.                                    
  2947.                                     table_bonk_deallocation_count = 0
  2948.                                     for entry in Heap:
  2949.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  2950.                                             Deallocate(Heap, entry, Overlay_Dict)
  2951.                                             table_bonk_deallocation_count += 1
  2952.                                    
  2953.                                     for entry in Heap:
  2954.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  2955.                                             Deallocate(Heap, entry, Overlay_Dict)
  2956.                                             table_bonk_deallocation_count += 1
  2957.                                            
  2958.                                     for entry in Heap:
  2959.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  2960.                                             Deallocate(Heap, entry, Overlay_Dict)
  2961.                                             table_bonk_deallocation_count += 1
  2962.                                    
  2963.                                     if table_bonk_deallocation_count != 3:
  2964.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  2965.                                    
  2966.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  2967.                                
  2968.                                
  2969.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  2970.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  2971.                                    
  2972.                                     Deallocate(Heap, actor, Overlay_Dict)
  2973.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2974.                                     # CLEAR THE ACTOR
  2975.                                     Clear_Instance(actor, room)
  2976.                                    
  2977.                                 else:
  2978.                                    
  2979.                                     Deallocate(Heap, actor, Overlay_Dict)
  2980.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  2981.                        
  2982.                    
  2983.                     # With probability 1/2, we deallocate first and allocate second
  2984.                     elif decision_coin_flip <= .5:
  2985.                    
  2986.                         explosive_count = 0
  2987.                         droppable_count = 0
  2988.                         hookshot_exists = False
  2989.                        
  2990.                         ##### DEALLOCATION
  2991.                         for actor in room.priority_queue:
  2992.                            
  2993.                             # whether or not we deallocate an actor is based off of this
  2994.                             coin_flip = np.random.uniform(0,1)
  2995.                            
  2996.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  2997.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  2998.                                
  2999.                                
  3000.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  3001.                                    
  3002.                                     Deallocate(Heap, actor, Overlay_Dict)
  3003.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  3004.                                     Clear_Instances('00E8', room)
  3005.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3006.                                
  3007.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  3008.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  3009.                                    
  3010.                                     table_bonk_deallocation_count = 0
  3011.                                     for entry in Heap:
  3012.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  3013.                                             Deallocate(Heap, entry, Overlay_Dict)
  3014.                                             table_bonk_deallocation_count += 1
  3015.                                    
  3016.                                     for entry in Heap:
  3017.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  3018.                                             Deallocate(Heap, entry, Overlay_Dict)
  3019.                                             table_bonk_deallocation_count += 1
  3020.                                            
  3021.                                     for entry in Heap:
  3022.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  3023.                                             Deallocate(Heap, entry, Overlay_Dict)
  3024.                                             table_bonk_deallocation_count += 1
  3025.                                    
  3026.                                     if table_bonk_deallocation_count != 3:
  3027.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  3028.                                    
  3029.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  3030.                                
  3031.                                
  3032.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  3033.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  3034.                                    
  3035.                                     Deallocate(Heap, actor, Overlay_Dict)
  3036.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3037.                                     # CLEAR THE ACTOR
  3038.                                     Clear_Instance(actor, room)
  3039.                                    
  3040.                                 else:
  3041.                                    
  3042.                                     Deallocate(Heap, actor, Overlay_Dict)
  3043.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3044.                        
  3045.  
  3046.                         ##### ALLOCATION
  3047.                         for action in allocation_list_dict[room.number]:
  3048.                            
  3049.                             # whether or not we add an action is based off of this
  3050.                             coin_flip = np.random.uniform(0,1)
  3051.                            
  3052.                             if action == 'Smoke' and coin_flip > .5:
  3053.                                
  3054.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  3055.                                 action_list.append("Allocate: Smoke")
  3056.                                
  3057.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  3058.                                
  3059.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  3060.                                 action_list.append("Allocate: Chu")
  3061.                                 explosive_count += 1
  3062.                                
  3063.                             elif action == 'Arrow' and coin_flip > .5:
  3064.                                
  3065.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  3066.                                 action_list.append("Allocate: Arrow")
  3067.                            
  3068.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  3069.                                
  3070.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  3071.                                 action_list.append("Allocate: Bomb")
  3072.                                 explosive_count += 1
  3073.                                
  3074.                             elif action == 'Zora Fins' and coin_flip > .5:
  3075.                                
  3076.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  3077.                                 action_list.append("Allocate: Zora Fins")
  3078.                            
  3079.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  3080.                                
  3081.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  3082.                                 action_list.append("Allocate: Fish")
  3083.                                 droppable_count += 1
  3084.                                
  3085.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  3086.                                
  3087.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  3088.                                 action_list.append("Allocate: Bugs")
  3089.                                 droppable_count += 1
  3090.                            
  3091.                             elif action == 'Hookshot' and coin_flip > .5:
  3092.                                
  3093.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  3094.                                 action_list.append("Allocate: Hookshot")
  3095.                                 hookshot_exists = True
  3096.                                
  3097.                             elif action == 'Charged Spin Attack' and (hookshot_exists is False) and coin_flip > .5:
  3098.                                
  3099.                                 Allocate_Charged_Spin_Attack(Heap, room.number, Overlay_Dict)
  3100.                                 action_list.append("Allocate: Charged Spin Attack")
  3101.                            
  3102.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  3103.                                
  3104.                                 projectile_coin_flip = np.random.uniform(0,1)
  3105.                                
  3106.                                 if projectile_coin_flip > .5:
  3107.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  3108.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  3109.                                    
  3110.                                 elif projectile_coin_flip <= .5:
  3111.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  3112.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  3113.                    
  3114.                
  3115.                 else:
  3116.                    
  3117.                     Load_Room(Heap, room, transition, Overlay_Dict)
  3118.                    
  3119.                     action_list.append("Load Room: Room %d" %(room.number) + " with " + transition.name + " %d" %(transition.priority))
  3120.                    
  3121.                     """
  3122.                    
  3123.                    Now randomly (with some chosen distribution) choose things to allocate
  3124.                    and/or things to deallocate (in your current room). Make it so that
  3125.                    you can only choose a specific action once. For example, if allocation_list
  3126.                    has ['bomb', 'bomb, 'bomb', 'fish'] in it, then make it so you can only use
  3127.                    fish once, but you can use bomb 3 times
  3128.                    
  3129.                    Somehow try to encode that hookshot/charged spin are mutually exclusive
  3130.                    and that if either of them exist then they must be the last action
  3131.                    
  3132.                    Allow yourself to deallocate things before allocating things even
  3133.                    though it might be impossible or slow in some cases
  3134.                    
  3135.                    """
  3136.                    
  3137.                     # Do a coinflip to decide between allocating or deallocating first
  3138.                     #decision_coin_flip = np.random.uniform(0,1)
  3139.                     ##### Deterministically do deallocation step first
  3140.                     decision_coin_flip = 0
  3141.                    
  3142.                     # With probability 1/2, we allocate first and deallocate second
  3143.                     # if we allocate first, don't allow 'Charged Spin Attack'
  3144.                     if decision_coin_flip > .5:
  3145.                        
  3146.                         explosive_count = 0
  3147.                         droppable_count = 0
  3148.                        
  3149.                         ##### ALLOCATION
  3150.                         for action in allocation_list_dict[room.number]:
  3151.                            
  3152.                             # whether or not we add an action is based off of this
  3153.                             coin_flip = np.random.uniform(0,1)
  3154.                            
  3155.                             if action == 'Smoke' and coin_flip > .5:
  3156.                                
  3157.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  3158.                                 action_list.append("Allocate: Smoke")
  3159.                                
  3160.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  3161.                                
  3162.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  3163.                                 action_list.append("Allocate: Chu")
  3164.                                 explosive_count += 1
  3165.                                
  3166.                             elif action == 'Arrow' and coin_flip > .5:
  3167.                                
  3168.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  3169.                                 action_list.append("Allocate: Arrow")
  3170.                            
  3171.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  3172.                                
  3173.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  3174.                                 action_list.append("Allocate: Bomb")
  3175.                                 explosive_count += 1
  3176.                                
  3177.                             elif action == 'Zora Fins' and coin_flip > .5:
  3178.                                
  3179.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  3180.                                 action_list.append("Allocate: Zora Fins")
  3181.                            
  3182.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  3183.                                
  3184.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  3185.                                 action_list.append("Allocate: Fish")
  3186.                                 droppable_count += 1
  3187.                                
  3188.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  3189.                                
  3190.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  3191.                                 action_list.append("Allocate: Bugs")
  3192.                                 droppable_count += 1
  3193.                            
  3194.                             elif action == 'Hookshot' and coin_flip > .5:
  3195.                                
  3196.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  3197.                                 action_list.append("Allocate: Hookshot")
  3198.                            
  3199.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  3200.                                
  3201.                                 projectile_coin_flip = np.random.uniform(0,1)
  3202.                                
  3203.                                 if projectile_coin_flip > .5:
  3204.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  3205.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  3206.                                    
  3207.                                 elif projectile_coin_flip <= .5:
  3208.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  3209.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  3210.                        
  3211.                             ### We don't include 'Charged Spin Attack' in this
  3212.                        
  3213.                         ##### DEALLOCATION
  3214.                         for actor in room.priority_queue:
  3215.                            
  3216.                             # whether or not we deallocate an actor is based off of this
  3217.                             coin_flip = np.random.uniform(0,1)
  3218.                            
  3219.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  3220.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  3221.                                
  3222.                                
  3223.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  3224.                                    
  3225.                                     Deallocate(Heap, actor, Overlay_Dict)
  3226.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  3227.                                     Clear_Instances('00E8', room)
  3228.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3229.                                
  3230.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  3231.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  3232.                                    
  3233.                                     table_bonk_deallocation_count = 0
  3234.                                     for entry in Heap:
  3235.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  3236.                                             Deallocate(Heap, entry, Overlay_Dict)
  3237.                                             table_bonk_deallocation_count += 1
  3238.                                    
  3239.                                     for entry in Heap:
  3240.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  3241.                                             Deallocate(Heap, entry, Overlay_Dict)
  3242.                                             table_bonk_deallocation_count += 1
  3243.                                            
  3244.                                     for entry in Heap:
  3245.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  3246.                                             Deallocate(Heap, entry, Overlay_Dict)
  3247.                                             table_bonk_deallocation_count += 1
  3248.                                    
  3249.                                     if table_bonk_deallocation_count != 3:
  3250.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  3251.                                    
  3252.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  3253.                                
  3254.                                
  3255.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  3256.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  3257.                                    
  3258.                                     Deallocate(Heap, actor, Overlay_Dict)
  3259.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3260.                                     # CLEAR THE ACTOR
  3261.                                     Clear_Instance(actor, room)
  3262.                                    
  3263.                                 else:
  3264.                                    
  3265.                                     Deallocate(Heap, actor, Overlay_Dict)
  3266.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3267.                        
  3268.                    
  3269.                     # With probability 1/2, we deallocate first and allocate second
  3270.                     elif decision_coin_flip <= .5:
  3271.                    
  3272.                         explosive_count = 0
  3273.                         droppable_count = 0
  3274.                         hookshot_exists = False
  3275.                        
  3276.                         ##### DEALLOCATION
  3277.                         for actor in room.priority_queue:
  3278.                            
  3279.                             # whether or not we deallocate an actor is based off of this
  3280.                             coin_flip = np.random.uniform(0,1)
  3281.                            
  3282.                             ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
  3283.                             if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
  3284.                                
  3285.                                
  3286.                                 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
  3287.                                    
  3288.                                     Deallocate(Heap, actor, Overlay_Dict)
  3289.                                     # There is at most one rupee cluster per room, so this is fine to clear it
  3290.                                     Clear_Instances('00E8', room)
  3291.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3292.                                
  3293.                                 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
  3294.                                 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
  3295.                                    
  3296.                                     table_bonk_deallocation_count = 0
  3297.                                     for entry in Heap:
  3298.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
  3299.                                             Deallocate(Heap, entry, Overlay_Dict)
  3300.                                             table_bonk_deallocation_count += 1
  3301.                                    
  3302.                                     for entry in Heap:
  3303.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
  3304.                                             Deallocate(Heap, entry, Overlay_Dict)
  3305.                                             table_bonk_deallocation_count += 1
  3306.                                            
  3307.                                     for entry in Heap:
  3308.                                         if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
  3309.                                             Deallocate(Heap, entry, Overlay_Dict)
  3310.                                             table_bonk_deallocation_count += 1
  3311.                                    
  3312.                                     if table_bonk_deallocation_count != 3:
  3313.                                         print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
  3314.                                    
  3315.                                     action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
  3316.                                
  3317.                                
  3318.                                 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
  3319.                                 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
  3320.                                    
  3321.                                     Deallocate(Heap, actor, Overlay_Dict)
  3322.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3323.                                     # CLEAR THE ACTOR
  3324.                                     Clear_Instance(actor, room)
  3325.                                    
  3326.                                 else:
  3327.                                    
  3328.                                     Deallocate(Heap, actor, Overlay_Dict)
  3329.                                     action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
  3330.                        
  3331.  
  3332.                         ##### ALLOCATION
  3333.                         for action in allocation_list_dict[room.number]:
  3334.                            
  3335.                             # whether or not we add an action is based off of this
  3336.                             coin_flip = np.random.uniform(0,1)
  3337.                            
  3338.                             if action == 'Smoke' and coin_flip > .5:
  3339.                                
  3340.                                 Allocate_Smoke(Heap, room.number, Overlay_Dict)
  3341.                                 action_list.append("Allocate: Smoke")
  3342.                                
  3343.                             elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
  3344.                                
  3345.                                 Allocate_Chu(Heap, room.number, Overlay_Dict)
  3346.                                 action_list.append("Allocate: Chu")
  3347.                                 explosive_count += 1
  3348.                                
  3349.                             elif action == 'Arrow' and coin_flip > .5:
  3350.                                
  3351.                                 Allocate_Arrow(Heap, room.number, Overlay_Dict)
  3352.                                 action_list.append("Allocate: Arrow")
  3353.                            
  3354.                             elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
  3355.                                
  3356.                                 Allocate_Bomb(Heap, room.number, Overlay_Dict)
  3357.                                 action_list.append("Allocate: Bomb")
  3358.                                 explosive_count += 1
  3359.                                
  3360.                             elif action == 'Zora Fins' and coin_flip > .5:
  3361.                                
  3362.                                 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
  3363.                                 action_list.append("Allocate: Zora Fins")
  3364.                            
  3365.                             elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
  3366.                                
  3367.                                 Allocate_Fish(Heap, room.number, Overlay_Dict)
  3368.                                 action_list.append("Allocate: Fish")
  3369.                                 droppable_count += 1
  3370.                                
  3371.                             elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
  3372.                                
  3373.                                 Allocate_Bugs(Heap, room.number, Overlay_Dict)
  3374.                                 action_list.append("Allocate: Bugs")
  3375.                                 droppable_count += 1
  3376.                            
  3377.                             elif action == 'Hookshot' and coin_flip > .5:
  3378.                                
  3379.                                 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
  3380.                                 action_list.append("Allocate: Hookshot")
  3381.                                 hookshot_exists = True
  3382.                                
  3383.                             elif action == 'Charged Spin Attack' and (hookshot_exists is False) and coin_flip > .5:
  3384.                                
  3385.                                 Allocate_Charged_Spin_Attack(Heap, room.number, Overlay_Dict)
  3386.                                 action_list.append("Allocate: Charged Spin Attack")
  3387.                            
  3388.                             elif action == 'Gold Skulltula' and coin_flip > .5:
  3389.                                
  3390.                                 projectile_coin_flip = np.random.uniform(0,1)
  3391.                                
  3392.                                 if projectile_coin_flip > .5:
  3393.                                     Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
  3394.                                     action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
  3395.                                    
  3396.                                 elif projectile_coin_flip <= .5:
  3397.                                     Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
  3398.                                     action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
  3399.                    
  3400.                 room_count += 1
  3401.            
  3402.             ##### Now we load the last room in room_order_list
  3403.             current_room = Current_Room(room_load_list, Room_List)
  3404.             most_recent_transition = room_load_list[-1]
  3405.             Load_Room(Heap, current_room, most_recent_transition, Overlay_Dict)
  3406.            
  3407.             action_list.append("Load Room: Room %d" %(current_room.number) + " with " + most_recent_transition.name + " %d" %(most_recent_transition.priority))
  3408.            
  3409.            
  3410.             """
  3411.            
  3412.            Now that we have iterated through all of the rooms, we want to check to see
  3413.            if we are in a room with a valid grabbale object. If so, then store the addresses
  3414.            of all of them and make a copy of the current Heap state. From here, we want to try
  3415.            every possibility in the sense that we want to check every valid grabbable object
  3416.            in every room that we can get to and also check every superslide case that is possible
  3417.            (based on the binary number associated with each valid grabbable object) and then
  3418.            check if either the Angle or Position (input this into the function via Offset_List)
  3419.            line up with the chest or deku guard
  3420.            
  3421.            There aren't too many possibilities from here in practice, so we might as well check them all
  3422.            
  3423.            Also encode that if we superslide into a room with a chest/deku guard, then we must
  3424.            exit the room and then reenter it (or enter another room with a chest/deku guard; we will
  3425.            test every case) and after doing that we will check the chest/deku guard addresses
  3426.            and see if any of them line up with any of the pots that we stored the addresses of
  3427.            
  3428.            We'll eventually want to write stuff to a text file, so maybe set file as an input argument
  3429.            or just hardcode it, not sure
  3430.            
  3431.            """
  3432.            
  3433.             """
  3434.            
  3435.            WE MAKE THE ASSUMPTION THAT YOU LAND IN A ROOM THAT EITHER IS A ROOM
  3436.            WITH A CHEST/DEKU GUARD OR A ROOM THAT NEIGHBORS A ROOM WITH A CHEST/DEKU GUARD
  3437.            BECAUSE I CANNOT THINK OF ANY PLACES WHERE THIS WOULDN'T HAPPEN WHEN TESTING
  3438.            SUPERSLIDE SRM (ZORA FIN WOULD BE DIFFERENT, BUT THIS SOLVER DOESN'T TEST IT)
  3439.            
  3440.            Also, before supersliding, we assume that you're in a room that either has
  3441.            a valid grabbable object, or is next to a room with a valid grabbable object.
  3442.            Of course, this means fewer possibilities are being tested in a place like
  3443.            oceanside, but there are already so many possibilities to test to begin with that
  3444.            this probably isn't a big deal for now. This also affects deku palace, but maybe
  3445.            I'll change this by the time I work on deku palace (because if you end in Room2,
  3446.            then nothing happens)
  3447.            
  3448.            """
  3449.            
  3450.             """
  3451.            
  3452.            Nevermind some of those other comments, here is what I'm really assuming.
  3453.            
  3454.            I will be assuming that if you end in a room without a valid grabbable
  3455.            actor, then it will search all neighbors of that room for valid grabbable
  3456.            actors and if none of those have valid grabbable objects then it will
  3457.            search all of those neighbors and choose the first one it finds (this
  3458.            will allow for ending in Room 2 in Deku Palace). Otherwise it does nothing
  3459.            (though this will never happen for the cases I plan on checking for now)
  3460.            
  3461.            (*Coded)If you are in a room with a valid grabbable actor and no chest/deku guard,
  3462.            then we will check the addresses of all valid grabbable actors in this room
  3463.            and superslide into the chest room, exit and reenter it. Then we will check the address of the
  3464.            chest and see if it lines up with any of the pot addresses from the previous
  3465.            room.
  3466.            
  3467.            (*Coded)If you are in a room with a valid grabbable actor AND a chest/deku guard, then
  3468.            you will record the valid grabbable actor addresses then superslide to exit the
  3469.            room and then check all neighbors of the room you enter for having a chest/deku guard
  3470.            and test all of them
  3471.            
  3472.            
  3473.            
  3474.            """
  3475.            
  3476.             valid_grabbable_actor_room_list = []
  3477.            
  3478.             for room in Room_List:
  3479.                 if Valid_Grabbable_In_Room(room, Grabbable_Dict) is True:
  3480.                     valid_grabbable_actor_room_list.append(room)
  3481.            
  3482.             # This gives a list of all ways we can exit our current room
  3483.             #transition_list_possibilities = Generate_Room_Load_Permutations(current_room, Room_List, 1)
  3484.            
  3485.             ##### Case 1: there is a valid grabbable actor in the current room, but no chest/deku guard (the guard thing doesn't matter because this never happens in palace anyway)
  3486.             if (current_room in valid_grabbable_actor_room_list) and (Chest_In_Room(current_room) is False) and (Deku_Guard_In_Room(current_room) is False):
  3487.                
  3488.                 valid_pot_list = []
  3489.                 pot_address_list = []
  3490.                
  3491.                 for pot in Grabbable_Dict:
  3492.                    
  3493.                     if Actor_Is_In_Room(current_room, pot) is True:
  3494.                         valid_pot_list.append(pot)
  3495.                         pot_address_list.append(pot.address)
  3496.                
  3497.                 """
  3498.                
  3499.                Now for each pot in valid_pot_list, we want to test every applicable
  3500.                superslide scenario
  3501.                
  3502.                Before each one, we need to copy the current state and then modify the copies
  3503.                to check for the solution
  3504.                
  3505.                """
  3506.                
  3507.                 for pot in valid_pot_list:
  3508.                    
  3509.                     # both bomb and smoke loaded on superslide
  3510.                     if Grabbable_Dict[pot][0][0] == '1':
  3511.                        
  3512.                         action_list100 = []
  3513.                        
  3514.                         # COPY STATE
  3515.                         #######################################################
  3516.                         Room_List_Copy = Copy_Room_List(Room_List)
  3517.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  3518.                        
  3519.                         room_copy_dict = {}
  3520.                         for room in Room_List_Copy:
  3521.                             room_copy_dict[room.number] = room
  3522.                        
  3523.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  3524.                        
  3525.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  3526.                         #######################################################
  3527.                        
  3528.                         Bomb_And_Smoke_Superslide(Heap_Copy, current_room.number, Overlay_Dict_Copy)
  3529.                         action_list100.append("Superslide with Bomb and Smoke still allocated")
  3530.                        
  3531.                         # The room we superslide into through the plane corresponding to the given pot
  3532.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  3533.                        
  3534.                         destination_room_copy = room_copy_dict[destination_room.number]
  3535.                         current_room_copy = room_copy_dict[current_room.number]
  3536.                        
  3537.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  3538.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  3539.                        
  3540.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3541.                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3542.                        
  3543.                         # Now exit the chest room
  3544.                         Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3545.                         action_list100.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3546.                        
  3547.                         # Now reenter the chest room
  3548.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3549.                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3550.                        
  3551.                         ##### Now check for chests/deku guards
  3552.                        
  3553.                         chest_guard_list = []
  3554.                        
  3555.                         for entry in Heap_Copy:
  3556.                            
  3557.                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  3558.                                 chest_guard_list.append(entry)
  3559.                        
  3560.                         soln_found = False
  3561.                         for entry in chest_guard_list:
  3562.                             if (pot.address - entry.address) in Offset_List:
  3563.                                
  3564.                                 action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  3565.                                
  3566.                                 if (pot.address - entry.address) == 0x160:
  3567.                                     angle_solution_count += 1
  3568.                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3569.                                 elif (pot.address - entry.address) == 0x1F0:
  3570.                                     position_solution_count += 1
  3571.                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3572.                                
  3573.                                 soln_found = True
  3574.                                
  3575.                         if soln_found is True:
  3576.                             total_action_list = action_list + action_list100
  3577.                            
  3578.                             # the "a" argument is important so we don't overwrite previous solutions
  3579.                             with open(filename, "a") as file:
  3580.                                
  3581.                                 for action in total_action_list:
  3582.                                    
  3583.                                     file.write(action + "\n")
  3584.                                 file.write("-----\n")
  3585.                    
  3586.                    
  3587.                     ##### Only smoke is loaded from superslide
  3588.                     elif Grabbable_Dict[pot][0][1] == '1':
  3589.                        
  3590.                         action_list010 = []
  3591.                        
  3592.                         # COPY STATE
  3593.                         #######################################################
  3594.                         Room_List_Copy = Copy_Room_List(Room_List)
  3595.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  3596.                        
  3597.                         room_copy_dict = {}
  3598.                         for room in Room_List_Copy:
  3599.                             room_copy_dict[room.number] = room
  3600.                        
  3601.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  3602.                        
  3603.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  3604.                         #######################################################
  3605.                        
  3606.                         Allocate_Smoke(Heap_Copy, current_room.number, Overlay_Dict_Copy)
  3607.                         action_list010.append("Superslide with Smoke still allocated")
  3608.                        
  3609.                         # The room we superslide into through the plane corresponding to the given pot
  3610.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  3611.                        
  3612.                         destination_room_copy = room_copy_dict[destination_room.number]
  3613.                         current_room_copy = room_copy_dict[current_room.number]
  3614.                        
  3615.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  3616.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  3617.                        
  3618.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3619.                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3620.                        
  3621.                         # Now exit the chest room
  3622.                         Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3623.                         action_list010.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3624.                        
  3625.                         # Now reenter the chest room
  3626.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3627.                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3628.                        
  3629.                        
  3630.                         ##### Now check for chests/deku guards
  3631.                        
  3632.                         chest_guard_list = []
  3633.                        
  3634.                         for entry in Heap_Copy:
  3635.                            
  3636.                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  3637.                                 chest_guard_list.append(entry)
  3638.                        
  3639.                         soln_found = False
  3640.                         for entry in chest_guard_list:
  3641.                             if (pot.address - entry.address) in Offset_List:
  3642.                                
  3643.                                 action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  3644.                                
  3645.                                 if (pot.address - entry.address) == 0x160:
  3646.                                     angle_solution_count += 1
  3647.                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3648.                                 elif (pot.address - entry.address) == 0x1F0:
  3649.                                     position_solution_count += 1
  3650.                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3651.                                
  3652.                                 soln_found = True
  3653.                                
  3654.                         if soln_found is True:
  3655.                             total_action_list = action_list + action_list010
  3656.                            
  3657.                             # the "a" argument is important so we don't overwrite previous solutions
  3658.                             with open(filename, "a") as file:
  3659.                                
  3660.                                 for action in total_action_list:
  3661.                                    
  3662.                                     file.write(action + "\n")
  3663.                                 file.write("-----\n")
  3664.                    
  3665.                    
  3666.                     #### Bomb and Smoke are both unloaded
  3667.                     elif Grabbable_Dict[pot][0][2] == '1':
  3668.                        
  3669.                         action_list001 = []
  3670.                        
  3671.                         # COPY STATE
  3672.                         #######################################################
  3673.                         Room_List_Copy = Copy_Room_List(Room_List)
  3674.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  3675.                        
  3676.                         room_copy_dict = {}
  3677.                         for room in Room_List_Copy:
  3678.                             room_copy_dict[room.number] = room
  3679.                        
  3680.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  3681.                        
  3682.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  3683.                         #######################################################
  3684.                        
  3685.                         # Do not allocate anything
  3686.                         action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  3687.                        
  3688.                         # The room we superslide into through the plane corresponding to the given pot
  3689.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  3690.                        
  3691.                         destination_room_copy = room_copy_dict[destination_room.number]
  3692.                         current_room_copy = room_copy_dict[current_room.number]
  3693.                        
  3694.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  3695.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  3696.                        
  3697.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3698.                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3699.                        
  3700.                         # Now exit the chest room
  3701.                         Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3702.                         action_list001.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3703.                        
  3704.                         # Now reenter the chest room
  3705.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3706.                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3707.                        
  3708.                        
  3709.                         ##### Now check for chests/deku guards
  3710.                        
  3711.                         chest_guard_list = []
  3712.                        
  3713.                         for entry in Heap_Copy:
  3714.                            
  3715.                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  3716.                                 chest_guard_list.append(entry)
  3717.                        
  3718.                         soln_found = False
  3719.                         for entry in chest_guard_list:
  3720.                             if (pot.address - entry.address) in Offset_List:
  3721.                                
  3722.                                 action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  3723.                                
  3724.                                 if (pot.address - entry.address) == 0x160:
  3725.                                     angle_solution_count += 1
  3726.                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3727.                                 elif (pot.address - entry.address) == 0x1F0:
  3728.                                     position_solution_count += 1
  3729.                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3730.                                
  3731.                                 soln_found = True
  3732.                                
  3733.                         if soln_found is True:
  3734.                             total_action_list = action_list + action_list001
  3735.                            
  3736.                             # the "a" argument is important so we don't overwrite previous solutions
  3737.                             with open(filename, "a") as file:
  3738.                                
  3739.                                 for action in total_action_list:
  3740.                                    
  3741.                                     file.write(action + "\n")
  3742.                                 file.write("-----\n")
  3743.                                
  3744.                                
  3745.                                
  3746.             # Case 2: there is a valid grabbable actor in the current room AND there is a chest or deku guard                  
  3747.             elif (current_room in valid_grabbable_actor_room_list) and ((Chest_In_Room(current_room) is True) or (Deku_Guard_In_Room(current_room) is True)):      
  3748.                
  3749.                 valid_pot_list = []
  3750.                 pot_address_list = []
  3751.                
  3752.                 for pot in Grabbable_Dict:
  3753.                    
  3754.                     if Actor_Is_In_Room(current_room, pot) is True:
  3755.                         valid_pot_list.append(pot)
  3756.                         pot_address_list.append(pot.address)
  3757.                
  3758.                
  3759.                 """
  3760.                
  3761.                Now for each pot in valid_pot_list, we want to test every applicable
  3762.                superslide scenario
  3763.                
  3764.                Before each one, we need to copy the current state and then modify the copies
  3765.                to check for the solution
  3766.                
  3767.                Also, for every case, we need to consider every possible room that contains
  3768.                a chest/deku guard that neighbors the room we just entered (meaning you
  3769.                will need to make copies of the copies of the state)
  3770.                
  3771.                """
  3772.                
  3773.                 for pot in valid_pot_list:
  3774.                    
  3775.                     # both bomb and smoke loaded on superslide
  3776.                     if Grabbable_Dict[pot][0][0] == '1':
  3777.                        
  3778.                         action_list100 = []
  3779.                        
  3780.                         # COPY STATE
  3781.                         #######################################################
  3782.                         Room_List_Copy = Copy_Room_List(Room_List)
  3783.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  3784.                        
  3785.                         room_copy_dict = {}
  3786.                         for room in Room_List_Copy:
  3787.                             room_copy_dict[room.number] = room
  3788.                        
  3789.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  3790.                        
  3791.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  3792.                         #######################################################
  3793.                        
  3794.                         Bomb_And_Smoke_Superslide(Heap_Copy, current_room.number, Overlay_Dict_Copy)
  3795.                         action_list100.append("Superslide with Bomb and Smoke still allocated")
  3796.                        
  3797.                         # The room we superslide into through the plane corresponding to the given pot
  3798.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  3799.                        
  3800.                         destination_room_copy = room_copy_dict[destination_room.number]
  3801.                        
  3802.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  3803.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  3804.                        
  3805.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3806.                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3807.                        
  3808.                         """
  3809.                        
  3810.                        Now we check all neighbors of our current room (destination_room) and for
  3811.                        each neighbor that has a chest or deku guard in it, we will create a copy
  3812.                        of our copy of the state, then enter each of them through each possible
  3813.                        loading plane and then check the chest/guard addresses and see if anything
  3814.                        lines up
  3815.                        
  3816.                        """
  3817.                        
  3818.                         for neighbor in Neighbors(destination_room, Room_List):
  3819.                            
  3820.                             if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
  3821.                                
  3822.                                 for transition in Shared_Transitions(destination_room, neighbor):
  3823.                                    
  3824.                                      # COPY STATE
  3825.                                     #######################################################
  3826.                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  3827.                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  3828.                                    
  3829.                                     room_copy_dict_2 = {}
  3830.                                     for room in Room_List_Copy_2:
  3831.                                         room_copy_dict_2[room.number] = room
  3832.                                    
  3833.                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  3834.                                    
  3835.                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  3836.                                     #######################################################
  3837.                                    
  3838.                                     action_list_2 = []
  3839.                                    
  3840.                                     transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
  3841.                                    
  3842.                                     neighbor_copy = room_copy_dict_2[neighbor.number]
  3843.                                    
  3844.                                     Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
  3845.                                     action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
  3846.                                    
  3847.                                    
  3848.                                     ##### Now check for chests/deku guards
  3849.                        
  3850.                                     chest_guard_list = []
  3851.                                    
  3852.                                     for entry in Heap_Copy_2:
  3853.                                        
  3854.                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  3855.                                             chest_guard_list.append(entry)
  3856.                                    
  3857.                                     soln_found = False
  3858.                                     for entry in chest_guard_list:
  3859.                                         if (pot.address - entry.address) in Offset_List:
  3860.                                            
  3861.                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  3862.  
  3863.                                             if (pot.address - entry.address) == 0x160:
  3864.                                                 angle_solution_count += 1
  3865.                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3866.                                             elif (pot.address - entry.address) == 0x1F0:
  3867.                                                 position_solution_count += 1
  3868.                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3869.  
  3870.                                             soln_found = True
  3871.                                            
  3872.                                     if soln_found is True:
  3873.                                         total_action_list = action_list + action_list100 + action_list_2
  3874.                                        
  3875.                                         # the "a" argument is important so we don't overwrite previous solutions
  3876.                                         with open(filename, "a") as file:
  3877.                                            
  3878.                                             for action in total_action_list:
  3879.                                                
  3880.                                                 file.write(action + "\n")
  3881.                                             file.write("-----\n")
  3882.                    
  3883.                    
  3884.                     ##### Only smoke is loaded from superslide
  3885.                     elif Grabbable_Dict[pot][0][1] == '1':
  3886.                        
  3887.                         action_list010 = []
  3888.                        
  3889.                         # COPY STATE
  3890.                         #######################################################
  3891.                         Room_List_Copy = Copy_Room_List(Room_List)
  3892.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  3893.                        
  3894.                         room_copy_dict = {}
  3895.                         for room in Room_List_Copy:
  3896.                             room_copy_dict[room.number] = room
  3897.                        
  3898.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  3899.                        
  3900.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  3901.                         #######################################################
  3902.                        
  3903.                         Allocate_Smoke(Heap_Copy, current_room.number, Overlay_Dict_Copy)
  3904.                         action_list010.append("Superslide with Smoke still allocated")
  3905.                        
  3906.                         # The room we superslide into through the plane corresponding to the given pot
  3907.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  3908.                        
  3909.                         destination_room_copy = room_copy_dict[destination_room.number]
  3910.                        
  3911.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  3912.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  3913.                        
  3914.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  3915.                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  3916.                        
  3917.                         """
  3918.                        
  3919.                        Now we check all neighbors of our current room (destination_room) and for
  3920.                        each neighbor that has a chest or deku guard in it, we will create a copy
  3921.                        of our copy of the state, then enter each of them through each possible
  3922.                        loading plane and then check the chest/guard addresses and see if anything
  3923.                        lines up
  3924.                        
  3925.                        """
  3926.                        
  3927.                         for neighbor in Neighbors(destination_room, Room_List):
  3928.                            
  3929.                             if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
  3930.  
  3931.                                 for transition in Shared_Transitions(destination_room, neighbor):
  3932.                                    
  3933.                                     # COPY STATE
  3934.                                     #######################################################
  3935.                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  3936.                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  3937.                                    
  3938.                                     room_copy_dict_2 = {}
  3939.                                     for room in Room_List_Copy_2:
  3940.                                         room_copy_dict_2[room.number] = room
  3941.                                    
  3942.                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  3943.                                    
  3944.                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  3945.                                     #######################################################
  3946.                                    
  3947.                                     action_list_2 = []
  3948.                                    
  3949.                                     transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
  3950.                                    
  3951.                                     neighbor_copy = room_copy_dict_2[neighbor.number]
  3952.                                    
  3953.                                     Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
  3954.                                     action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
  3955.                                    
  3956.                                    
  3957.                                     ##### Now check for chests/deku guards
  3958.                        
  3959.                                     chest_guard_list = []
  3960.                                    
  3961.                                     for entry in Heap_Copy_2:
  3962.                                        
  3963.                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  3964.                                             chest_guard_list.append(entry)
  3965.                                    
  3966.                                     soln_found = False
  3967.                                     for entry in chest_guard_list:
  3968.                                         if (pot.address - entry.address) in Offset_List:
  3969.                                            
  3970.                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  3971.  
  3972.                                             if (pot.address - entry.address) == 0x160:
  3973.                                                 angle_solution_count += 1
  3974.                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3975.                                             elif (pot.address - entry.address) == 0x1F0:
  3976.                                                 position_solution_count += 1
  3977.                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  3978.  
  3979.                                             soln_found = True
  3980.                                            
  3981.                                     if soln_found is True:
  3982.                                         total_action_list = action_list + action_list010 + action_list_2
  3983.                                        
  3984.                                         # the "a" argument is important so we don't overwrite previous solutions
  3985.                                         with open(filename, "a") as file:
  3986.                                            
  3987.                                             for action in total_action_list:
  3988.                                                
  3989.                                                 file.write(action + "\n")
  3990.                                             file.write("-----\n")
  3991.                        
  3992.                        
  3993.                     #### Bomb and Smoke are both unloaded
  3994.                     elif Grabbable_Dict[pot][0][2] == '1':
  3995.                        
  3996.                         action_list001 = []
  3997.                        
  3998.                         # COPY STATE
  3999.                         #######################################################
  4000.                         Room_List_Copy = Copy_Room_List(Room_List)
  4001.                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  4002.                        
  4003.                         room_copy_dict = {}
  4004.                         for room in Room_List_Copy:
  4005.                             room_copy_dict[room.number] = room
  4006.                        
  4007.                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  4008.                        
  4009.                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  4010.                         #######################################################
  4011.                        
  4012.                         # Do not allocate anything
  4013.                         action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  4014.                        
  4015.                         # The room we superslide into through the plane corresponding to the given pot
  4016.                         destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
  4017.                        
  4018.                         destination_room_copy = room_copy_dict[destination_room.number]
  4019.                        
  4020.                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
  4021.                         superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
  4022.                        
  4023.                         Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
  4024.                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4025.                        
  4026.                         """
  4027.                        
  4028.                        Now we check all neighbors of our current room (destination_room) and for
  4029.                        each neighbor that has a chest or deku guard in it, we will create a copy
  4030.                        of our copy of the state, then enter each of them through each possible
  4031.                        loading plane and then check the chest/guard addresses and see if anything
  4032.                        lines up
  4033.                        
  4034.                        """
  4035.                        
  4036.                         for neighbor in Neighbors(destination_room, Room_List):
  4037.                            
  4038.                             if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
  4039.  
  4040.                                 for transition in Shared_Transitions(destination_room, neighbor):
  4041.  
  4042.                                     # COPY STATE
  4043.                                     #######################################################
  4044.                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  4045.                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4046.                                    
  4047.                                     room_copy_dict_2 = {}
  4048.                                     for room in Room_List_Copy_2:
  4049.                                         room_copy_dict_2[room.number] = room
  4050.                                    
  4051.                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4052.                                    
  4053.                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  4054.                                     #######################################################
  4055.  
  4056.                                     action_list_2 = []
  4057.                                    
  4058.                                     transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
  4059.                                    
  4060.                                     neighbor_copy = room_copy_dict_2[neighbor.number]
  4061.                                    
  4062.                                     Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
  4063.                                     action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
  4064.                                    
  4065.                                    
  4066.                                     ##### Now check for chests/deku guards
  4067.                        
  4068.                                     chest_guard_list = []
  4069.                                    
  4070.                                     for entry in Heap_Copy_2:
  4071.                                        
  4072.                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4073.                                             chest_guard_list.append(entry)
  4074.                                    
  4075.                                     soln_found = False
  4076.                                     for entry in chest_guard_list:
  4077.                                         if (pot.address - entry.address) in Offset_List:
  4078.                                            
  4079.                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4080.  
  4081.                                             if (pot.address - entry.address) == 0x160:
  4082.                                                 angle_solution_count += 1
  4083.                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4084.                                             elif (pot.address - entry.address) == 0x1F0:
  4085.                                                 position_solution_count += 1
  4086.                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4087.  
  4088.                                             soln_found = True
  4089.                                            
  4090.                                     if soln_found is True:
  4091.                                         total_action_list = action_list + action_list001 + action_list_2
  4092.                                        
  4093.                                         # the "a" argument is important so we don't overwrite previous solutions
  4094.                                         with open(filename, "a") as file:
  4095.                                            
  4096.                                             for action in total_action_list:
  4097.                                                
  4098.                                                 file.write(action + "\n")
  4099.                                             file.write("-----\n")
  4100.                        
  4101.                        
  4102.             ##### Case 3: there is NOT a valid grabbable actor in the current room            
  4103.             elif (current_room not in valid_grabbable_actor_room_list):
  4104.                
  4105.                 for neighbor in Neighbors(current_room, Room_List):
  4106.                    
  4107.                     ##### Valid grabbable actor in neighbor
  4108.                     if neighbor in valid_grabbable_actor_room_list:
  4109.                        
  4110.                        
  4111.                         # For every transition in Shared_Transitions(current_room, neighbor)
  4112.                         for transition in Shared_Transitions(current_room, neighbor):
  4113.                            
  4114.                             action_list_transition = []
  4115.                            
  4116.                             ##### COPY THE STATE
  4117.                             #######################################################
  4118.                             Room_List_Copy = Copy_Room_List(Room_List)
  4119.                             Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  4120.                            
  4121.                             room_copy_dict = {}
  4122.                             for room in Room_List_Copy:
  4123.                                 room_copy_dict[room.number] = room
  4124.                            
  4125.                             Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  4126.                            
  4127.                             Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  4128.                             #######################################################
  4129.                            
  4130.                             ##### ENTER neighbor after copying it
  4131.                            
  4132.                             neighbor_copy = room_copy_dict[neighbor.number]
  4133.                             transition_copy = Find_Actor_Copy(transition, Room_List_Copy)
  4134.  
  4135.                             Load_Room(Heap_Copy, neighbor_copy, transition_copy, Overlay_Dict_Copy)
  4136.                             action_list_transition.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
  4137.                            
  4138.                            
  4139.                             ##### Iterate through all pots in this room
  4140.                        
  4141.                             valid_pot_list = []
  4142.                             pot_address_list = []
  4143.                            
  4144.                             for pot in Grabbable_Dict_Copy:
  4145.                                
  4146.                                 if Actor_Is_In_Room(neighbor_copy, pot) is True:
  4147.                                     valid_pot_list.append(pot)
  4148.                                     pot_address_list.append(pot.address)
  4149.                            
  4150.                            
  4151.                            
  4152.                             # If there is a chest/guard, superslide, then check neighbors for chests/guards and test all (copy state)
  4153.                             if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
  4154.                                
  4155.                                 for pot in valid_pot_list:
  4156.                                    
  4157.                                     # both bomb and smoke loaded on superslide
  4158.                                     if Grabbable_Dict_Copy[pot][0][0] == '1':
  4159.                                        
  4160.                                         action_list100 = []
  4161.                                        
  4162.                                         # COPY STATE
  4163.                                         #######################################################
  4164.                                         Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  4165.                                         Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4166.                                        
  4167.                                         room_copy_dict_SS = {}
  4168.                                         for room in Room_List_Copy_SS:
  4169.                                             room_copy_dict_SS[room.number] = room
  4170.                                        
  4171.                                         Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  4172.                                        
  4173.                                         Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  4174.                                         #######################################################
  4175.                                        
  4176.                                         Bomb_And_Smoke_Superslide(Heap_Copy_SS, neighbor.number, Overlay_Dict_Copy_SS)
  4177.                                         action_list100.append("Superslide with Bomb and Smoke still allocated")
  4178.                                        
  4179.                                         # The room we superslide into through the plane corresponding to the given pot
  4180.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4181.                                        
  4182.                                         destination_room_copy = room_copy_dict_SS[destination_room.number]
  4183.                                        
  4184.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  4185.                                         superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  4186.                                        
  4187.                                         Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  4188.                                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4189.                                        
  4190.                                         """
  4191.                                        
  4192.                                        Now we check all neighbors of our current room (destination_room) and for
  4193.                                        each neighbor that has a chest or deku guard in it, we will create a copy
  4194.                                        of our copy of the state, then enter each of them through each possible
  4195.                                        loading plane and then check the chest/guard addresses and see if anything
  4196.                                        lines up
  4197.                                        
  4198.                                        """
  4199.                                        
  4200.                                         for bordering_room in Neighbors(destination_room, Room_List):
  4201.                                            
  4202.                                             if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  4203.                                                
  4204.                                                 for loading_plane in Shared_Transitions(destination_room, bordering_room):
  4205.                                                    
  4206.                                                      # COPY STATE
  4207.                                                     #######################################################
  4208.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  4209.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  4210.                                                    
  4211.                                                     room_copy_dict_2 = {}
  4212.                                                     for room in Room_List_Copy_2:
  4213.                                                         room_copy_dict_2[room.number] = room
  4214.                                                    
  4215.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4216.                                                    
  4217.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  4218.                                                     #######################################################
  4219.                                                    
  4220.                                                     action_list_2 = []
  4221.                                                    
  4222.                                                     loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  4223.                                                    
  4224.                                                     bordering_room_copy = room_copy_dict_2[bordering_room.number]
  4225.                                                    
  4226.                                                     Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  4227.                                                     action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  4228.                                                    
  4229.                                                    
  4230.                                                     ##### Now check for chests/deku guards
  4231.                                        
  4232.                                                     chest_guard_list = []
  4233.                                                    
  4234.                                                     for entry in Heap_Copy_2:
  4235.                                                        
  4236.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4237.                                                             chest_guard_list.append(entry)
  4238.                                                    
  4239.                                                     soln_found = False
  4240.                                                     for entry in chest_guard_list:
  4241.                                                         if (pot.address - entry.address) in Offset_List:
  4242.                                                            
  4243.                                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4244.  
  4245.                                                             if (pot.address - entry.address) == 0x160:
  4246.                                                                 angle_solution_count += 1
  4247.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4248.                                                             elif (pot.address - entry.address) == 0x1F0:
  4249.                                                                 position_solution_count += 1
  4250.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4251.  
  4252.                                                             soln_found = True
  4253.                                                            
  4254.                                                     if soln_found is True:
  4255.                                                         total_action_list = action_list + action_list_transition + action_list100 + action_list_2
  4256.                                                        
  4257.                                                         # the "a" argument is important so we don't overwrite previous solutions
  4258.                                                         with open(filename, "a") as file:
  4259.                                                            
  4260.                                                             for action in total_action_list:
  4261.                                                                
  4262.                                                                 file.write(action + "\n")
  4263.                                                             file.write("-----\n")
  4264.                                    
  4265.                                        
  4266.                                        
  4267.                                     ##### Only smoke is loaded from superslide
  4268.                                     elif Grabbable_Dict_Copy[pot][0][1] == '1':
  4269.                                        
  4270.                                         action_list010 = []
  4271.                                        
  4272.                                         # COPY STATE
  4273.                                         #######################################################
  4274.                                         Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  4275.                                         Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4276.                                        
  4277.                                         room_copy_dict_SS = {}
  4278.                                         for room in Room_List_Copy_SS:
  4279.                                             room_copy_dict_SS[room.number] = room
  4280.                                        
  4281.                                         Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  4282.                                        
  4283.                                         Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  4284.                                         #######################################################
  4285.                                        
  4286.                                         Allocate_Smoke(Heap_Copy_SS, neighbor.number, Overlay_Dict_Copy_SS)
  4287.                                         action_list010.append("Superslide with Smoke still allocated")
  4288.                                        
  4289.                                         # The room we superslide into through the plane corresponding to the given pot
  4290.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4291.                                        
  4292.                                         destination_room_copy = room_copy_dict_SS[destination_room.number]
  4293.                                        
  4294.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  4295.                                         superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  4296.                                        
  4297.                                         Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  4298.                                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4299.                                        
  4300.                                         """
  4301.                                        
  4302.                                        Now we check all neighbors of our current room (destination_room) and for
  4303.                                        each neighbor that has a chest or deku guard in it, we will create a copy
  4304.                                        of our copy of the state, then enter each of them through each possible
  4305.                                        loading plane and then check the chest/guard addresses and see if anything
  4306.                                        lines up
  4307.                                        
  4308.                                        """
  4309.                                        
  4310.                                         for bordering_room in Neighbors(destination_room, Room_List):
  4311.                                            
  4312.                                             if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  4313.                                                
  4314.                                                 for loading_plane in Shared_Transitions(destination_room, bordering_room):
  4315.                                                    
  4316.                                                      # COPY STATE
  4317.                                                     #######################################################
  4318.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  4319.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  4320.                                                    
  4321.                                                     room_copy_dict_2 = {}
  4322.                                                     for room in Room_List_Copy_2:
  4323.                                                         room_copy_dict_2[room.number] = room
  4324.                                                    
  4325.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4326.                                                    
  4327.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  4328.                                                     #######################################################
  4329.                                                    
  4330.                                                     action_list_2 = []
  4331.                                                    
  4332.                                                     loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  4333.                                                    
  4334.                                                     bordering_room_copy = room_copy_dict_2[bordering_room.number]
  4335.                                                    
  4336.                                                     Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  4337.                                                     action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  4338.                                                    
  4339.                                                    
  4340.                                                     ##### Now check for chests/deku guards
  4341.                                        
  4342.                                                     chest_guard_list = []
  4343.                                                    
  4344.                                                     for entry in Heap_Copy_2:
  4345.                                                        
  4346.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4347.                                                             chest_guard_list.append(entry)
  4348.                                                    
  4349.                                                     soln_found = False
  4350.                                                     for entry in chest_guard_list:
  4351.                                                         if (pot.address - entry.address) in Offset_List:
  4352.                                                            
  4353.                                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4354.                                                            
  4355.                                                             if (pot.address - entry.address) == 0x160:
  4356.                                                                 angle_solution_count += 1
  4357.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4358.                                                             elif (pot.address - entry.address) == 0x1F0:
  4359.                                                                 position_solution_count += 1
  4360.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4361.                                
  4362.                                                             soln_found = True
  4363.                                                            
  4364.                                                     if soln_found is True:
  4365.                                                         total_action_list = action_list + action_list_transition + action_list010 + action_list_2
  4366.                                                        
  4367.                                                         # the "a" argument is important so we don't overwrite previous solutions
  4368.                                                         with open(filename, "a") as file:
  4369.                                                            
  4370.                                                             for action in total_action_list:
  4371.                                                                
  4372.                                                                 file.write(action + "\n")
  4373.                                                             file.write("-----\n")
  4374.  
  4375.  
  4376.                                     #### Bomb and Smoke are both unloaded
  4377.                                     elif Grabbable_Dict_Copy[pot][0][2] == '1':
  4378.                                        
  4379.                                         action_list001 = []
  4380.                                        
  4381.                                         # COPY STATE
  4382.                                         #######################################################
  4383.                                         Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  4384.                                         Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4385.                                        
  4386.                                         room_copy_dict_SS = {}
  4387.                                         for room in Room_List_Copy_SS:
  4388.                                             room_copy_dict_SS[room.number] = room
  4389.                                        
  4390.                                         Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  4391.                                        
  4392.                                         Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  4393.                                         #######################################################
  4394.                                        
  4395.                                         # Do not allocate anything
  4396.                                         action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  4397.                                        
  4398.                                         # The room we superslide into through the plane corresponding to the given pot
  4399.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4400.                                        
  4401.                                         destination_room_copy = room_copy_dict_SS[destination_room.number]
  4402.                                        
  4403.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  4404.                                         superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  4405.                                        
  4406.                                         Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  4407.                                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4408.                                        
  4409.                                         """
  4410.                                        
  4411.                                        Now we check all neighbors of our current room (destination_room) and for
  4412.                                        each neighbor that has a chest or deku guard in it, we will create a copy
  4413.                                        of our copy of the state, then enter each of them through each possible
  4414.                                        loading plane and then check the chest/guard addresses and see if anything
  4415.                                        lines up
  4416.                                        
  4417.                                        """
  4418.                                        
  4419.                                         for bordering_room in Neighbors(destination_room, Room_List):
  4420.                                            
  4421.                                             if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  4422.                                                
  4423.                                                 for loading_plane in Shared_Transitions(destination_room, bordering_room):
  4424.                                                    
  4425.                                                      # COPY STATE
  4426.                                                     #######################################################
  4427.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  4428.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  4429.                                                    
  4430.                                                     room_copy_dict_2 = {}
  4431.                                                     for room in Room_List_Copy_2:
  4432.                                                         room_copy_dict_2[room.number] = room
  4433.                                                    
  4434.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4435.                                                    
  4436.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  4437.                                                     #######################################################
  4438.                                                    
  4439.                                                     action_list_2 = []
  4440.                                                    
  4441.                                                     loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  4442.                                                    
  4443.                                                     bordering_room_copy = room_copy_dict_2[bordering_room.number]
  4444.                                                    
  4445.                                                     Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  4446.                                                     action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  4447.                                                    
  4448.                                                    
  4449.                                                     ##### Now check for chests/deku guards
  4450.                                        
  4451.                                                     chest_guard_list = []
  4452.                                                    
  4453.                                                     for entry in Heap_Copy_2:
  4454.                                                        
  4455.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4456.                                                             chest_guard_list.append(entry)
  4457.                                                    
  4458.                                                     soln_found = False
  4459.                                                     for entry in chest_guard_list:
  4460.                                                         if (pot.address - entry.address) in Offset_List:
  4461.                                                            
  4462.                                                             action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4463.                                                            
  4464.                                                             if (pot.address - entry.address) == 0x160:
  4465.                                                                 angle_solution_count += 1
  4466.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4467.                                                             elif (pot.address - entry.address) == 0x1F0:
  4468.                                                                 position_solution_count += 1
  4469.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4470.                                
  4471.                                                             soln_found = True
  4472.                                                            
  4473.                                                     if soln_found is True:
  4474.                                                         total_action_list = action_list + action_list_transition + action_list001 + action_list_2
  4475.                                                        
  4476.                                                         # the "a" argument is important so we don't overwrite previous solutions
  4477.                                                         with open(filename, "a") as file:
  4478.                                                            
  4479.                                                             for action in total_action_list:
  4480.                                                                
  4481.                                                                 file.write(action + "\n")
  4482.                                                             file.write("-----\n")                
  4483.  
  4484.                                        
  4485.                                        
  4486.                             # If there isn't a chest/guard, superslide (into chest/guard room by assumption), then exit then reenter it (this case never happens in palace, so this is an okay assumption)
  4487.                             elif Chest_In_Room(neighbor) == False and Deku_Guard_In_Room(neighbor) == False:
  4488.                                
  4489.                                 for pot in valid_pot_list:
  4490.                                    
  4491.                                     # both bomb and smoke loaded on superslide
  4492.                                     if Grabbable_Dict_Copy[pot][0][0] == '1':
  4493.                                        
  4494.                                         action_list100 = []
  4495.                                        
  4496.                                         # COPY STATE
  4497.                                         #######################################################
  4498.                                         Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  4499.                                         Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4500.                                        
  4501.                                         room_copy_dict_2 = {}
  4502.                                         for room in Room_List_Copy_2:
  4503.                                             room_copy_dict_2[room.number] = room
  4504.                                        
  4505.                                         Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4506.                                        
  4507.                                         Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  4508.                                         #######################################################
  4509.                                        
  4510.                                         Bomb_And_Smoke_Superslide(Heap_Copy_2, neighbor_copy.number, Overlay_Dict_Copy_2)
  4511.                                         action_list100.append("Superslide with Bomb and Smoke still allocated")
  4512.                                        
  4513.                                         # The room we superslide into through the plane corresponding to the given pot
  4514.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4515.                                        
  4516.                                         destination_room_copy = room_copy_dict_2[destination_room.number]
  4517.                                         neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
  4518.                                        
  4519.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  4520.                                         superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  4521.                                        
  4522.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4523.                                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4524.                                        
  4525.                                         # Now exit the chest room
  4526.                                         Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  4527.                                         action_list100.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4528.                                        
  4529.                                         # Now reenter the chest room
  4530.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4531.                                         action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4532.                                        
  4533.                                         ##### Now check for chests/deku guards
  4534.                                        
  4535.                                         chest_guard_list = []
  4536.                                        
  4537.                                         for entry in Heap_Copy_2:
  4538.                                            
  4539.                                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4540.                                                 chest_guard_list.append(entry)
  4541.                                        
  4542.                                         soln_found = False
  4543.                                         for entry in chest_guard_list:
  4544.                                             if (pot.address - entry.address) in Offset_List:
  4545.                                                
  4546.                                                 action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4547.                                                
  4548.                                                 if (pot.address - entry.address) == 0x160:
  4549.                                                     angle_solution_count += 1
  4550.                                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4551.                                                 elif (pot.address - entry.address) == 0x1F0:
  4552.                                                     position_solution_count += 1
  4553.                                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4554.                                
  4555.                                                 soln_found = True
  4556.                                                
  4557.                                         if soln_found is True:
  4558.                                             total_action_list = action_list + action_list_transition + action_list100
  4559.                                            
  4560.                                             # the "a" argument is important so we don't overwrite previous solutions
  4561.                                             with open(filename, "a") as file:
  4562.                                                
  4563.                                                 for action in total_action_list:
  4564.                                                    
  4565.                                                     file.write(action + "\n")
  4566.                                                 file.write("-----\n")
  4567.                                    
  4568.                                    
  4569.                                    
  4570.                                     ##### Only smoke is loaded from superslide
  4571.                                     elif Grabbable_Dict_Copy[pot][0][1] == '1':
  4572.  
  4573.                                         action_list010 = []
  4574.                                        
  4575.                                         # COPY STATE
  4576.                                         #######################################################
  4577.                                         Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  4578.                                         Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4579.                                        
  4580.                                         room_copy_dict_2 = {}
  4581.                                         for room in Room_List_Copy_2:
  4582.                                             room_copy_dict_2[room.number] = room
  4583.                                        
  4584.                                         Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4585.                                        
  4586.                                         Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  4587.                                         #######################################################
  4588.                                        
  4589.                                         Allocate_Smoke(Heap_Copy_2, neighbor_copy.number, Overlay_Dict_Copy_2)
  4590.                                         action_list010.append("Superslide with Smoke still allocated")
  4591.                                        
  4592.                                         # The room we superslide into through the plane corresponding to the given pot
  4593.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4594.                                        
  4595.                                         destination_room_copy = room_copy_dict_2[destination_room.number]
  4596.                                         neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
  4597.                                        
  4598.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  4599.                                         superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  4600.                                        
  4601.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4602.                                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4603.                                        
  4604.                                         # Now exit the chest room
  4605.                                         Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  4606.                                         action_list010.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4607.                                        
  4608.                                         # Now reenter the chest room
  4609.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4610.                                         action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4611.                                        
  4612.                                         ##### Now check for chests/deku guards
  4613.                                        
  4614.                                         chest_guard_list = []
  4615.                                        
  4616.                                         for entry in Heap_Copy_2:
  4617.                                            
  4618.                                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4619.                                                 chest_guard_list.append(entry)
  4620.                                        
  4621.                                         soln_found = False
  4622.                                         for entry in chest_guard_list:
  4623.                                             if (pot.address - entry.address) in Offset_List:
  4624.                                                
  4625.                                                 action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4626.                                                
  4627.                                                 if (pot.address - entry.address) == 0x160:
  4628.                                                     angle_solution_count += 1
  4629.                                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4630.                                                 elif (pot.address - entry.address) == 0x1F0:
  4631.                                                     position_solution_count += 1
  4632.                                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4633.                                
  4634.                                                 soln_found = True
  4635.                                                
  4636.                                         if soln_found is True:
  4637.                                             total_action_list = action_list + action_list_transition + action_list010
  4638.                                            
  4639.                                             # the "a" argument is important so we don't overwrite previous solutions
  4640.                                             with open(filename, "a") as file:
  4641.                                                
  4642.                                                 for action in total_action_list:
  4643.                                                    
  4644.                                                     file.write(action + "\n")
  4645.                                                 file.write("-----\n")
  4646.  
  4647.  
  4648.  
  4649.                                     #### Bomb and Smoke are both unloaded
  4650.                                     elif Grabbable_Dict_Copy[pot][0][2] == '1':
  4651.  
  4652.                                         action_list001 = []
  4653.                                        
  4654.                                         # COPY STATE
  4655.                                         #######################################################
  4656.                                         Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  4657.                                         Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4658.                                        
  4659.                                         room_copy_dict_2 = {}
  4660.                                         for room in Room_List_Copy_2:
  4661.                                             room_copy_dict_2[room.number] = room
  4662.                                        
  4663.                                         Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4664.                                        
  4665.                                         Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  4666.                                         #######################################################
  4667.                                        
  4668.                                         # Do not allocate anything
  4669.                                         action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  4670.                                        
  4671.                                         # The room we superslide into through the plane corresponding to the given pot
  4672.                                         destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4673.                                        
  4674.                                         destination_room_copy = room_copy_dict_2[destination_room.number]
  4675.                                         neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
  4676.                                        
  4677.                                         pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  4678.                                         superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  4679.                                        
  4680.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4681.                                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4682.                                        
  4683.                                         # Now exit the chest room
  4684.                                         Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  4685.                                         action_list001.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4686.                                        
  4687.                                         # Now reenter the chest room
  4688.                                         Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  4689.                                         action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4690.                                        
  4691.                                         ##### Now check for chests/deku guards
  4692.                                        
  4693.                                         chest_guard_list = []
  4694.                                        
  4695.                                         for entry in Heap_Copy_2:
  4696.                                            
  4697.                                             if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4698.                                                 chest_guard_list.append(entry)
  4699.                                        
  4700.                                         soln_found = False
  4701.                                         for entry in chest_guard_list:
  4702.                                             if (pot.address - entry.address) in Offset_List:
  4703.                                                
  4704.                                                 action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4705.                                                
  4706.                                                 if (pot.address - entry.address) == 0x160:
  4707.                                                     angle_solution_count += 1
  4708.                                                     print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4709.                                                 elif (pot.address - entry.address) == 0x1F0:
  4710.                                                     position_solution_count += 1
  4711.                                                     print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4712.                                
  4713.                                                 soln_found = True
  4714.                                                
  4715.                                         if soln_found is True:
  4716.                                             total_action_list = action_list + action_list_transition + action_list001
  4717.                                            
  4718.                                             # the "a" argument is important so we don't overwrite previous solutions
  4719.                                             with open(filename, "a") as file:
  4720.                                                
  4721.                                                 for action in total_action_list:
  4722.                                                    
  4723.                                                     file.write(action + "\n")
  4724.                                                 file.write("-----\n")
  4725.                                        
  4726.  
  4727.                     ##### No valid grabbable actor in neighbor
  4728.                     elif neighbor not in valid_grabbable_actor_room_list:
  4729.                        
  4730.                         for new_neighbor in Neighbors(neighbor, Room_List):
  4731.                            
  4732.                             # if new neighbor has a valid grabbable actor... (Otherwise, we do nothing)
  4733.                             if new_neighbor in valid_grabbable_actor_room_list:
  4734.                                
  4735.                                
  4736.                                 for neighbor_transition in Shared_Transitions(current_room, neighbor):
  4737.                                     for new_neighbor_transition in Shared_Transitions(neighbor, new_neighbor):
  4738.                                        
  4739.                                         action_list_transition = []
  4740.                                
  4741.                                         ##### COPY THE STATE
  4742.                                         #######################################################
  4743.                                         Room_List_Copy = Copy_Room_List(Room_List)
  4744.                                         Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
  4745.                                        
  4746.                                         room_copy_dict = {}
  4747.                                         for room in Room_List_Copy:
  4748.                                             room_copy_dict[room.number] = room
  4749.                                        
  4750.                                         Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
  4751.                                        
  4752.                                         Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
  4753.                                         #######################################################
  4754.                                        
  4755.                                         neighbor_copy = room_copy_dict[neighbor.number]
  4756.                                         neighbor_transition_copy = Find_Actor_Copy(neighbor_transition, Room_List_Copy)
  4757.                                        
  4758.                                         new_neighbor_copy = room_copy_dict[new_neighbor.number]
  4759.                                         new_neighbor_transition_copy = Find_Actor_Copy(new_neighbor_transition, Room_List_Copy)
  4760.                                                                        
  4761.                                         ##### ENTER neighbor
  4762.                                        
  4763.                                         Load_Room(Heap_Copy, neighbor_copy, neighbor_transition_copy, Overlay_Dict_Copy)
  4764.                                         action_list_transition.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + neighbor_transition_copy.name + " %d" %(neighbor_transition_copy.priority))
  4765.                                        
  4766.                                         ##### ENTER new_neighbor
  4767.                                        
  4768.                                         Load_Room(Heap_Copy, new_neighbor_copy, new_neighbor_transition_copy, Overlay_Dict_Copy)
  4769.                                         action_list_transition.append("Load Room: Room %d" %(new_neighbor_copy.number) + " with " + new_neighbor_transition_copy.name + " %d" %(new_neighbor_transition_copy.priority))
  4770.                                        
  4771.                                        
  4772.                                         ##### Iterate through all pots in this room
  4773.                                
  4774.                                         valid_pot_list = []
  4775.                                         pot_address_list = []
  4776.                                        
  4777.                                         for pot in Grabbable_Dict_Copy:
  4778.                                            
  4779.                                             if Actor_Is_In_Room(new_neighbor_copy, pot) is True:
  4780.                                                 valid_pot_list.append(pot)
  4781.                                                 pot_address_list.append(pot.address)
  4782.  
  4783.                                         # If there is a chest/guard, superslide, then check neighbors for chests/guards and test all (copy state)
  4784.                                         if Chest_In_Room(new_neighbor) == True or Deku_Guard_In_Room(new_neighbor) == True:
  4785.                                            
  4786.                                             for pot in valid_pot_list:
  4787.                                                
  4788.                                                 # both bomb and smoke loaded on superslide
  4789.                                                 if Grabbable_Dict_Copy[pot][0][0] == '1':
  4790.                                                    
  4791.                                                     action_list100 = []
  4792.                                                    
  4793.                                                     # COPY STATE
  4794.                                                     #######################################################
  4795.                                                     Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  4796.                                                     Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4797.                                                    
  4798.                                                     room_copy_dict_SS = {}
  4799.                                                     for room in Room_List_Copy_SS:
  4800.                                                         room_copy_dict_SS[room.number] = room
  4801.                                                    
  4802.                                                     Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  4803.                                                    
  4804.                                                     Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  4805.                                                     #######################################################
  4806.                                                    
  4807.                                                     Bomb_And_Smoke_Superslide(Heap_Copy_SS, new_neighbor.number, Overlay_Dict_Copy_SS)
  4808.                                                     action_list100.append("Superslide with Bomb and Smoke still allocated")
  4809.                                                    
  4810.                                                     # The room we superslide into through the plane corresponding to the given pot
  4811.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4812.                                                    
  4813.                                                     destination_room_copy = room_copy_dict_SS[destination_room.number]
  4814.                                                    
  4815.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  4816.                                                     superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  4817.                                                    
  4818.                                                     Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  4819.                                                     action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4820.                                                    
  4821.                                                     """
  4822.                                                    
  4823.                                                    Now we check all neighbors of our current room (destination_room) and for
  4824.                                                    each neighbor that has a chest or deku guard in it, we will create a copy
  4825.                                                    of our copy of the state, then enter each of them through each possible
  4826.                                                    loading plane and then check the chest/guard addresses and see if anything
  4827.                                                    lines up
  4828.                                                    
  4829.                                                    """
  4830.                                                    
  4831.                                                     for bordering_room in Neighbors(destination_room, Room_List):
  4832.                                                        
  4833.                                                         if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  4834.                                                            
  4835.                                                             for loading_plane in Shared_Transitions(destination_room, bordering_room):
  4836.                                                                
  4837.                                                                  # COPY STATE
  4838.                                                                 #######################################################
  4839.                                                                 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  4840.                                                                 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  4841.                                                                
  4842.                                                                 room_copy_dict_2 = {}
  4843.                                                                 for room in Room_List_Copy_2:
  4844.                                                                     room_copy_dict_2[room.number] = room
  4845.                                                                
  4846.                                                                 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4847.                                                                
  4848.                                                                 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  4849.                                                                 #######################################################
  4850.                                                                
  4851.                                                                 action_list_2 = []
  4852.                                                                
  4853.                                                                 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  4854.                                                                
  4855.                                                                 bordering_room_copy = room_copy_dict_2[bordering_room.number]
  4856.                                                                
  4857.                                                                 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  4858.                                                                 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  4859.                                                                
  4860.                                                                
  4861.                                                                 ##### Now check for chests/deku guards
  4862.                                                    
  4863.                                                                 chest_guard_list = []
  4864.                                                                
  4865.                                                                 for entry in Heap_Copy_2:
  4866.                                                                    
  4867.                                                                     if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4868.                                                                         chest_guard_list.append(entry)
  4869.                                                                
  4870.                                                                 soln_found = False
  4871.                                                                 for entry in chest_guard_list:
  4872.                                                                     if (pot.address - entry.address) in Offset_List:
  4873.                                                                        
  4874.                                                                         action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4875.                                                                        
  4876.                                                                         if (pot.address - entry.address) == 0x160:
  4877.                                                                             angle_solution_count += 1
  4878.                                                                             print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4879.                                                                         elif (pot.address - entry.address) == 0x1F0:
  4880.                                                                             position_solution_count += 1
  4881.                                                                             print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4882.                                
  4883.                                                                         soln_found = True
  4884.                                                                        
  4885.                                                                 if soln_found is True:
  4886.                                                                     total_action_list = action_list + action_list_transition + action_list100 + action_list_2
  4887.                                                                    
  4888.                                                                     # the "a" argument is important so we don't overwrite previous solutions
  4889.                                                                     with open(filename, "a") as file:
  4890.                                                                        
  4891.                                                                         for action in total_action_list:
  4892.                                                                            
  4893.                                                                             file.write(action + "\n")
  4894.                                                                         file.write("-----\n")
  4895.                                                
  4896.                                                    
  4897.                                                    
  4898.                                                 ##### Only smoke is loaded from superslide
  4899.                                                 elif Grabbable_Dict_Copy[pot][0][1] == '1':
  4900.                                                    
  4901.                                                     action_list010 = []
  4902.                                                    
  4903.                                                     # COPY STATE
  4904.                                                     #######################################################
  4905.                                                     Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  4906.                                                     Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  4907.                                                    
  4908.                                                     room_copy_dict_SS = {}
  4909.                                                     for room in Room_List_Copy_SS:
  4910.                                                         room_copy_dict_SS[room.number] = room
  4911.                                                    
  4912.                                                     Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  4913.                                                    
  4914.                                                     Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  4915.                                                     #######################################################
  4916.                                                    
  4917.                                                     Allocate_Smoke(Heap_Copy_SS, new_neighbor.number, Overlay_Dict_Copy_SS)
  4918.                                                     action_list010.append("Superslide with Smoke still allocated")
  4919.                                                    
  4920.                                                     # The room we superslide into through the plane corresponding to the given pot
  4921.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  4922.                                                    
  4923.                                                     destination_room_copy = room_copy_dict_SS[destination_room.number]
  4924.                                                    
  4925.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  4926.                                                     superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  4927.                                                    
  4928.                                                     Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  4929.                                                     action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  4930.                                                    
  4931.                                                     """
  4932.                                                    
  4933.                                                    Now we check all neighbors of our current room (destination_room) and for
  4934.                                                    each neighbor that has a chest or deku guard in it, we will create a copy
  4935.                                                    of our copy of the state, then enter each of them through each possible
  4936.                                                    loading plane and then check the chest/guard addresses and see if anything
  4937.                                                    lines up
  4938.                                                    
  4939.                                                    """
  4940.                                                    
  4941.                                                     for bordering_room in Neighbors(destination_room, Room_List):
  4942.                                                        
  4943.                                                         if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  4944.                                                            
  4945.                                                             for loading_plane in Shared_Transitions(destination_room, bordering_room):
  4946.                                                                
  4947.                                                                  # COPY STATE
  4948.                                                                 #######################################################
  4949.                                                                 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  4950.                                                                 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  4951.                                                                
  4952.                                                                 room_copy_dict_2 = {}
  4953.                                                                 for room in Room_List_Copy_2:
  4954.                                                                     room_copy_dict_2[room.number] = room
  4955.                                                                
  4956.                                                                 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  4957.                                                                
  4958.                                                                 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  4959.                                                                 #######################################################
  4960.                                                                
  4961.                                                                 action_list_2 = []
  4962.                                                                
  4963.                                                                 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  4964.                                                                
  4965.                                                                 bordering_room_copy = room_copy_dict_2[bordering_room.number]
  4966.                                                                
  4967.                                                                 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  4968.                                                                 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  4969.                                                                
  4970.                                                                
  4971.                                                                 ##### Now check for chests/deku guards
  4972.                                                    
  4973.                                                                 chest_guard_list = []
  4974.                                                                
  4975.                                                                 for entry in Heap_Copy_2:
  4976.                                                                    
  4977.                                                                     if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  4978.                                                                         chest_guard_list.append(entry)
  4979.                                                                
  4980.                                                                 soln_found = False
  4981.                                                                 for entry in chest_guard_list:
  4982.                                                                     if (pot.address - entry.address) in Offset_List:
  4983.                                                                        
  4984.                                                                         action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  4985.                                                                        
  4986.                                                                         if (pot.address - entry.address) == 0x160:
  4987.                                                                             angle_solution_count += 1
  4988.                                                                             print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4989.                                                                         elif (pot.address - entry.address) == 0x1F0:
  4990.                                                                             position_solution_count += 1
  4991.                                                                             print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  4992.                                
  4993.                                                                         soln_found = True
  4994.                                                                        
  4995.                                                                 if soln_found is True:
  4996.                                                                     total_action_list = action_list + action_list_transition + action_list010 + action_list_2
  4997.                                                                    
  4998.                                                                     # the "a" argument is important so we don't overwrite previous solutions
  4999.                                                                     with open(filename, "a") as file:
  5000.                                                                        
  5001.                                                                         for action in total_action_list:
  5002.                                                                            
  5003.                                                                             file.write(action + "\n")
  5004.                                                                         file.write("-----\n")
  5005.            
  5006.            
  5007.                                                 #### Bomb and Smoke are both unloaded
  5008.                                                 elif Grabbable_Dict_Copy[pot][0][2] == '1':
  5009.                                                    
  5010.                                                     action_list001 = []
  5011.                                                    
  5012.                                                     # COPY STATE
  5013.                                                     #######################################################
  5014.                                                     Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
  5015.                                                     Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
  5016.                                                    
  5017.                                                     room_copy_dict_SS = {}
  5018.                                                     for room in Room_List_Copy_SS:
  5019.                                                         room_copy_dict_SS[room.number] = room
  5020.                                                    
  5021.                                                     Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
  5022.                                                    
  5023.                                                     Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
  5024.                                                     #######################################################
  5025.                                                    
  5026.                                                     # Do not allocate anything
  5027.                                                     action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  5028.                                                    
  5029.                                                     # The room we superslide into through the plane corresponding to the given pot
  5030.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  5031.                                                    
  5032.                                                     destination_room_copy = room_copy_dict_SS[destination_room.number]
  5033.                                                    
  5034.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
  5035.                                                     superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
  5036.                                                    
  5037.                                                     Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
  5038.                                                     action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5039.                                                    
  5040.                                                     """
  5041.                                                    
  5042.                                                    Now we check all neighbors of our current room (destination_room) and for
  5043.                                                    each neighbor that has a chest or deku guard in it, we will create a copy
  5044.                                                    of our copy of the state, then enter each of them through each possible
  5045.                                                    loading plane and then check the chest/guard addresses and see if anything
  5046.                                                    lines up
  5047.                                                    
  5048.                                                    """
  5049.                                                    
  5050.                                                     for bordering_room in Neighbors(destination_room, Room_List):
  5051.                                                        
  5052.                                                         if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
  5053.                                                            
  5054.                                                             for loading_plane in Shared_Transitions(destination_room, bordering_room):
  5055.                                                                
  5056.                                                                  # COPY STATE
  5057.                                                                 #######################################################
  5058.                                                                 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
  5059.                                                                 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
  5060.                                                                
  5061.                                                                 room_copy_dict_2 = {}
  5062.                                                                 for room in Room_List_Copy_2:
  5063.                                                                     room_copy_dict_2[room.number] = room
  5064.                                                                
  5065.                                                                 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
  5066.                                                                
  5067.                                                                 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
  5068.                                                                 #######################################################
  5069.                                                                
  5070.                                                                 action_list_2 = []
  5071.                                                                
  5072.                                                                 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
  5073.                                                                
  5074.                                                                 bordering_room_copy = room_copy_dict_2[bordering_room.number]
  5075.                                                                
  5076.                                                                 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
  5077.                                                                 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
  5078.                                                                
  5079.                                                                
  5080.                                                                 ##### Now check for chests/deku guards
  5081.                                                    
  5082.                                                                 chest_guard_list = []
  5083.                                                                
  5084.                                                                 for entry in Heap_Copy_2:
  5085.                                                                    
  5086.                                                                     if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  5087.                                                                         chest_guard_list.append(entry)
  5088.                                                                
  5089.                                                                 soln_found = False
  5090.                                                                 for entry in chest_guard_list:
  5091.                                                                     if (pot.address - entry.address) in Offset_List:
  5092.                                                                        
  5093.                                                                         action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  5094.                                                                        
  5095.                                                                         if (pot.address - entry.address) == 0x160:
  5096.                                                                             angle_solution_count += 1
  5097.                                                                             print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5098.                                                                         elif (pot.address - entry.address) == 0x1F0:
  5099.                                                                             position_solution_count += 1
  5100.                                                                             print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5101.                                
  5102.                                                                         soln_found = True
  5103.                                                                        
  5104.                                                                 if soln_found is True:
  5105.                                                                     total_action_list = action_list + action_list_transition + action_list001 + action_list_2
  5106.                                                                    
  5107.                                                                     # the "a" argument is important so we don't overwrite previous solutions
  5108.                                                                     with open(filename, "a") as file:
  5109.                                                                        
  5110.                                                                         for action in total_action_list:
  5111.                                                                            
  5112.                                                                             file.write(action + "\n")
  5113.                                                                         file.write("-----\n")
  5114.                                                
  5115.                                                
  5116.                                                
  5117.                                         # If there isn't a chest/guard, superslide (into chest/guard room by assumption), then exit then reenter it (this case never happens in palace, so this is an okay assumption)
  5118.                                         elif Chest_In_Room(new_neighbor) == False and Deku_Guard_In_Room(new_neighbor) == False:
  5119.                                            
  5120.                                             for pot in valid_pot_list:
  5121.                                                
  5122.                                                 # both bomb and smoke loaded on superslide
  5123.                                                 if Grabbable_Dict_Copy[pot][0][0] == '1':
  5124.                                                    
  5125.                                                     action_list100 = []
  5126.                                                    
  5127.                                                     # COPY STATE
  5128.                                                     #######################################################
  5129.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  5130.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  5131.                                                    
  5132.                                                     room_copy_dict_2 = {}
  5133.                                                     for room in Room_List_Copy_2:
  5134.                                                         room_copy_dict_2[room.number] = room
  5135.                                                    
  5136.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  5137.                                                    
  5138.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  5139.                                                     #######################################################
  5140.                                                    
  5141.                                                     Bomb_And_Smoke_Superslide(Heap_Copy_2, new_neighbor_copy.number, Overlay_Dict_Copy_2)
  5142.                                                     action_list100.append("Superslide with Bomb and Smoke still allocated")
  5143.                                                    
  5144.                                                     # The room we superslide into through the plane corresponding to the given pot
  5145.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  5146.                                                    
  5147.                                                     destination_room_copy = room_copy_dict_2[destination_room.number]
  5148.                                                     new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
  5149.                                                    
  5150.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  5151.                                                     superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  5152.                                                    
  5153.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5154.                                                     action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5155.                                                    
  5156.                                                     # Now exit the chest room
  5157.                                                     Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  5158.                                                     action_list100.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5159.                                                    
  5160.                                                     # Now reenter the chest room
  5161.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5162.                                                     action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5163.                                                    
  5164.                                                     ##### Now check for chests/deku guards
  5165.                                                    
  5166.                                                     chest_guard_list = []
  5167.                                                    
  5168.                                                     for entry in Heap_Copy_2:
  5169.                                                        
  5170.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  5171.                                                             chest_guard_list.append(entry)
  5172.                                                    
  5173.                                                     soln_found = False
  5174.                                                     for entry in chest_guard_list:
  5175.                                                         if (pot.address - entry.address) in Offset_List:
  5176.                                                            
  5177.                                                             action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  5178.                                                            
  5179.                                                             if (pot.address - entry.address) == 0x160:
  5180.                                                                 angle_solution_count += 1
  5181.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5182.                                                             elif (pot.address - entry.address) == 0x1F0:
  5183.                                                                 position_solution_count += 1
  5184.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5185.                                
  5186.                                                             soln_found = True
  5187.                                                            
  5188.                                                     if soln_found is True:
  5189.                                                         total_action_list = action_list + action_list_transition + action_list100
  5190.                                                        
  5191.                                                         # the "a" argument is important so we don't overwrite previous solutions
  5192.                                                         with open(filename, "a") as file:
  5193.                                                            
  5194.                                                             for action in total_action_list:
  5195.                                                                
  5196.                                                                 file.write(action + "\n")
  5197.                                                             file.write("-----\n")
  5198.                                                
  5199.                                                
  5200.                                                
  5201.                                                 ##### Only smoke is loaded from superslide
  5202.                                                 elif Grabbable_Dict_Copy[pot][0][1] == '1':
  5203.            
  5204.                                                     action_list010 = []
  5205.                                                    
  5206.                                                     # COPY STATE
  5207.                                                     #######################################################
  5208.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  5209.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  5210.                                                    
  5211.                                                     room_copy_dict_2 = {}
  5212.                                                     for room in Room_List_Copy_2:
  5213.                                                         room_copy_dict_2[room.number] = room
  5214.                                                    
  5215.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  5216.                                                    
  5217.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  5218.                                                     #######################################################
  5219.                                                    
  5220.                                                     Allocate_Smoke(Heap_Copy_2, new_neighbor_copy.number, Overlay_Dict_Copy_2)
  5221.                                                     action_list010.append("Superslide with Smoke still allocated")
  5222.                                                    
  5223.                                                     # The room we superslide into through the plane corresponding to the given pot
  5224.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  5225.                                                    
  5226.                                                     destination_room_copy = room_copy_dict_2[destination_room.number]
  5227.                                                     new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
  5228.                                                    
  5229.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  5230.                                                     superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  5231.                                                    
  5232.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5233.                                                     action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5234.                                                    
  5235.                                                     # Now exit the chest room
  5236.                                                     Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  5237.                                                     action_list010.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5238.                                                    
  5239.                                                     # Now reenter the chest room
  5240.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5241.                                                     action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5242.                                                    
  5243.                                                     ##### Now check for chests/deku guards
  5244.                                                    
  5245.                                                     chest_guard_list = []
  5246.                                                    
  5247.                                                     for entry in Heap_Copy_2:
  5248.                                                        
  5249.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  5250.                                                             chest_guard_list.append(entry)
  5251.                                                    
  5252.                                                     soln_found = False
  5253.                                                     for entry in chest_guard_list:
  5254.                                                         if (pot.address - entry.address) in Offset_List:
  5255.                                                            
  5256.                                                             action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  5257.                                                            
  5258.                                                             if (pot.address - entry.address) == 0x160:
  5259.                                                                 angle_solution_count += 1
  5260.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5261.                                                             elif (pot.address - entry.address) == 0x1F0:
  5262.                                                                 position_solution_count += 1
  5263.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5264.                                
  5265.                                                             soln_found = True
  5266.                                                            
  5267.                                                     if soln_found is True:
  5268.                                                         total_action_list = action_list + action_list_transition + action_list010
  5269.                                                        
  5270.                                                         # the "a" argument is important so we don't overwrite previous solutions
  5271.                                                         with open(filename, "a") as file:
  5272.                                                            
  5273.                                                             for action in total_action_list:
  5274.                                                                
  5275.                                                                 file.write(action + "\n")
  5276.                                                             file.write("-----\n")
  5277.            
  5278.            
  5279.            
  5280.                                                 #### Bomb and Smoke are both unloaded
  5281.                                                 elif Grabbable_Dict_Copy[pot][0][2] == '1':
  5282.            
  5283.                                                     action_list001 = []
  5284.                                                    
  5285.                                                     # COPY STATE
  5286.                                                     #######################################################
  5287.                                                     Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
  5288.                                                     Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
  5289.                                                    
  5290.                                                     room_copy_dict_2 = {}
  5291.                                                     for room in Room_List_Copy_2:
  5292.                                                         room_copy_dict_2[room.number] = room
  5293.                                                    
  5294.                                                     Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
  5295.                                                    
  5296.                                                     Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
  5297.                                                     #######################################################
  5298.                                                    
  5299.                                                     # Do not allocate anything
  5300.                                                     action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
  5301.                                                    
  5302.                                                     # The room we superslide into through the plane corresponding to the given pot
  5303.                                                     destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
  5304.                                                    
  5305.                                                     destination_room_copy = room_copy_dict_2[destination_room.number]
  5306.                                                     new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
  5307.                                                    
  5308.                                                     pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
  5309.                                                     superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
  5310.                                                    
  5311.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5312.                                                     action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5313.                                                    
  5314.                                                     # Now exit the chest room
  5315.                                                     Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
  5316.                                                     action_list001.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5317.                                                    
  5318.                                                     # Now reenter the chest room
  5319.                                                     Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
  5320.                                                     action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
  5321.                                                    
  5322.                                                     ##### Now check for chests/deku guards
  5323.                                                    
  5324.                                                     chest_guard_list = []
  5325.                                                    
  5326.                                                     for entry in Heap_Copy_2:
  5327.                                                        
  5328.                                                         if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
  5329.                                                             chest_guard_list.append(entry)
  5330.                                                    
  5331.                                                     soln_found = False
  5332.                                                     for entry in chest_guard_list:
  5333.                                                         if (pot.address - entry.address) in Offset_List:
  5334.                                                            
  5335.                                                             action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
  5336.                                                            
  5337.                                                             if (pot.address - entry.address) == 0x160:
  5338.                                                                 angle_solution_count += 1
  5339.                                                                 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5340.                                                             elif (pot.address - entry.address) == 0x1F0:
  5341.                                                                 position_solution_count += 1
  5342.                                                                 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
  5343.                                
  5344.                                                             soln_found = True
  5345.                                                            
  5346.                                                     if soln_found is True:
  5347.                                                         total_action_list = action_list + action_list_transition + action_list001
  5348.                                                        
  5349.                                                         # the "a" argument is important so we don't overwrite previous solutions
  5350.                                                         with open(filename, "a") as file:
  5351.                                                            
  5352.                                                             for action in total_action_list:
  5353.                                                                
  5354.                                                                 file.write(action + "\n")
  5355.                                                             file.write("-----\n")
  5356.                                    
  5357.  
  5358.  
  5359.  
  5360. ###############################################################################
  5361. ###############################################################################
  5362. ###############################################################################
  5363. ###############################################################################
  5364. ###############################################################################
  5365. ###############################################################################
  5366. ###############################################################################
  5367. ###############################################################################
  5368. ###############################################################################
  5369. ###############################################################################
  5370. ###############################################################################
  5371. ###############################################################################
  5372. ###############################################################################
  5373. ###############################################################################
  5374. ###############################################################################
  5375. ###############################################################################
  5376. ###############################################################################
  5377. ###############################################################################
  5378. ###############################################################################
  5379. ###############################################################################
  5380. ###############################################################################
  5381. ###############################################################################
  5382. ###############################################################################
  5383. ###############################################################################
  5384. ###############################################################################
  5385. ###############################################################################
  5386. ###############################################################################
  5387. ###############################################################################
  5388. ###############################################################################
  5389. ###############################################################################
  5390. ###############################################################################
  5391. ###############################################################################
  5392. ###############################################################################
  5393. ###############################################################################
  5394. ###############################################################################
  5395. ###############################################################################
  5396. ###############################################################################
  5397. ###############################################################################
  5398. ###############################################################################
  5399. ###############################################################################
  5400. ###############################################################################
  5401. ###############################################################################
  5402. ###############################################################################
  5403. ###############################################################################
  5404. ###############################################################################
  5405. ###############################################################################
  5406. ###############################################################################
  5407. ###############################################################################
  5408.                                                            
  5409.                    
  5410.                                          
  5411.                                                            
  5412.                                                            
  5413.                                                            
  5414.                                                            
  5415. """
  5416.  
  5417.   Before proceeding, we should define all of the transitions we plan on passing through
  5418.  
  5419.   Since "Beneath the Graveyard" is relatively simple and I currently only want to consider
  5420.   passing through a single plane, I will just define Plane_1 to be the plane shared between
  5421.   Room0 and Room1
  5422.  
  5423.   This loading plane happens the be the second element in Room0_queue, so I will define it based on that
  5424.  
  5425. """
  5426.  
  5427. Oceanside_Plane_0 = Oceanside_Room3_queue[0]
  5428.  
  5429.  
  5430.  
  5431.  
  5432.  
  5433. """
  5434.  
  5435.    Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
  5436.    we want to attempt to use for superslide SRM where the keys are the grabbable
  5437.    actors and the values are lists with 3-bit strings where each bit means:
  5438.        
  5439.        100 : Possible to enter Plane with both Bomb and Smoke loaded
  5440.        010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
  5441.        001 : Possible to enter Plane with no Smoke loaded
  5442.    
  5443.    and Transitions, where the transitions are the ones you can superslide through
  5444.    
  5445.    
  5446. """
  5447.  
  5448. Oceanside_Grabbable_dict = {
  5449.         Oceanside_Room3_queue[6] : ['010', Oceanside_Plane_0],
  5450.         Oceanside_Room3_queue[7] : ['010', Oceanside_Plane_0]
  5451.         }                                                        
  5452.                                                            
  5453.  
  5454. Hardcoded_Allocation_List_0 = [
  5455.         'Fish',
  5456.         'Fish',
  5457.         'Bugs',
  5458.         'Bugs',
  5459.         'Smoke',
  5460.         'Chu',
  5461.         'Chu',
  5462.         'Chu',
  5463.         'Arrow',
  5464.         'Arrow',
  5465.         'Arrow',
  5466.         'Arrow',
  5467.         'Arrow',
  5468.         'Bomb',
  5469.         'Bomb',
  5470.         'Bomb',
  5471.         'Zora Fins',
  5472.         'Hookshot',
  5473.         'Charged Spin Attack'
  5474.         ]                                                          
  5475.  
  5476. Hardcoded_Allocation_List_2 = [
  5477.         'Smoke',
  5478.         'Arrow',
  5479.         'Arrow',
  5480.         'Arrow',
  5481.         'Arrow',
  5482.         'Arrow',
  5483.         'Bomb',
  5484.         'Bomb',
  5485.         'Bomb',
  5486.         'Hookshot',
  5487.         'Charged Spin Attack'
  5488.         ]
  5489.  
  5490. Hardcoded_Allocation_List_2_G = [
  5491.         'Gold Skulltula'
  5492.         'Smoke',
  5493.         'Arrow',
  5494.         'Arrow',
  5495.         'Arrow',
  5496.         'Arrow',
  5497.         'Arrow',
  5498.         'Bomb',
  5499.         'Bomb',
  5500.         'Bomb',
  5501.         'Hookshot',
  5502.         'Charged Spin Attack'
  5503.         ]
  5504.  
  5505. Hardcoded_Allocation_List_3 = [
  5506.         'Bomb',
  5507.         'Bomb',
  5508.         'Bomb',
  5509.         'Hookshot',
  5510.         'Charged Spin Attack'
  5511.         ]
  5512.  
  5513. Hardcoded_Allocation_List_4 = [
  5514.         'Arrow',
  5515.         'Arrow',
  5516.         'Arrow',
  5517.         'Arrow',
  5518.         'Arrow',
  5519.         'Bomb',
  5520.         'Bomb',
  5521.         'Bomb',
  5522.         'Hookshot',
  5523.         'Charged Spin Attack'
  5524.         ]
  5525.  
  5526.  
  5527. Allocation_List_Dict_Grave_0 = {
  5528.         0 : Hardcoded_Allocation_List_3,
  5529.         1 : Hardcoded_Allocation_List_3
  5530.         }
  5531.  
  5532.  
  5533. Allocation_List_Dict_Oceanside_0 = {
  5534.         3 : Hardcoded_Allocation_List_2_G,
  5535.         4 : Hardcoded_Allocation_List_2
  5536.         }
  5537.  
  5538. # CHANGE PATH TO WHERE YOU HAVE YOUR TEXT FILE SAVED
  5539. save_path = "C:\\Users\\xyzabc\\Documents\\Bizhawk RAM Watch\\scripts\\"
  5540. name_of_file = "Grave Chain 0"
  5541. complete_name = save_path + name_of_file + ".txt"  
  5542.  
  5543. Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
  5544.  
  5545. ##### OCEANSIDE
  5546. #Randomized_Solver(Oceanside_Room3, Oceanside_Room_List, 5, Allocation_List_Dict_Oceanside_0, Oceanside_Grabbable_dict, Overlay_dict, complete_name, [0x160, 0x1F0], Heap)
  5547.  
  5548.  
  5549. ##### BENEATH THE GRAVEYARD
  5550. Randomized_Solver(Room1, Room_List, 2, Allocation_List_Dict_Grave_0, Grabbable_dict, Overlay_dict, complete_name, [0x160, 0x1F0], Heap)
  5551.  
  5552. """
  5553.  
  5554. THIS COPY OF THE SCRIPT HARDCODES THE INITIAL HEAP INTO THE SOLVER FUNCTION TO LOOK
  5555. FOR SRM CHAINS IN BENEATH THE GRAVEYARD
  5556.  
  5557. """
  5558.  
  5559.  
  5560. """
  5561.  
  5562. SOME ASSUMPTIONS ABOUT THIS SCRIPT:
  5563.    
  5564.    - THE SOLVER AUTOMATICALLY CLEARS ALL BAD BATS AT THE START
  5565.    
  5566.    - WE DO NOT DEALLOCATE WEBS OR GOLD SKULLTULAS IN OCEANSIDE BECAUSE WE WANT
  5567.    A SETUP THAT DOES NOT NEED SONG OF TIME STORAGE TO DO REPEATEDLY. EVEN IF IT
  5568.    ALLOWED DEALLOCATIONG GOLD SKULLTULAS, IT DOES NOT ACCOUNT FOR THE TOKENS AND
  5569.    IT ASSUMES DEALLOCATING A GOLD SKULLTULA IS EQUIVALENT TO PICKING UP ITS TOKEN
  5570.    
  5571.    - WE ASSUME THAT WE ALWAYS PERFORM THE DEALLOCATION STEPS BEFORE THE ALLOCATION
  5572.    STEPS BECAUSE IT IS EASIER TO DEAL WITH SOLUTIONS WITH THIS QUALITY
  5573.    
  5574.    - THIS SCRIPT HARDCODES HOW WE DEALLOCATE THE 01E7 BONK ACTORS FOR THE OCEANSIDE
  5575.    ROOM 3 TABLE
  5576.    
  5577.    - ALLOCATING GOLD SKULLTULAS IS SPECIFIC TO ROOM 3 OF OCEANSIDE (SHOOTING THE
  5578.    PAINTING ALLOCATES A GOLD SKULLTULA)
  5579.    
  5580.    TODO: (DEKU PALACE CONTEXT) WANT A WAY TO ASSERT THAT A POT NEEDS
  5581.    TO BREAK BEFORE PALACE SUPERSLIDE FOR ONE OF THE POTS (I THINK; NEEDS TESTING)
  5582.    
  5583.    
  5584.  
  5585.  
  5586. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement