private static WallData[] FindRoom( WallUseCounter wallCounter, bool useReversedWall, PointWallsMap pointWallsMap, ref WallUseCounter[] path, int depth = 0) { var indent = new string (' ', depth * 2); // Debug.Log ($"{indent}Wall {wallCounter}"); Assert.IsTrue(depth < 10); if (path != null && path.Length > 0 && wallCounter == path[0]) { Array.ForEach(path, x => x.Counter++); var room = path.Select(x => x.Wall).ToArray(); // Debug.Log ($"{indent}Room found {RoomToString (room)}"); return(room); } var wall = wallCounter.Wall; if (useReversedWall) { wall = wall.Reverse(); } var end = wall .Points .Last(); var wallVector = wall.GetInverseVector(); var allNextWalls = pointWallsMap[end]; var nextWalls = allNextWalls .Where( x => x != wallCounter && !x.Deadlock && x.Counter < 2) .Select(x => GetNextWallData(wall, wallVector, x)) .OrderBy(x => x.Item3) .ToList(); path = AppendToArray(path, wallCounter); foreach (var nextWall in nextWalls) { var room = FindRoom( nextWall.Item1, nextWall.Item2, pointWallsMap, ref path, depth + 1); if (room != null) { return(room); } } // Debug.Log ($"{indent}Wall {wallCounter.Wall} deadlocked"); wallCounter.Deadlock = true; return(null); }
public static WallData[][] FindRooms(Walls walls) { var pointWallsMap = new PointWallsMap(); var uniqueWalls = new HashSet <WallData> (); foreach (var point in walls.Points) { foreach (var wall in walls.GetPointWalls(point)) { uniqueWalls.Add(wall); } } var wallCounterMap = new Dictionary <WallData, WallUseCounter> (); foreach (var wall in uniqueWalls) { wallCounterMap.Add(wall, new WallUseCounter(wall)); } uniqueWalls.Clear(); foreach (var point in walls.Points) { pointWallsMap.Add( point, walls .GetPointWalls(point) .ConvertAll(x => wallCounterMap[x]) .ToArray()); } var rooms = new List <WallData[]> (); var vector2Comparer = new Vector2Comparer(); var orderedWallCounters = wallCounterMap .Values .OrderBy(x => vector2Comparer.GetMin(x.Wall.Start, x.Wall.End), vector2Comparer) .ToArray(); var i = 0; do { Assert.IsTrue(++i < 10); var startWall = orderedWallCounters .FirstOrDefault(x => x.Counter == 0); if (startWall == null) { break; } WallUseCounter[] path = null; var room = FindRoom(startWall, false, pointWallsMap, ref path); Assert.IsNotNull(room); rooms.Add(room); } while (true); /** * Remove 'superroom', ie room which includes all rooms in this group. * Such room include only 'shared' walls, ie walls with UseCount == 2. */ /* if (rooms.Count > 1) { * var sorterRooms = rooms * .OrderByDescending (x => x.Length) * .ToArray (); * for (int j = 0; j < sorterRooms.Length; j++) { * if (rooms[j].All (x => wallCounterMap[x].Counter == 2)) { * rooms.RemoveAt (j); * break; * } * } * }*/ return(rooms.ToArray()); }