def reassign_key_doors(builder, world, player):
    logger = logging.getLogger('')
    logger.debug('Key doors for %s', builder.name)
    proposal = builder.key_door_proposal
    flat_proposal = flatten_pair_list(proposal)
    queue = deque(find_current_key_doors(builder))
    while (len(queue) > 0):
        d = queue.pop()
        if ((d.type is DoorType.SpiralStairs) and (d not in proposal)):
            room = world.get_room(d.roomIndex, player)
            if (room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow):
                room.delete(d.doorListPos)
            elif (len(room.doorList) > 1):
                room.mirror(d.doorListPos)
            else:
                room.delete(d.doorListPos)
            d.smallKey = False
        elif ((d.type is DoorType.Interior) and (d not in flat_proposal) and (d.dest not in flat_proposal)):
            world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
            d.smallKey = False
            d.dest.smallKey = False
            queue.remove(d.dest)
        elif ((d.type is DoorType.Normal) and (d not in flat_proposal)):
            world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
            d.smallKey = False
            for dp in world.paired_doors[player]:
                if ((dp.door_a == d.name) or (dp.door_b == d.name)):
                    dp.pair = False
    for obj in proposal:
        if (type(obj) is tuple):
            d1 = obj[0]
            d2 = obj[1]
            if (d1.type is DoorType.Interior):
                change_door_to_small_key(d1, world, player)
                d2.smallKey = True
            else:
                names = [d1.name, d2.name]
                found = False
                for dp in world.paired_doors[player]:
                    if ((dp.door_a in names) and (dp.door_b in names)):
                        dp.pair = True
                        found = True
                    elif (dp.door_a in names):
                        dp.pair = False
                    elif (dp.door_b in names):
                        dp.pair = False
                if (not found):
                    world.paired_doors[player].append(PairedDoor(d1.name, d2.name))
                    change_door_to_small_key(d1, world, player)
                    change_door_to_small_key(d2, world, player)
            world.spoiler.set_door_type(((d1.name + ' <-> ') + d2.name), 'Key Door', player)
            logger.debug('Key Door: %s', ((d1.name + ' <-> ') + d2.name))
        else:
            d = obj
            if (d.type is DoorType.Interior):
                change_door_to_small_key(d, world, player)
                d.dest.smallKey = True
            elif (d.type is DoorType.SpiralStairs):
                pass
            elif (d.type is DoorType.Normal):
                change_door_to_small_key(d, world, player)
            world.spoiler.set_door_type(d.name, 'Key Door', player)
            logger.debug('Key Door: %s', d.name)
def reassign_key_doors(builder, world, player):
    logger = logging.getLogger()
    logger.debug('Key doors for %s', builder.name)
    proposal = builder.key_door_proposal
    flat_proposal = flatten_pair_list(proposal)
    queue = deque(find_current_key_doors(builder))
    while (len(queue) > 0):
        d = queue.pop()
        if ((d.type is DoorType.SpiralStairs) and (d not in proposal)):
            room = world.get_room(d.roomIndex, player)
            if (room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow):
                room.delete(d.doorListPos)
            elif (len(room.doorList) > 1):
                room.mirror(d.doorListPos)
            else:
                room.delete(d.doorListPos)
            d.smallKey = False
        elif ((d.type is DoorType.Interior) and (d not in flat_proposal) and (d.dest not in flat_proposal)):
            world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
            d.smallKey = False
            d.dest.smallKey = False
            queue.remove(d.dest)
        elif ((d.type is DoorType.Normal) and (d not in flat_proposal)):
            world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
            d.smallKey = False
            for dp in world.paired_doors[player]:
                if ((dp.door_a == d.name) or (dp.door_b == d.name)):
                    dp.pair = False
    for obj in proposal:
        if (type(obj) is tuple):
            d1 = obj[0]
            d2 = obj[1]
            if (d1.type is DoorType.Interior):
                change_door_to_small_key(d1, world, player)
                d2.smallKey = True
            else:
                names = [d1.name, d2.name]
                found = False
                for dp in world.paired_doors[player]:
                    if ((dp.door_a in names) and (dp.door_b in names)):
                        dp.pair = True
                        found = True
                    elif (dp.door_a in names):
                        dp.pair = False
                    elif (dp.door_b in names):
                        dp.pair = False
                if (not found):
                    world.paired_doors[player].append(PairedDoor(d1.name, d2.name))
                    change_door_to_small_key(d1, world, player)
                    change_door_to_small_key(d2, world, player)
            world.spoiler.set_door_type(((d1.name + ' <-> ') + d2.name), 'Key Door', player)
            logger.debug('Key Door: %s', ((d1.name + ' <-> ') + d2.name))
        else:
            d = obj
            if (d.type is DoorType.Interior):
                change_door_to_small_key(d, world, player)
                d.dest.smallKey = True
            elif (d.type is DoorType.SpiralStairs):
                pass
            elif (d.type is DoorType.Normal):
                change_door_to_small_key(d, world, player)
            world.spoiler.set_door_type(d.name, 'Key Door', player)
            logger.debug('Key Door: %s', d.name)