public void SetupMap(MapTileTypeEnum mapTileType = MapTileTypeEnum.land, bool free = true) { map = new MapTile[width, height]; for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { map[x, y] = new MapTile(new Point(x, y), new MapTileType() { type = mapTileType }, 0.5, free); } } UpdateMapTileData(); }
public void SetAdjacent() { Adjacent = new List <MapTile>(); if (x < grid.GetUpperBound(0)) { Adjacent.Add(grid[x + 1, y]); } if (x > 0) { Adjacent.Add(grid[x - 1, y]); } if (y < grid.GetUpperBound(1)) { Adjacent.Add(grid[x, y + 1]); } if (y > 0) { Adjacent.Add(grid[x, y - 1]); } }
/// <summary> /// Initializes the type of Tiles passed in based on the MapTile object loaded from the Load(...) process /// </summary> /// <typeparam name="T">Type of object array we are going to create</typeparam> /// <param name="tiles">MapTile array that is used to create the new typed array</param> /// <param name="objectConstruction">TileConstructor delegate used to convert the MapTile object to the subclass passed in as T</param> /// <returns>T[,] type of objects created from MapTiles[,] passed in</returns> public static T[,] initTiles <T>(MapTile[,] tiles, TileConstructor <T> objectConstruction) where T : MapTile { T[,] mapPieces = new T[tiles.GetUpperBound(0) + 1, tiles.GetUpperBound(1) + 1]; MapTile tile; for (int y = 0; y <= mapPieces.GetUpperBound(0); y++) { for (int x = 0; x <= mapPieces.GetUpperBound(1); x++) { tile = tiles[y, x]; if (tile != null) { mapPieces[y, x] = objectConstruction.Invoke(tile); } else { mapPieces[y, x] = null; } } } return(mapPieces); }
public PathFinderFast(Level level) { if (level == null) { throw new Exception("Map cannot be null"); } if (level.mapTiles == null) { throw new Exception("Grid cannot be null"); } mLevel = level; mGrid = level.mapTiles; mGridX = (ushort)(mGrid.GetUpperBound(0) + 1); mGridY = (ushort)(mGrid.GetUpperBound(1) + 1); mGridXMinus1 = (ushort)(mGridX - 1); mGridXLog2 = (ushort)Math.Log(mGridX, 2); if (Math.Log(mGridX, 2) != (int)Math.Log(mGridX, 2) || Math.Log(mGridY, 2) != (int)Math.Log(mGridY, 2)) { throw new Exception("Invalid Grid, size in X and Y must be power of 2"); } if (nodes == null || nodes.Length != (mGridX * mGridY)) { nodes = new List <PathFinderNodeFast> [mGridX * mGridY]; touchedLocations = new Stack <int>(mGridX * mGridY); mClose = new List <Vector2i>(mGridX * mGridY); } for (var i = 0; i < nodes.Length; ++i) { nodes[i] = new List <PathFinderNodeFast>(1); } mOpen = new PriorityQueueB <Location>(new ComparePFNodeMatrix(nodes)); }
public void SetupMap(double PerlinDiff, double Seed, double HeightBias, double Zoom) { map = new MapTile[width, height]; PerlinNoise p = new PerlinNoise(); //Generate tiles for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { //Map generation //Calculate perlin double mHeight = p.perlin(x * PerlinDiff, y * PerlinDiff, Seed); //Modify perlin value for more extremes mHeight = mHeight * Zoom - HeightBias; mHeight = mHeight < 0 ? 0 : mHeight; //Remove negative values mHeight = mHeight > 1 ? 1 : mHeight; //Remove values larger than 1 MapTileTypeEnum mapTileEnum = MapTileTypeEnum.land; if (mHeight < 0.2) { mapTileEnum = MapTileTypeEnum.deepWater; } else if (mHeight < 0.4) { mapTileEnum = MapTileTypeEnum.shallowWater; } else if (mHeight < 0.6) { mapTileEnum = MapTileTypeEnum.land; } else if (mHeight < 0.8) { mapTileEnum = MapTileTypeEnum.hill; } else if (mHeight <= 1.0) { mapTileEnum = MapTileTypeEnum.mountain; } map[x, y] = new MapTile(new Point(x, y), new MapTileType { type = mapTileEnum }, mHeight); } } //Add neighbours as they are now initialised for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { map[x, y].GetNeighbours(this); } } //Generate continents int counter = 0; Random colorGenerator = new Random(); continents = new List <Continent>(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (map[x, y].continent == null) { Continent continent = new Continent(); map = continent.NewContinent(this, new Point(x, y), counter++.ToString(), colorGenerator).map; continents.Add(continent); } } } //Find largest land continent for road TODO: Do this for all continents of certain size int maxSize = 0; Continent maxContinent = new Continent(); foreach (Continent continent in continents) { if (continent.Type == MapTileTypeEnum.land && maxSize < continent.tiles.Count) { maxSize = continent.tiles.Count; maxContinent = continent; } } maxContinent.color = Color.Black; //TODO: For edges in continents find all the different zones, not only side //TODO: Create a road between each of the zones goals = new List <MapTile>(); while (true) { if (maxContinent.edges.top.Count != 0) { MapTile toAdd = maxContinent.edges.top[colorGenerator.Next(maxContinent.edges.top.Count)]; if (!goals.Contains(toAdd)) { goals.Add(toAdd); break; } } else { break; } } while (true) { if (maxContinent.edges.bottom.Count != 0) { MapTile toAdd = maxContinent.edges.bottom[colorGenerator.Next(maxContinent.edges.bottom.Count)]; if (!goals.Contains(toAdd)) { goals.Add(toAdd); break; } } else { break; } } while (true) { if (maxContinent.edges.left.Count != 0) { MapTile toAdd = maxContinent.edges.left[colorGenerator.Next(maxContinent.edges.left.Count)]; if (!goals.Contains(toAdd)) { goals.Add(toAdd); break; } } else { break; } } while (true) { if (maxContinent.edges.right.Count != 0) { MapTile toAdd = maxContinent.edges.right[colorGenerator.Next(maxContinent.edges.right.Count)]; if (!goals.Contains(toAdd)) { goals.Add(toAdd); break; } } else { break; } } //Skip code to create path when there are to few goals if (goals.Count <= 1) { return; } for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { map[x, y].InitialiseDistances(goals.Count); map[x, y].GoalIDs = goals.ConvertAll(g => g.id).ToArray(); for (int i = 0; i < goals.Count; i++) { map[x, y].Costs[i] = -1; } } } CalculateCost(ref map); //Path creation List <MapTile> toDraw = new List <MapTile>(goals); int positionsLength = toDraw.Count; IEnumerable <IEnumerable <int> > rawPossibilites = GetPermutations(Enumerable.Range(0, positionsLength).ToList(), positionsLength); List <List <int> > possibilites = rawPossibilites.ToList().ConvertAll(i => i.ToList()); //Save shortest path double shortestLength = double.MaxValue; MapTile[] shortestGoals = new MapTile[positionsLength]; //Calculate the length of each path option foreach (IEnumerable <int> possibility in possibilites) { //Generate order MapTile[] order = new MapTile[positionsLength]; foreach (int index in possibility) { order[index] = toDraw[index]; } //Initialise variables for path finding //Copy map MapTile[,] localMap = new MapTile[map.GetUpperBound(0) + 1, map.GetUpperBound(1) + 1]; for (int x = 0; x <= map.GetUpperBound(0); x++) { for (int y = 0; y <= map.GetUpperBound(1); y++) { localMap[x, y] = (MapTile)map[x, y].Clone(); } } double length = 0; List <MapTile> localGoals = order.ToList(); localGoals.RemoveAt(0); //Calculate path length FindPath(order.ToList(), ref localMap, ref length, localGoals.ToArray()); //Check if shortest if (length < shortestLength) { shortestLength = length; shortestGoals = order; } } //Draw path pathLength = 0; //This is starting position toDraw.Remove(goals[0]); FindPath(shortestGoals.ToList(), ref map, ref pathLength, goals.ToArray()); //Clean up path //CleanPath(); }