private void Start() { if (ok) { return; } ok = true; Generator generator = new CellularAutomataGenerator(rule, fulfillment); var temp = generator.GenerateMaze((int)levelSize.x, (int)levelSize.y); var maze = CellularMazeCleaner.Clean(temp, minSize); for (int i = 1; i < maze.GetLength(0) - 1; i++) { for (int j = 1; j < maze.GetLength(1) - 1; j++) { if (maze[i, j]) { var instance = Instantiate(floor, new Vector3(i * floorSize.x, 0, j * floorSize.y), Quaternion.identity, transform); CreateWalls(maze, i, j, instance.transform); CreateColumn(maze, i, j, instance.transform); } } } }
public static MapData GenerateFloor(uint floorNumber, int widthInTiles, int heightInTiles) { // Generate a walkable map, complete with stairs down var isWalkableMap = new ArrayMap <bool>(widthInTiles, heightInTiles); CellularAutomataGenerator.Generate(isWalkableMap); // Randomly positioned on a ground tile! True = walkable var playerPosition = isWalkableMap.RandomPosition(true); var stairsDownPosition = playerPosition; while (Math.Abs(playerPosition.X - stairsDownPosition.X) + Math.Abs(playerPosition.Y - stairsDownPosition.Y) <= MinimumPlayerStairsDistance) { stairsDownPosition = isWalkableMap.RandomPosition(true); } System.Console.WriteLine($"Stairs are at {stairsDownPosition}"); var mapData = new MapData() { Map = isWalkableMap, PlayerPosition = playerPosition, StairsDownPosition = stairsDownPosition }; return(mapData); }
public Map(IGenerator dungeonRandom, int width, int height, Adventure adventure, bool useTestMap = false) { Width = width; Height = height; Adventure = adventure; var wMap = new ArrayMap <bool>(width, height); // creating map here if (useTestMap) { TestMap(wMap); } else { //RandomRoomsGenerator.Generate(wMap, dungeonRandom, 15, 5, 15, 50); CellularAutomataGenerator.Generate(wMap, dungeonRandom); } WalkabilityMap = wMap; ExplorationMap = new ArrayMap <int>(width, height); EntityMap = new ArrayMap <AdventureEntityContainer>(width, height); TileMap = new ArrayMap <Tile>(width, height); Entities = new List <AdventureEntity>(); var resMap = new ArrayMap <double>(width, height); for (var i = 0; i < width; i++) { for (var j = 0; j < height; j++) { // build up Entity Map, not necessary and really slow on big maps //EntityMap[i,j] = new AdventureEntityContainer(); if (wMap[i, j]) { //ExplorationMap[i, j] = 1; _walkableTiles++; TileMap[i, j] = new StoneTile(this, Coord.Get(i, j)); } else { //ExplorationMap[i, j] = -9; resMap[i, j] = 1; TileMap[i, j] = new StoneWall(this, Coord.Get(i, j)); } } } FovMap = new FOV(resMap); Locations = CreateMapLocations(wMap, 9); ExpectedFovNum = new int[width, height]; }
private void aStarMatches(Distance distanceCalc) { var map = new ArrayMap <bool>(MAP_WIDTH, MAP_HEIGHT); CellularAutomataGenerator.Generate(map); var graphTuple = initGraph(map, distanceCalc); var pather = new AStar(map, distanceCalc); var controlPather = new CA.AStar(graphTuple.Graph); controlPather.ChoosenHeuristic = distanceHeuristic(distanceCalc); for (int i = 0; i < ITERATIONS; i++) { Coord start = Coord.Get(SingletonRandom.DefaultRNG.Next(map.Width - 1), SingletonRandom.DefaultRNG.Next(map.Height - 1)); while (!map[start]) { start = Coord.Get(SingletonRandom.DefaultRNG.Next(map.Width - 1), SingletonRandom.DefaultRNG.Next(map.Height - 1)); } Coord end = Coord.Get(SingletonRandom.DefaultRNG.Next(map.Width - 1), SingletonRandom.DefaultRNG.Next(map.Height - 1)); while (end == start || !map[end]) { end = Coord.Get(SingletonRandom.DefaultRNG.Next(map.Width - 1), SingletonRandom.DefaultRNG.Next(map.Height - 1)); } var path1 = pather.ShortestPath(start, end); controlPather.SearchPath(graphTuple.Nodes[start.X, start.Y], graphTuple.Nodes[end.X, end.Y]); var path2 = controlPather.PathByNodes; if (path2.Length != path1.LengthWithStart) { Console.WriteLine($"Error: Control got {path2.Length}, but custom AStar got {path1.LengthWithStart}"); Console.WriteLine("Control: "); Utility.PrintHightlightedPoints(map, Utility.ToCoords(path2)); Console.WriteLine("AStar :"); Utility.PrintHightlightedPoints(map, path1.StepsWithStart); } bool lengthGood = (path1.LengthWithStart <= path2.Length); Assert.AreEqual(true, lengthGood); Assert.AreEqual(path1.Start, start); Assert.AreEqual(path1.End, end); checkWalkable(path1, map); checkAdjacency(path1, distanceCalc); } }
public void GenerateMap() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int[,] map; if (useRandomSeed) { map = CellularAutomataGenerator.GenerateMap(width, height, randomFillPercent, smoothingIterations, neighborDistanceX, neighborDistanceY); } else { map = CellularAutomataGenerator.GenerateMap(width, height, randomFillPercent, smoothingIterations, neighborDistanceX, neighborDistanceY, seed); } stopwatch.Stop(); genTimeText.text = string.Format("Generated map in {0}ms.", stopwatch.ElapsedMilliseconds == 0 ? "<1" : stopwatch.ElapsedMilliseconds.ToString()); if (mapVisualizer != null) { mapVisualizer.SetMap(map); } }
private static void Main(string[] args) { var gen = new CellularAutomataGenerator(); while (true) { string[] input = Console.ReadLine().Split(' '); int[] values = { 100, // Width 100, // Height 45, // Alive 5, // Birth 4, // Survival 5 // Iterations }; int[] otherGoodConfig = { 100, 100, 30, 6, 5, 5 }; for (int i = 0; i < input.Length && i < values.Length; i++) { int prevVal = values[i]; if (!Int32.TryParse(input[i], out values[i])) { values[i] = prevVal; } } gen.Generate(values[0], values[1], values[2], values[3], values[4], values[5]).SaveToImageFile(); } }
private static void Pathing() { /* AStar */ var timeAStar = PathingTests.TimeForAStar(Runner.MAP_WIDTH, Runner.MAP_HEIGHT, Runner.ITERATIONS_FOR_TIMING); Console.WriteLine(); Console.WriteLine($"Time for {Runner.ITERATIONS_FOR_TIMING} paths, on {Runner.MAP_WIDTH}x{Runner.MAP_HEIGHT} map:"); Console.WriteLine($"\tAStar: {timeAStar}"); /* Single-Goal GoalMap */ var map = new ArrayMap <bool>(Runner.MAP_WIDTH, Runner.MAP_HEIGHT); CellularAutomataGenerator.Generate(map); Coord goal = map.RandomPosition(true); var timeGoalMap = PathingTests.TimeForGoalMap(map, goal.Yield(), Runner.ITERATIONS_FOR_TIMING); var timeFleeMap = PathingTests.TimeForFleeMap(map, goal.Yield(), Runner.ITERATIONS_FOR_TIMING); Console.WriteLine(); Console.WriteLine($"Time to calculate single-source goal map on {Runner.MAP_WIDTH}x{Runner.MAP_HEIGHT} map {Runner.ITERATIONS_FOR_TIMING} times:"); Console.WriteLine($"\tGoal-Map : {timeGoalMap}"); Console.WriteLine($"\tFlee-Map : {timeFleeMap}"); /* Multi-Goal GoalMap */ var goals = new List <Coord>(); for (int i = 0; i < Runner.NUM_GOALS; i++) { goals.Add(map.RandomPosition(true)); } var timeMGoalMap = PathingTests.TimeForGoalMap(map, goals, Runner.ITERATIONS_FOR_TIMING); var timeMFleeMap = PathingTests.TimeForFleeMap(map, goals, Runner.ITERATIONS_FOR_TIMING); Console.WriteLine(); Console.WriteLine($"Time to calculate multi-source goal map on {Runner.MAP_WIDTH}x{Runner.MAP_HEIGHT} map {Runner.ITERATIONS_FOR_TIMING} times:"); Console.WriteLine($"\tGoal-Map : {timeMGoalMap}"); Console.WriteLine($"\tFlee-Map : {timeMFleeMap}"); }
// Start is called before the first frame update void Start() { // Singleton if (instance == null) { instance = this; } else { Destroy(gameObject); } // Initialize size of map map = new Cell[width, height]; Queue <Cell> floors = new Queue <Cell>(); // Randomly disperse walls onto map for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { // 50-50 chance of cell becoming a wall if (Random.Range(0, 100) < initialWallPlacementProbability) { map[x, y] = new Cell(x, y, 1); } else { map[x, y] = new Cell(x, y, 0); } } } // Run algorithm for input iterations for (int i = 0; i < iterations - 1; i++) { Cell[,] newMap = new Cell[width, height]; for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { if (Cell.MooresNeighborhood(map, x, y) >= wallThreshold) { newMap[x, y] = new Cell(x, y, 1); } else { newMap[x, y] = new Cell(x, y, 0); } } } map = newMap; } // Final iteration we add all floors to queue Cell[,] finalMap = new Cell[width, height]; for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { if (Cell.MooresNeighborhood(map, x, y) >= wallThreshold) { finalMap[x, y] = new Cell(x, y, 1); } else { finalMap[x, y] = new Cell(x, y, 0); floors.Enqueue(finalMap[x, y]); } } } map = finalMap; // Room Creation while (floors.Count > 0) { Cell current = floors.Dequeue(); if (current.visited == false) { Room newRoom = new Room(); CreateRoom(current, newRoom); Room.rooms.Add(newRoom); } } Room largestRoom = Room.rooms[0]; // Find largest room foreach (Room curRoom in Room.rooms) { if (curRoom.edgeCells.Count > largestRoom.edgeCells.Count) { largestRoom = curRoom; } } // If a room is not connected to the largest room, connect nearest rooms until it is // This assures connectivity to all rooms foreach (Room curRoom in Room.rooms) { while (!curRoom.connectedRooms.Contains(largestRoom)) { ConnectionInformation cellsToConnect = curRoom.FindNearestUnconnected(); List <Cell> path = AStar.Search(map, cellsToConnect.startCell, cellsToConnect.endCell); foreach (Cell cell in path) { // Use connectionSize to fill in connection cells for (int i = -connectionSize; i <= connectionSize; i++) { for (int j = -connectionSize; j <= connectionSize; j++) { int tempX = cell.x + i; int tempY = cell.y + j; if (tempX >= 0 && tempX <= map.GetUpperBound(0) && tempY >= 0 && tempY <= map.GetUpperBound(1)) { map[tempX, tempY].value = 0; } } } } curRoom.connectedRooms.UnionWith(cellsToConnect.targetRoom.connectedRooms); } } // Create list that will be used for furnishing List <Cell> randomOrder = new List <Cell>(); // Placement of walls and floors for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { if (map[x, y].value == 1) { Instantiate(wall, new Vector3(x, y, 0), Quaternion.identity); } else if (map[x, y].value == 0) { Instantiate(ground, new Vector3(x, y, 0), Quaternion.identity); // Add floors to list used for furnishing randomOrder.Add(map[x, y]); } } } // Furnishing for (int i = 0; i < furnishingIterations; i++) { Shuffle(randomOrder); Cell[,] newMap = (Cell[, ])map.Clone(); foreach (Cell curCell in randomOrder) { if (map[curCell.x, curCell.y].value == 0) { foreach (GameObject obj in furniture) { Furniture curFurniture = obj.GetComponent <Furniture>(); if (curFurniture.CanSpawn(map, curCell.x, curCell.y)) { curFurniture.Spawn(curCell.x, curCell.y); newMap[curCell.x, curCell.y].value = curFurniture.myValue; break; } } } } map = newMap; } // Assure required amounts are met foreach (GameObject obj in furniture) { Furniture curFurniture = obj.GetComponent <Furniture>(); int count = 0; while (curFurniture.GetAmount() < curFurniture.requiredAmount) { if (count > maxFurnishingIterations) { Debug.LogError("Could not create level with required furniture"); Debug.Break(); break; } Shuffle(randomOrder); foreach (Cell curCell in randomOrder) { if (map[curCell.x, curCell.y].value == 0 && curFurniture.CanSpawn(map, curCell.x, curCell.y)) { curFurniture.Spawn(curCell.x, curCell.y); map[curCell.x, curCell.y].value = curFurniture.myValue; break; } } count++; } } }