def check_required_paths(paths, world, player):
    for dungeon_name in paths.keys():
        builder = world.dungeon_layouts[player][dungeon_name]
        if (len(paths[dungeon_name]) > 0):
            states_to_explore = defaultdict(list)
            for path in paths[dungeon_name]:
                if (type(path) is tuple):
                    states_to_explore[tuple([path[0]])].append(path[1])
                else:
                    states_to_explore[tuple(builder.path_entrances)].append(path)
            cached_initial_state = None
            for (start_regs, dest_regs) in states_to_explore.items():
                check_paths = convert_regions(dest_regs, world, player)
                start_regions = convert_regions(start_regs, world, player)
                initial = (start_regs == tuple(builder.path_entrances))
                if ((not initial) or (cached_initial_state is None)):
                    init = determine_init_crystal(initial, cached_initial_state, start_regions)
                    state = ExplorationState(init, dungeon_name)
                    for region in start_regions:
                        state.visit_region(region)
                        state.add_all_doors_check_unattached(region, world, player)
                    explore_state(state, world, player)
                    if (initial and (cached_initial_state is None)):
                        cached_initial_state = state
                else:
                    state = cached_initial_state
                (valid, bad_region) = check_if_regions_visited(state, check_paths)
                if (not valid):
                    if check_for_pinball_fix(state, bad_region, world, player):
                        explore_state(state, world, player)
                        (valid, bad_region) = check_if_regions_visited(state, check_paths)
                if (not valid):
                    raise Exception(('%s cannot reach %s' % (dungeon_name, bad_region.name)))
def check_required_paths(paths, world, player):
    for dungeon_name in paths.keys():
        builder = world.dungeon_layouts[player][dungeon_name]
        if (len(paths[dungeon_name]) > 0):
            states_to_explore = defaultdict(list)
            for path in paths[dungeon_name]:
                if (type(path) is tuple):
                    states_to_explore[tuple([path[0]])].append(path[1])
                else:
                    states_to_explore[tuple(builder.path_entrances)].append(path)
            cached_initial_state = None
            for (start_regs, dest_regs) in states_to_explore.items():
                check_paths = convert_regions(dest_regs, world, player)
                start_regions = convert_regions(start_regs, world, player)
                initial = (start_regs == tuple(builder.path_entrances))
                if ((not initial) or (cached_initial_state is None)):
                    init = determine_init_crystal(initial, cached_initial_state, start_regions)
                    state = ExplorationState(init, dungeon_name)
                    for region in start_regions:
                        state.visit_region(region)
                        state.add_all_doors_check_unattached(region, world, player)
                    explore_state(state, world, player)
                    if (initial and (cached_initial_state is None)):
                        cached_initial_state = state
                else:
                    state = cached_initial_state
                (valid, bad_region) = check_if_regions_visited(state, check_paths)
                if (not valid):
                    if check_for_pinball_fix(state, bad_region, world, player):
                        explore_state(state, world, player)
                        (valid, bad_region) = check_if_regions_visited(state, check_paths)
                if (not valid):
                    raise Exception(('%s cannot reach %s' % (dungeon_name, bad_region.name)))