public HouseData GenerateInnerDoors(HouseData houseData) { houseData.roomPairs = new List <RoomPair> (); for (int x = 2; x < houseData.floorPlan.roomData.GetLength(0) - 2; x++) { for (int z = 2; z < houseData.floorPlan.roomData.GetLength(1) - 2; z++) { if (houseData.floorPlan.area [x, z] == UnitType.INNERWALL_DOWN) //Mögliche Wand für eine Tür { if (houseData.floorPlan.area [x, z - 1] == UnitType.INNERWALL_UP) //Angrenzendes Feld ist das Gegenstück zur Wand { RoomPair roomPair = GetExistingRoomPair(ref houseData.roomPairs, new RoomPair(houseData.floorPlan.roomData[x, z], houseData.floorPlan.roomData[x, z - 1])); roomPair.doorPoints.Add(new Point2DTupel(x, z, x, z - 1)); } } else if (houseData.floorPlan.area [x, z] == UnitType.INNERWALL_UP) //Mögliche Wand für eine Tür { if (houseData.floorPlan.area [x, z + 1] == UnitType.INNERWALL_DOWN) //Angrenzendes Feld ist das Gegenstück zur Wand { RoomPair roomPair = GetExistingRoomPair(ref houseData.roomPairs, new RoomPair(houseData.floorPlan.roomData[x, z], houseData.floorPlan.roomData[x, z + 1])); roomPair.doorPoints.Add(new Point2DTupel(x, z, x, z + 1)); } } else if (houseData.floorPlan.area [x, z] == UnitType.INNERWALL_LEFT) //Mögliche Wand für eine Tür { if (houseData.floorPlan.area [x + 1, z] == UnitType.INNERWALL_RIGHT) //Angrenzendes Feld ist das Gegenstück zur Wand { RoomPair roomPair = GetExistingRoomPair(ref houseData.roomPairs, new RoomPair(houseData.floorPlan.roomData[x, z], houseData.floorPlan.roomData[x + 1, z])); roomPair.doorPoints.Add(new Point2DTupel(x, z, x + 1, z)); } } else if (houseData.floorPlan.area [x, z] == UnitType.INNERWALL_RIGHT) //Mögliche Wand für eine Tür { if (houseData.floorPlan.area [x - 1, z] == UnitType.INNERWALL_LEFT) //Angrenzendes Feld ist das Gegenstück zur Wand { RoomPair roomPair = GetExistingRoomPair(ref houseData.roomPairs, new RoomPair(houseData.floorPlan.roomData[x, z], houseData.floorPlan.roomData[x - 1, z])); roomPair.doorPoints.Add(new Point2DTupel(x, z, x - 1, z)); } } } } foreach (RoomPair rp in houseData.roomPairs) { Point2DTupel doorPlaces = rp.doorPoints [randomGenerator.Next(rp.doorPoints.Count)]; houseData.floorPlan.doorInfo.Add((double)doorPlaces.point1.x * (double)1000 + (double)doorPlaces.point1.z / (double)1000, houseData.floorPlan.area [doorPlaces.point1.x, doorPlaces.point1.z]); houseData.floorPlan.doorInfo.Add((double)doorPlaces.point2.x * (double)1000 + (double)doorPlaces.point2.z / (double)1000, houseData.floorPlan.area [doorPlaces.point2.x, doorPlaces.point2.z]); houseData.floorPlan.area [doorPlaces.point1.x, doorPlaces.point1.z] = UnitType.DOOR; houseData.floorPlan.area [doorPlaces.point2.x, doorPlaces.point2.z] = UnitType.DOOR; } return(houseData); }
private void AddWallsSequentially() { Room[,] r = _rooms; //capacity should be rooms * 2? ArrayList ExcludeWalls = new ArrayList(r.Length * 2); Random random = new Random(); SolutionFinder finder = new SolutionFinder(); finder.FindSolution(this); PassCount = 0; while (finder.CycleFound) { PassCount++; foreach (Room room in r) { //if there's already only one way out of this room, then skip it if (room.PassableNeighbors < 2) continue; Direction d = random.Next(4); Room neighbor = room.Neighbors[d] as Room; //if the selected neighbor isn't a room, move on if (neighbor == null) continue; //if there's already only one way out of the selected neighbor, move on if (neighbor.PassableNeighbors < 2) continue; RoomPair pair = new RoomPair(room, room.Neighbors[d]); //if we've already determined that we can't add this wall, don't try again if (ExcludeWalls.Contains(pair)) continue; //now try to add the new wall, and make sure all the rooms are still reachable new Wall(room, d); finder.FindSolution(this); if (finder.RoomsConnected < r.Length) { room.RemoveConnector(d); ExcludeWalls.Add(pair); finder.CycleFound = true; finder.RoomsConnected = r.Length; } //break out of the foreach loop early if we've already eliminated all cycles if (!finder.CycleFound) break; } } }
public RoomPair GetExistingRoomPair(ref List <RoomPair> list, RoomPair equal) { foreach (RoomPair rp in list) { if (rp.Equals(equal)) { return(rp); } } list.Add(equal); return(equal); }
//This method places starting room, places a certain number of regular rooms in a loop, then places an exit room. void GenerateMap(int levelNumber) { //Levels are randomly generated with rooms being placed into a 7 by 7 grid. //The starting room is always placed in the middle of the grid at position (3,3). //The length of each one of our rooms is 256 units and the height is 176 units. //A fantasy version of each level and a science version of each level are generated simultaneously, but offset by 2000 units in the x dimension. Vector2 startPos = new Vector2(3, 3); //Position of the start room in the model of our level grid. Vector2 scaledStartPos = new Vector2(3 * 256, 3 * 176); //Actual position of the fantasy room being instantiated in Unity. Vector2 offsetStartPos = new Vector2((3 * 256) + 2000, 3 * 176); //Actual position of the science room being instantiated in Unity (notice 2000 unit offset in x dimension). //Instantiates fantasy room at starting position and adds room to our grid model. GameObject roomToInstantiate = Instantiate(fantasyStartRooms[0], scaledStartPos, Quaternion.identity); fantasyRooms[3, 3] = roomToInstantiate; //Instantiates science room at starting position and adds room to our grid model. roomToInstantiate = Instantiate(scienceStartRooms[0], offsetStartPos, Quaternion.identity); scienceRooms[3, 3] = roomToInstantiate; //Adds the starting coordinate position (3,3) to our roomCoordinate list. //Coordinates contained in this list are occupied. roomCoordinates.Add(startPos); roomCoordinatesSize += 1; for (int i = 0; i < 8; i++) //This loop places 8 "normal" rooms that are not starting rooms, exit rooms, key rooms, or lock rooms. { Vector3 coordinate = selectCoordinate(); //Calls function that will return an available coordinate pair for instantiating a new room. Vector2 scaledCoordinate = new Vector2((int)coordinate.x * 256, (int)coordinate.y * 176); //Multiply room coordinate by the dimensions of our rooms. Vector2 offsetCoordinate = new Vector2(((int)coordinate.x * 256) + 2000, (int)coordinate.y * 176); //Applies 2000 unit offset for science room. RoomPair fanAndSciRoom = selectRoom(); //Calls method that will return a pair of rooms to be instantiated (one fantasy and one science room). GameObject fantasyRoomToInstantiate = Instantiate(fanAndSciRoom._fantasy, scaledCoordinate, Quaternion.identity); //Instantiates fantasy room fantasyRooms[(int)coordinate.x, (int)coordinate.y] = fantasyRoomToInstantiate; //Adds just instantiated fantasy room to fantasyRooms matrix at appropriate coordinates. spawnEnemies(scaledCoordinate, fantasyEnemies, fanAndSciRoom._fantasy.transform.name); //This method instantiates enemies at the most recently instantiated fantasy room. GameObject scienceRoomToInstantiate = Instantiate(fanAndSciRoom._science, offsetCoordinate, Quaternion.identity); //Instantiates science room scienceRooms[(int)coordinate.x, (int)coordinate.y] = scienceRoomToInstantiate; //Adds just instantiated science room to scienceRooms matrix at appropriate coordinates. spawnEnemies(offsetCoordinate, fantasyEnemies, fanAndSciRoom._science.transform.name); //This method instantiates enemies at the most recently instantiated science room. //Opens the doors between the newly instnatiated room and its neighbor so that the player character can move between rooms. openDoors((int)coordinate.z, (int)coordinate.x, (int)coordinate.y, fantasyRoomToInstantiate, scienceRoomToInstantiate); //Adds the new coordinates to the list of occupied coordinates. roomCoordinates.Add(coordinate); roomCoordinatesSize += 1; } //Places a room containing a key somewhere in the level and stores the coordinates of the key room in variable keyPos. Vector2 keyPos = placeKeyRoom(); Boolean lockAndKeyFarAway = false; //This variable will be set to true if the locked room is placed at least 3 spaces away from the key room. while (lockAndKeyFarAway == false) //This loop continues until the locked room is placed far enough away from the key room. { Vector3 lockPos = selectCoordinate(); //Potential coordinates for placing the locked room. Vector3 endPos = new Vector3(); Boolean possibleToPlaceExit = false; //This variable will be set to true if there is an available space to place the exit room next to the locked room after placing locked room. if (isCoordinateEmpty((int)lockPos.x, (int)lockPos.y + 1)) //If true exit room will be placed north of locked room. { endPos = new Vector3((int)lockPos.x, (int)lockPos.y + 1, 1); possibleToPlaceExit = true; } else if (isCoordinateEmpty((int)lockPos.x, (int)lockPos.y - 1)) //If true exit room will be placed south of locked room. { endPos = new Vector3((int)lockPos.x, (int)lockPos.y - 1, 2); possibleToPlaceExit = true; } else if (isCoordinateEmpty((int)lockPos.x + 1, (int)lockPos.y)) //If true exit room will be placed east of locked room. { endPos = new Vector3((int)lockPos.x + 1, (int)lockPos.y, 3); possibleToPlaceExit = true; } else if (isCoordinateEmpty((int)lockPos.x - 1, (int)lockPos.y)) //If true exit room will be placed west of locked room. { endPos = new Vector3((int)lockPos.x - 1, (int)lockPos.y, 4); possibleToPlaceExit = true; } if (possibleToPlaceExit == true) { //This condition checks to make sure the key room and locked room are at least 3 spaces apart. if (distanceBetweenPoints((int)keyPos.x, (int)keyPos.y, (int)lockPos.x, (int)lockPos.y) >= 3) { placeLockRoom(lockPos); //Places the locked room at coordinates in lockPos. Vector2 scaledEndPos = new Vector2((int)endPos.x * 256, (int)endPos.y * 176); Vector2 offsetEndPos = new Vector2(((int)endPos.x * 256) + 2000, (int)endPos.y * 176); //Instantiates fantasy exit room, adds the room to our model, and spawns enemies in the exit room. GameObject fantasyRoomToInstantiate = Instantiate(fantasyEndRooms[0], scaledEndPos, Quaternion.identity); fantasyRooms[(int)endPos.x, (int)endPos.y] = roomToInstantiate; spawnEnemies(scaledEndPos, fantasyEnemies, fantasyEndRooms[0].transform.name); //Instantiates science exit room, adds the room to our model, and spawns enemies in the exit room. GameObject scienceRoomToInstantiate = Instantiate(scienceEndRooms[0], offsetEndPos, Quaternion.identity); scienceRooms[(int)endPos.x, (int)endPos.y] = roomToInstantiate; spawnEnemies(offsetEndPos, fantasyEnemies, scienceEndRooms[0].transform.name); lockAndKeyFarAway = true; //Opens the doors between the exit room and the locked room so that the player character can move between rooms. openDoors((int)endPos.z, (int)endPos.x, (int)endPos.y, fantasyRoomToInstantiate, scienceRoomToInstantiate); } } } }