"use strict";
/**
 * These functions have to do with the room grid index for the level (i.e. the position that the
 * room is on the grid that represents the map for the level).
 *
 * For functions having to do with the grid index inside of the room, see the "Room Grid" functions.
 *
 * @module
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.vectorToRoomGridIndex = exports.roomGridIndexToVector = exports.roomExists = exports.newRoom = exports.isRoomInsideGrid = exports.isRedKeyRoom = exports.isDoorSlotValidAtGridIndexForRedRoom = exports.isDoorSlotValidAtGridIndex = exports.isDeadEnd = exports.inRedKeyRoom = exports.inGrid = exports.getRoomShapeAdjacentNonExistingGridIndexes = exports.getRoomShapeAdjacentGridIndexes = exports.getRoomShapeAdjacentGridIndexDeltas = exports.getRoomShapeAdjacentExistingGridIndexes = exports.getRoomGridIndexesForType = exports.getRoomDescriptorsForType = exports.getRoomAdjacentGridIndexes = exports.getNewRoomCandidatesForLevel = exports.getNewRoomCandidatesBesideRoom = exports.getNewRoomCandidate = exports.getAllRoomGridIndexes = exports.getAdjacentRoomGridIndexes = exports.getAdjacentNonExistingRoomGridIndexes = exports.getAdjacentExistingRoomGridIndexes = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const constants_1 = require("../core/constants");
const roomShapeToDoorSlotsToGridIndexDelta_1 = require("../objects/roomShapeToDoorSlotsToGridIndexDelta");
const array_1 = require("./array");
const doors_1 = require("./doors");
const flag_1 = require("./flag");
const map_1 = require("./map");
const rng_1 = require("./rng");
const roomData_1 = require("./roomData");
const roomShape_1 = require("./roomShape");
const rooms_1 = require("./rooms");
const LEFT = -1;
const UP = -constants_1.LEVEL_GRID_ROW_WIDTH;
const RIGHT = 1;
const DOWN = constants_1.LEVEL_GRID_ROW_WIDTH;
const ADJACENT_ROOM_GRID_INDEX_DELTAS = [LEFT, UP, RIGHT, DOWN];
/**
 * Helper function to get only the adjacent room grid indexes that exist (i.e. have room data).
 *
 * This is just a filtering of the results of the `getAdjacentExistingRoomGridIndexes` function. See
 * that function for more information.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function getAdjacentExistingRoomGridIndexes(roomGridIndex) {
    const adjacentRoomGridIndexes = getAdjacentRoomGridIndexes(roomGridIndex);
    return adjacentRoomGridIndexes.filter((adjacentRoomGridIndex) => (0, roomData_1.getRoomData)(adjacentRoomGridIndex) !== undefined);
}
exports.getAdjacentExistingRoomGridIndexes = getAdjacentExistingRoomGridIndexes;
/**
 * Helper function to get only the adjacent room grid indexes that do not exist (i.e. do not have
 * room data).
 *
 * This is just a filtering of the results of the `getAdjacentExistingRoomGridIndexes` function. See
 * that function for more information.
 */
function getAdjacentNonExistingRoomGridIndexes(roomGridIndex) {
    const adjacentRoomGridIndexes = getAdjacentRoomGridIndexes(roomGridIndex);
    return adjacentRoomGridIndexes.filter((adjacentRoomGridIndex) => (0, roomData_1.getRoomData)(adjacentRoomGridIndex) === undefined);
}
exports.getAdjacentNonExistingRoomGridIndexes = getAdjacentNonExistingRoomGridIndexes;
/**
 * Helper function to get all of the room grid indexes that are adjacent to a given room grid index
 * (even if those room grid indexes do not have any rooms in them).
 *
 * Adjacent room grid indexes that are outside of the grid will not be included in the returned
 * array.
 *
 * If a room grid index is provided that is outside of the grid, then an empty array will be
 * returned.
 *
 * Note that this function does not take the shape of the room into account; it only looks at a
 * single room grid index.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function getAdjacentRoomGridIndexes(roomGridIndex) {
    const roomGridIndexToUse = roomGridIndex ?? (0, roomData_1.getRoomGridIndex)();
    if (!isRoomInsideGrid(roomGridIndexToUse)) {
        return [];
    }
    const adjacentRoomGridIndexes = ADJACENT_ROOM_GRID_INDEX_DELTAS.map((delta) => roomGridIndexToUse + delta);
    return adjacentRoomGridIndexes.filter((adjacentRoomGridIndex) => isRoomInsideGrid(adjacentRoomGridIndex));
}
exports.getAdjacentRoomGridIndexes = getAdjacentRoomGridIndexes;
/**
 * Helper function to get the room safe grid index for every room on the entire floor. This includes
 * off-grid rooms, such as the Devil Room.
 *
 * Rooms without any data are assumed to be non-existent and are not included.
 */
function getAllRoomGridIndexes() {
    const rooms = (0, rooms_1.getRooms)();
    return rooms.map((roomDescriptor) => roomDescriptor.SafeGridIndex);
}
exports.getAllRoomGridIndexes = getAllRoomGridIndexes;
/**
 * Helper function to pick a random valid spot on the floor to insert a brand new room. Note that
 * some floors will not have any valid spots. If this is the case, this function will return
 * undefined.
 *
 * If you want to get an unseeded room, you must explicitly pass `undefined` to the `seedOrRNG`
 * parameter.
 *
 * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
 *                  `RNG.Next` method will be called. If `undefined` is provided, it will default to
 *                  a random seed.
 * @param ensureDeadEnd Optional. Whether to pick a valid dead end attached to a normal room. If
 *                      false, the function will randomly pick from any valid location that would
 *                      have a red door.
 * @returns Either a tuple of adjacent room grid index, `DoorSlot`, and new room grid index, or
 *          undefined.
 */
function getNewRoomCandidate(seedOrRNG, ensureDeadEnd = true) {
    const newRoomCandidatesForLevel = getNewRoomCandidatesForLevel(ensureDeadEnd);
    if (newRoomCandidatesForLevel.length === 0) {
        return undefined;
    }
    return (0, array_1.getRandomArrayElement)(newRoomCandidatesForLevel, seedOrRNG);
}
exports.getNewRoomCandidate = getNewRoomCandidate;
/**
 * Helper function to iterate through the possible doors for a room and see if any of them would be
 * a valid spot to insert a brand new room on the floor.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 * @param ensureDeadEnd Optional. Whether to only include doors that lead to a valid dead end
 *                      attached to a normal room. If false, the function will include all doors
 *                      that would have a red door.
 * @returns A array of tuples of `DoorSlot` and room grid index.
 */
function getNewRoomCandidatesBesideRoom(roomGridIndex, ensureDeadEnd = true) {
    const roomDescriptor = (0, roomData_1.getRoomDescriptor)(roomGridIndex);
    // First, handle the case of rooms outside of the grid, which obviously cannot have any possible
    // adjacent new room candidates.
    if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
        return [];
    }
    // Rooms without data are non-existent, so they obviously cannot have any possible adjacent new
    // room candidates.
    const roomData = roomDescriptor.Data;
    if (roomData === undefined) {
        return [];
    }
    const doorSlotToRoomGridIndexes = getRoomShapeAdjacentNonExistingGridIndexes(roomDescriptor.SafeGridIndex, roomData.Shape);
    const roomCandidates = [];
    for (const [doorSlot, adjacentRoomGridIndex] of doorSlotToRoomGridIndexes) {
        // The "getRoomShapeAdjacentNonExistingGridIndexes" returns grid indexes for every possible
        // door, but the real room we are examining will only have a subset of these doors. Thus, we
        // have to exclude adjacent grid indexes where it would not be possible to place a door.
        const doorSlotFlag = (0, doors_1.doorSlotToDoorSlotFlag)(doorSlot);
        if (!(0, flag_1.hasFlag)(roomData.Doors, doorSlotFlag)) {
            continue;
        }
        // Check to see if hypothetically creating a room at the given room grid index would be a dead
        // end. In other words, if we created the room, we would only want it to connect to one other
        // room (this one).
        if (ensureDeadEnd && !isDeadEnd(adjacentRoomGridIndex)) {
            continue;
        }
        roomCandidates.push({
            doorSlot,
            roomGridIndex: adjacentRoomGridIndex,
        });
    }
    return roomCandidates;
}
exports.getNewRoomCandidatesBesideRoom = getNewRoomCandidatesBesideRoom;
/**
 * Helper function to get all of the spots on the floor to insert a brand new room.
 *
 * @param ensureDeadEnd Optional. Whether to only include spots that are a valid dead end attached
 *                      to a normal room. If false, the function will include all valid spots that
 *                      have a red door.
 * @returns A array of tuples containing the adjacent room grid index, the `DoorSlot`, and the new
 *          room grid index.
 */
function getNewRoomCandidatesForLevel(ensureDeadEnd = true) {
    // We want to iterate over every room on the floor and search for potential new room spots.
    const roomsInsideGrid = (0, rooms_1.getRoomsInsideGrid)();
    // However, we want to filter out special rooms because they are supposed to be dead ends.
    const normalRooms = roomsInsideGrid.filter((room) => room.Data !== undefined &&
        room.Data.Type === isaac_typescript_definitions_1.RoomType.DEFAULT &&
        !(0, rooms_1.isMirrorRoom)(room.Data) && // Mirror rooms do not count as special rooms.
        !(0, rooms_1.isMineShaft)(room.Data));
    const roomsToLookThrough = ensureDeadEnd ? normalRooms : roomsInsideGrid;
    const newRoomCandidates = [];
    for (const room of roomsToLookThrough) {
        const newRoomCandidatesBesideRoom = getNewRoomCandidatesBesideRoom(room.SafeGridIndex, ensureDeadEnd);
        for (const { doorSlot, roomGridIndex } of newRoomCandidatesBesideRoom) {
            newRoomCandidates.push({
                adjacentRoomGridIndex: room.SafeGridIndex,
                doorSlot,
                newRoomGridIndex: roomGridIndex,
            });
        }
    }
    return newRoomCandidates;
}
exports.getNewRoomCandidatesForLevel = getNewRoomCandidatesForLevel;
/**
 * Helper function to get the grid indexes of all the rooms connected to the given room index,
 * taking the shape of the room into account. (This will only include rooms with valid data.)
 *
 * Returns an empty map if the provided room grid index is out of bounds or has no associated room
 * data.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 * @returns A map of `DoorSlot` to the corresponding room grid index.
 */
function getRoomAdjacentGridIndexes(roomGridIndex) {
    const roomDescriptor = (0, roomData_1.getRoomDescriptor)(roomGridIndex);
    if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
        return new Map();
    }
    const roomData = roomDescriptor.Data;
    if (roomData === undefined) {
        return new Map();
    }
    return getRoomShapeAdjacentExistingGridIndexes(roomDescriptor.SafeGridIndex, roomData.Shape);
}
exports.getRoomAdjacentGridIndexes = getRoomAdjacentGridIndexes;
/**
 * Helper function to get an array of all of the room descriptors for rooms that match the specified
 * room type.
 *
 * This function only searches through rooms in the current dimension and rooms inside the grid.
 *
 * This function is variadic, meaning that you can specify N arguments to get the combined room
 * descriptors for N room types.
 */
function getRoomDescriptorsForType(...roomTypes) {
    const roomTypesSet = new Set(roomTypes);
    const roomsInsideGrid = (0, rooms_1.getRoomsInsideGrid)();
    return roomsInsideGrid.filter((roomDescriptor) => roomDescriptor.Data !== undefined &&
        roomTypesSet.has(roomDescriptor.Data.Type));
}
exports.getRoomDescriptorsForType = getRoomDescriptorsForType;
/**
 * Helper function to get an array of all of the safe grid indexes for rooms that match the
 * specified room type.
 *
 * This function only searches through rooms in the current dimension.
 *
 * This function is variadic, meaning that you can specify N arguments to get the combined grid
 * indexes for N room types.
 */
function getRoomGridIndexesForType(...roomTypes) {
    const roomDescriptors = getRoomDescriptorsForType(...roomTypes);
    return roomDescriptors.map((roomDescriptor) => roomDescriptor.SafeGridIndex);
}
exports.getRoomGridIndexesForType = getRoomGridIndexesForType;
/**
 * Helper function to get only the adjacent room grid indexes for a room shape that exist (i.e. have
 * room data).
 *
 * This is just a filtering of the results of the `getRoomShapeAdjacentGridIndexes` function. See
 * that function for more information.
 */
function getRoomShapeAdjacentExistingGridIndexes(safeRoomGridIndex, roomShape) {
    const roomShapeAdjacentGridIndexes = (0, map_1.copyMap)(getRoomShapeAdjacentGridIndexes(safeRoomGridIndex, roomShape));
    for (const [doorSlot, roomGridIndex] of roomShapeAdjacentGridIndexes) {
        const roomData = (0, roomData_1.getRoomData)(roomGridIndex);
        if (roomData === undefined) {
            roomShapeAdjacentGridIndexes.delete(doorSlot);
        }
    }
    return roomShapeAdjacentGridIndexes;
}
exports.getRoomShapeAdjacentExistingGridIndexes = getRoomShapeAdjacentExistingGridIndexes;
/**
 * Helper function to get the room grid index delta that each hypothetical door in a given room
 * shape would go to.
 *
 * This is used by the `getRoomShapeAdjacentGridIndexes` function.
 *
 * @returns A map of `DoorSlot` to the corresponding room grid index delta.
 */
function getRoomShapeAdjacentGridIndexDeltas(roomShape) {
    return roomShapeToDoorSlotsToGridIndexDelta_1.ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA[roomShape];
}
exports.getRoomShapeAdjacentGridIndexDeltas = getRoomShapeAdjacentGridIndexDeltas;
/**
 * Helper function to get the room grid index that each hypothetical door in a given room shape
 * would go to. (This will not include room grid indexes that are outside of the grid.)
 *
 * @param safeRoomGridIndex This must be the room safe grid index (i.e. the top-left room grid index
 *                          for the respective room).
 * @param roomShape The shape of the hypothetical room.
 * @returns A map of `DoorSlot` to the corresponding room grid index.
 */
function getRoomShapeAdjacentGridIndexes(safeRoomGridIndex, roomShape) {
    const roomShapeAdjacentGridIndexDeltas = getRoomShapeAdjacentGridIndexDeltas(roomShape);
    const adjacentGridIndexes = new Map();
    for (const [doorSlot, delta] of roomShapeAdjacentGridIndexDeltas) {
        const roomGridIndex = safeRoomGridIndex + delta;
        if (isRoomInsideGrid(roomGridIndex)) {
            adjacentGridIndexes.set(doorSlot, roomGridIndex);
        }
    }
    return adjacentGridIndexes;
}
exports.getRoomShapeAdjacentGridIndexes = getRoomShapeAdjacentGridIndexes;
/**
 * Helper function to get only the adjacent room grid indexes for a room shape that do not exist
 * (i.e. do not have room data).
 *
 * This is just a filtering of the results of the `getRoomShapeAdjacentGridIndexes` function. See
 * that function for more information.
 */
function getRoomShapeAdjacentNonExistingGridIndexes(safeRoomGridIndex, roomShape) {
    const roomShapeAdjacentGridIndexes = (0, map_1.copyMap)(getRoomShapeAdjacentGridIndexes(safeRoomGridIndex, roomShape));
    for (const [doorSlot, roomGridIndex] of roomShapeAdjacentGridIndexes) {
        const roomData = (0, roomData_1.getRoomData)(roomGridIndex);
        if (roomData !== undefined) {
            roomShapeAdjacentGridIndexes.delete(doorSlot);
        }
    }
    return roomShapeAdjacentGridIndexes;
}
exports.getRoomShapeAdjacentNonExistingGridIndexes = getRoomShapeAdjacentNonExistingGridIndexes;
/**
 * Helper function to determine if the current room grid index is inside of the normal 13x13 level
 * grid.
 *
 * For example, Devil Rooms and the Mega Satan room are not considered to be inside the grid.
 */
function inGrid() {
    const roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    return isRoomInsideGrid(roomGridIndex);
}
exports.inGrid = inGrid;
/**
 * Helper function to detect if the current room was created by the Red Key item.
 *
 * Under the hood, this checks for the `RoomDescriptorFlag.FLAG_RED_ROOM` flag.
 */
function inRedKeyRoom() {
    const roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    return isRedKeyRoom(roomGridIndex);
}
exports.inRedKeyRoom = inRedKeyRoom;
/**
 * Helper function to check if the given room grid index is a dead end. Specifically, this is
 * defined as having only one adjacent room that exists.
 *
 * Note that this function does not take the shape of the room into account; it only looks at a
 * single room grid index.
 *
 * This function does not care if the given room grid index actually exists, so you can use it to
 * check if a hypothetical room would be a dead end.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function isDeadEnd(roomGridIndex) {
    const adjacentExistingRoomGridIndexes = getAdjacentExistingRoomGridIndexes(roomGridIndex);
    return adjacentExistingRoomGridIndexes.length === 1;
}
exports.isDeadEnd = isDeadEnd;
function isDoorSlotValidAtGridIndex(doorSlot, roomGridIndex) {
    const allowedDoors = (0, roomData_1.getRoomAllowedDoors)(roomGridIndex);
    return allowedDoors.has(doorSlot);
}
exports.isDoorSlotValidAtGridIndex = isDoorSlotValidAtGridIndex;
function isDoorSlotValidAtGridIndexForRedRoom(doorSlot, roomGridIndex) {
    const doorSlotValidAtGridIndex = isDoorSlotValidAtGridIndex(doorSlot, roomGridIndex);
    if (!doorSlotValidAtGridIndex) {
        return false;
    }
    const roomShape = (0, roomData_1.getRoomShape)(roomGridIndex);
    if (roomShape === undefined) {
        return false;
    }
    const delta = (0, roomShape_1.getGridIndexDelta)(roomShape, doorSlot);
    if (delta === undefined) {
        return false;
    }
    const redRoomGridIndex = roomGridIndex + delta;
    return !roomExists(redRoomGridIndex) && isRoomInsideGrid(redRoomGridIndex);
}
exports.isDoorSlotValidAtGridIndexForRedRoom = isDoorSlotValidAtGridIndexForRedRoom;
/**
 * Helper function to detect if the provided room was created by the Red Key item.
 *
 * Under the hood, this checks for the `RoomDescriptorFlag.FLAG_RED_ROOM` flag.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function isRedKeyRoom(roomGridIndex) {
    const roomDescriptor = (0, roomData_1.getRoomDescriptor)(roomGridIndex);
    return (0, flag_1.hasFlag)(roomDescriptor.Flags, isaac_typescript_definitions_1.RoomDescriptorFlag.RED_ROOM);
}
exports.isRedKeyRoom = isRedKeyRoom;
/**
 * Helper function to determine if a given room grid index is inside of the normal 13x13 level grid.
 *
 * For example, Devil Rooms and the Mega Satan room are not considered to be inside the grid.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function isRoomInsideGrid(roomGridIndex) {
    if (roomGridIndex === undefined) {
        roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    }
    return roomGridIndex >= 0 && roomGridIndex <= constants_1.MAX_LEVEL_GRID_INDEX;
}
exports.isRoomInsideGrid = isRoomInsideGrid;
/**
 * Helper function to generate a new room on the floor.
 *
 * If you want to generate an unseeded room, you must explicitly pass `undefined` to the `seedOrRNG`
 * parameter.
 *
 * Under the hood, this function uses the `Level.MakeRedRoomDoor` method to create the room.
 *
 * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
 *                  `RNG.Next` method will be called. Default is `Level.GetDungeonPlacementSeed`.
 *                  Note that the RNG is only used to select the random location to put the room on
 *                  the floor; it does not influence the randomly chosen room contents. (That is
 *                  performed by the game and can not be manipulated prior to its generation.)
 * @param ensureDeadEnd Optional. Whether to place the room at a valid dead end attached to a normal
 *                      room. If false, it will randomly appear at any valid location that would
 *                      have a red door.
 * @param customRoomData Optional. By default, the newly created room will have data corresponding
 *                       to the game's randomly generated red room. If you provide this function
 *                       with room data, it will be used to override the vanilla data.
 * @returns The room grid index of the new room or undefined if the floor had no valid dead ends to
 *          place a room.
 */
function newRoom(seedOrRNG, ensureDeadEnd = true, customRoomData) {
    const level = cachedClasses_1.game.GetLevel();
    if (seedOrRNG === undefined) {
        seedOrRNG = level.GetDungeonPlacementSeed();
    }
    const rng = (0, rng_1.isRNG)(seedOrRNG) ? seedOrRNG : (0, rng_1.newRNG)(seedOrRNG);
    const newRoomCandidate = getNewRoomCandidate(rng, ensureDeadEnd);
    if (newRoomCandidate === undefined) {
        return undefined;
    }
    const { adjacentRoomGridIndex, doorSlot, newRoomGridIndex } = newRoomCandidate;
    level.MakeRedRoomDoor(adjacentRoomGridIndex, doorSlot);
    // By default, the room will be a "red room" and have a red graphical tint, so we want to make it
    // a normal room.
    const roomDescriptor = (0, roomData_1.getRoomDescriptor)(newRoomGridIndex);
    roomDescriptor.Flags = (0, flag_1.removeFlag)(roomDescriptor.Flags, isaac_typescript_definitions_1.RoomDescriptorFlag.RED_ROOM);
    if (customRoomData !== undefined) {
        roomDescriptor.Data = customRoomData;
    }
    // By default, the new room will not appear on the map, even if the player has The Mind. Thus, we
    // must manually alter the `DisplayFlags` of the room descriptor.
    const roomData = roomDescriptor.Data;
    if (roomData !== undefined) {
        const hasFullMap = level.GetStateFlag(isaac_typescript_definitions_1.LevelStateFlag.FULL_MAP_EFFECT);
        const hasCompass = level.GetStateFlag(isaac_typescript_definitions_1.LevelStateFlag.COMPASS_EFFECT);
        const hasBlueMap = level.GetStateFlag(isaac_typescript_definitions_1.LevelStateFlag.BLUE_MAP_EFFECT);
        const roomType = roomData.Type;
        const isSecretRoom = (0, rooms_1.isSecretRoomType)(roomType);
        if (hasFullMap) {
            roomDescriptor.DisplayFlags = constants_1.ALL_DISPLAY_FLAGS;
        }
        else if (!isSecretRoom && hasCompass) {
            roomDescriptor.DisplayFlags = (0, flag_1.addFlag)(isaac_typescript_definitions_1.DisplayFlag.VISIBLE, isaac_typescript_definitions_1.DisplayFlag.SHOW_ICON);
        }
        else if (isSecretRoom && hasBlueMap) {
            roomDescriptor.DisplayFlags = (0, flag_1.addFlag)(isaac_typescript_definitions_1.DisplayFlag.VISIBLE, isaac_typescript_definitions_1.DisplayFlag.SHOW_ICON);
        }
    }
    return newRoomGridIndex;
}
exports.newRoom = newRoom;
/**
 * Helper function to check if a room exists at the given room grid index. (A room will exist if it
 * has non-undefined data in the room descriptor.)
 */
function roomExists(roomGridIndex) {
    const roomData = (0, roomData_1.getRoomData)(roomGridIndex);
    return roomData !== undefined;
}
exports.roomExists = roomExists;
/**
 * Helper function to get the coordinates of a given room grid index. The floor is represented by a
 * 13x13 grid.
 *
 * - Since the starting room is in the center, the starting room grid index of 84 is equal to
 *   coordinates of (6, 6).
 * - The top-left grid index of 0 is equal to coordinates of: (12, 0)
 * - The top-right grid index of 12 is equal to coordinates of: (0, 0)
 * - The bottom-left grid index of 156 is equal to coordinates of: (0, 12)
 * - The bottom-right grid index of 168 is equal to coordinates of: (12, 12)
 */
function roomGridIndexToVector(roomGridIndex) {
    const x = roomGridIndex % constants_1.LEVEL_GRID_ROW_WIDTH;
    const y = Math.floor(roomGridIndex / constants_1.LEVEL_GRID_ROW_WIDTH);
    return Vector(x, y);
}
exports.roomGridIndexToVector = roomGridIndexToVector;
/**
 * Helper function to convert a room grid index expressed as a vector back into an integer.
 *
 * Also see the `roomGridIndexToVector` helper function.
 */
function vectorToRoomGridIndex(roomVector) {
    return roomVector.Y * constants_1.LEVEL_GRID_ROW_WIDTH + roomVector.X;
}
exports.vectorToRoomGridIndex = vectorToRoomGridIndex;
