public string GetTileUrl(TileCoordinate tile) { //combine the user supplied values & defaults and override defaults NameValueCollection dict = new NameValueCollection(); foreach (string item in DefaultQueryStringValues) dict[item] = DefaultQueryStringValues[item]; foreach (string item in QueryStringValues) dict[item] = QueryStringValues[item]; return TileHelper.GetAGSDynamicUrlAddress(MapServiceUrl, dict , new TileCoordinate() { Level = tile.Level, Column = tile.Column, Row = tile.Row }); }
// Return false if there is no available spawn location, otherwise return true private bool GetRandomSpawnLocation(TileCoordinate targetCrop, out TileCoordinate spawnTile) { TileCoordinate mapSize = GameController.TileMap.GetSize(); // Hold the directions corresponding to the unoccupied spawn tiles // Ex: Direction.Left is the (unoccupied) tile that is left of the target tile List <Enemy.Direction> unoccupied = new List <Enemy.Direction>() { Enemy.Direction.Left, Enemy.Direction.Right, Enemy.Direction.Up, Enemy.Direction.Down }; // Get which spawn locations are still available OccupiedSpawns occupied; if (_occupiedSpawns.TryGetValue(targetCrop, out occupied)) { // Left tile is occupied if (occupied.IsLeftOccupied) { unoccupied.Remove(Enemy.Direction.Left); } // Right tile is occupied if (occupied.IsRightOccupied) { unoccupied.Remove(Enemy.Direction.Right); } // Up tile is occupied if (occupied.IsUpOccupied) { unoccupied.Remove(Enemy.Direction.Up); } // Down tile is occupied if (occupied.IsDownOccupied) { unoccupied.Remove(Enemy.Direction.Down); } } // Randomly pick the spawn tile from remaining spawns spawnTile = new TileCoordinate(); if (unoccupied.Count == 0) { return(false); } int randomPicked = _randomNum.Next(unoccupied.Count); switch (unoccupied[randomPicked]) { case Enemy.Direction.Left: spawnTile = new TileCoordinate(-1, targetCrop.CoordZ); occupied.IsLeftOccupied = true; break; case Enemy.Direction.Right: spawnTile = new TileCoordinate(mapSize.CoordX, targetCrop.CoordZ); occupied.IsRightOccupied = true; break; case Enemy.Direction.Up: spawnTile = new TileCoordinate(targetCrop.CoordX, mapSize.CoordZ); occupied.IsUpOccupied = true; break; case Enemy.Direction.Down: spawnTile = new TileCoordinate(targetCrop.CoordX, -1); occupied.IsDownOccupied = true; break; } // Update occupied tiles _occupiedSpawns.Remove(targetCrop); _occupiedSpawns.Add(targetCrop, occupied); Debug.Log("Spawn Location [x:" + spawnTile.CoordX + " z:" + spawnTile.CoordZ + "] - for Target Crop: [x:" + targetCrop.CoordX + " z:" + targetCrop.CoordZ + "]"); return(true); }
/// <summary> /// Given an array of tiles and a starting coordinate, /// find all reachable tiles (and paths to get to those tiles). /// This is implemented using a modified form of Djikstra's algorithm. /// </summary> /// <param name="tiles"></param> /// <param name="startCoord"></param> public static void FindReachableTiles( int rows, int cols, int[,] dist, Coordinate[,] prev, Tile[,] tiles, Coordinate startCoord, int movementPoints) { var frontier = new MinHeap <TileCoordinateNode>(); TileCoordinate startTileCoordinate = new TileCoordinate( tiles[startCoord.r, startCoord.c], startCoord); TileCoordinateNode startNode = new TileCoordinateNode(startTileCoordinate, 0); frontier.Insert(startNode); for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { Coordinate coord = new Coordinate(r, c); if (!coord.Equals(startCoord)) { dist[coord.r, coord.c] = int.MaxValue; prev[coord.r, coord.c] = null; } else { dist[coord.r, coord.c] = 0; prev[coord.r, coord.c] = null; // doesn't matter for start coord } } } while (frontier.HeapSize() > 0) { TileCoordinateNode node = frontier.Pop(); TileCoordinate tileCoordinate = node.tileCoordinate; Coordinate coordinate = tileCoordinate.coordinate; foreach (TileCoordinate adjacentTileCoord in GetAdjacentTiles(tiles, coordinate)) { Coordinate adjacentCoord = adjacentTileCoord.coordinate; // watch for overflow here int calculatedDist = dist[coordinate.r, coordinate.c] + adjacentTileCoord.tile.movementCost; bool calculatedDistPreferrable = dist[adjacentCoord.r, adjacentCoord.c] == int.MaxValue || calculatedDist < dist[adjacentCoord.r, adjacentCoord.c]; if (calculatedDistPreferrable && calculatedDist <= movementPoints) { dist[adjacentCoord.r, adjacentCoord.c] = calculatedDist; prev[adjacentCoord.r, adjacentCoord.c] = coordinate; TileCoordinateNode adjacentNode = new TileCoordinateNode(adjacentTileCoord, calculatedDist); if (!frontier.Contains(adjacentNode)) { frontier.Insert(adjacentNode); } else { frontier.DecreaseKey(adjacentNode, adjacentNode); } } } } }
void ConnectClosestRooms(List <Room> allRooms, bool forceAccessibilityFromMainRoom = false) { List <Room> roomListA = new List <Room>(); List <Room> roomListB = new List <Room>(); if (forceAccessibilityFromMainRoom) { foreach (Room room in allRooms) { if (room.isAccessibleFromMainRoom) { roomListB.Add(room); } else { roomListA.Add(room); } } } else { roomListA = allRooms; roomListB = allRooms; } int bestDistance = 0; TileCoordinate bestTileA = new TileCoordinate(); TileCoordinate bestTileB = new TileCoordinate(); Room bestRoomA = new Room(); Room bestRoomB = new Room(); bool possibleConnectionFound = false; foreach (Room roomA in roomListA) { if (!forceAccessibilityFromMainRoom) { possibleConnectionFound = false; if (roomA.connectedRooms.Count > 0) { continue; } } foreach (Room roomB in roomListB) { if (roomA == roomB || roomA.IsConected(roomB))//if the room is checking itself or is already connected to the room its checking then skip to the next loop { continue; } for (int tileIndexA = 0; tileIndexA < roomA.edgeTiles.Count; tileIndexA++) { for (int tileIndexB = 0; tileIndexB < roomB.edgeTiles.Count; tileIndexB++) { TileCoordinate tileA = roomA.edgeTiles[tileIndexA]; TileCoordinate tileB = roomB.edgeTiles[tileIndexB]; int distanceBetweenRooms = (int)(Mathf.Pow(tileA.tileX - tileB.tileX, 2) + Mathf.Pow(tileA.tileY - tileB.tileY, 2)); // checking the distance between the two rooms (formula provided by tutorial) if (distanceBetweenRooms < bestDistance || !possibleConnectionFound) // if the distance found is less than the current best distance //and a possible connection has not been found then a new best result has been identified //and a new set of results need to be applied { bestDistance = distanceBetweenRooms; possibleConnectionFound = true; bestTileA = tileA; bestTileB = tileB; bestRoomA = roomA; bestRoomB = roomB; } } } } if (possibleConnectionFound && !forceAccessibilityFromMainRoom)//if the room has a possible connection and isnt set to be forced to connect then crate the best passage { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); } } if (possibleConnectionFound && forceAccessibilityFromMainRoom)// if a possible connection has been found and is set to force accessibilty thn craete teh bassage and rerun the method { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); ConnectClosestRooms(allRooms, true); } if (!forceAccessibilityFromMainRoom) { ConnectClosestRooms(allRooms, true); } }
public void SetTile(TileCoordinate tilePos, TileType type) { _tiles[GetTileIndex(tilePos)] = type; _tileMap.UpdateCropArray(tilePos, type); }
public LayerHandler(ref Scene scene) { Scene = scene; TileCoordinate = new TileCoordinate(); Loader = new LayerLoader(); }
/// <summary> /// Loops through all rooms and finds and connects the closest rooms /// </summary> /// <param name="allRooms"></param> /// <param name="forceAccessibilityFromMainRoom"></param> protected virtual void ConnectClosestRooms(List <Room> allRooms, bool forceAccessibilityFromMainRoom = false) { List <Room> roomListA = new List <Room>(); List <Room> roomListB = new List <Room>(); if (forceAccessibilityFromMainRoom) { foreach (Room room in allRooms) { if (room.IsAccessibleFromMainRoom) { roomListB.Add(room); } else { roomListA.Add(room); } } } else { roomListA = allRooms; roomListB = allRooms; } int bestDistance = 0; TileCoordinate bestTileA = new TileCoordinate(); TileCoordinate bestTileB = new TileCoordinate(); Room bestRoomA = new Room(); Room bestRoomB = new Room(); bool possibleConnectionFound = false; foreach (Room roomA in roomListA) { if (!forceAccessibilityFromMainRoom) { possibleConnectionFound = false; if (roomA.ConnectedRooms.Count > 0) { continue; } } foreach (Room roomB in roomListB) { if (roomA == roomB || roomA.IsConnected(roomB)) { continue; } for (int tileIndexA = 0; tileIndexA < roomA.EdgeTiles.Count; tileIndexA++) { for (int tileIndexB = 0; tileIndexB < roomB.EdgeTiles.Count; tileIndexB++) { TileCoordinate tileA = roomA.EdgeTiles[tileIndexA]; TileCoordinate tileB = roomB.EdgeTiles[tileIndexB]; int distanceBetweenRooms = (int)(Mathf.Pow(tileA.TileX - tileB.TileX, 2) + Mathf.Pow(tileA.TileY - tileB.TileY, 2)); if (distanceBetweenRooms < bestDistance || !possibleConnectionFound) { bestDistance = distanceBetweenRooms; possibleConnectionFound = true; bestTileA = tileA; bestTileB = tileB; bestRoomA = roomA; bestRoomB = roomB; } } } } if (possibleConnectionFound && !forceAccessibilityFromMainRoom) { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); } } if (possibleConnectionFound && forceAccessibilityFromMainRoom) { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); ConnectClosestRooms(allRooms, true); } if (!forceAccessibilityFromMainRoom) { ConnectClosestRooms(allRooms, true); } }
// Initialize the tile map's data (all the tiles) private void CreateLevel() { _mapData = new TileData(this, _levelData.TileLayout.width, _levelData.TileLayout.height); // Clear existing entities foreach (Transform child in transform) { GameObject.DestroyImmediate(child.gameObject); } // Create the map's tiles and entities for (int x = 0; x < _levelData.TileLayout.width; ++x) { for (int z = 0; z < _levelData.TileLayout.height; ++z) { TileCoordinate tilePos = new TileCoordinate(x, z); CreateTile(tilePos); } } GameObject player = CreateEntity(_levelData.PlayerSpawn, ( GameObject )Resources.Load("PlayerChar")); _player = player.GetComponent <Player>(); Debug.Log("height:" + _levelData.TileLayout.height); Debug.Log("width:" + _levelData.TileLayout.width); // Create left map border shadow float HalfTileSize = _tileSize / 2; GameObject leftShadow = Instantiate(ShadowObject); leftShadow.transform.localScale = new Vector3(1, _levelData.TileLayout.height, 1); leftShadow.transform.position = new Vector3(HalfTileSize, SHADOW_Y_OFFSET, _levelData.TileLayout.height / 2.0f); leftShadow.transform.parent = transform; // Create right map border shadow GameObject rightShadow = Instantiate(ShadowObject); rightShadow.transform.localScale = new Vector3(1, _levelData.TileLayout.height, 1); rightShadow.transform.position = new Vector3(_levelData.TileLayout.width - HalfTileSize, SHADOW_Y_OFFSET, _levelData.TileLayout.height / 2.0f); rightShadow.transform.parent = transform; rightShadow.transform.eulerAngles = new Vector3(90, 180, 0); // Create top map border shadow GameObject topShadow = Instantiate(ShadowObject); topShadow.transform.localScale = new Vector3(1, _levelData.TileLayout.width, 1); topShadow.transform.position = new Vector3(_levelData.TileLayout.width / 2.0f, SHADOW_Y_OFFSET, _levelData.TileLayout.height - HalfTileSize); topShadow.transform.parent = transform; topShadow.transform.eulerAngles = new Vector3(90, 90, 0); // Create bottom map border shadow GameObject bottomShadow = Instantiate(ShadowObject); bottomShadow.transform.localScale = new Vector3(1, _levelData.TileLayout.width, 1); bottomShadow.transform.position = new Vector3(_levelData.TileLayout.width / 2.0f, SHADOW_Y_OFFSET, HalfTileSize - 0.01f); bottomShadow.transform.parent = transform; bottomShadow.transform.eulerAngles = new Vector3(90, -90, 0); }
public static string GetWMSUrlAddress(string wmsVersion, string MapServiceUrl, NameValueCollection dict, TileCoordinate tileCoordinate) { return GetWMSUrlAddress(wmsVersion, MapServiceUrl, dict, tileCoordinate.Level, tileCoordinate.Row, tileCoordinate.Column); }
public static string GetOSMTileUrlAddressWithSubdomains(string baseUrl, List<string> subDomains, TileCoordinate tile) { return GetOSMTileUrlAddressWithSubdomains(baseUrl, subDomains, tile.Level, tile.Row, tile.Column); }
public static string GetOSMTileUrlAddress(string baseUrl, TileCoordinate tile) { return GetOSMTileUrlAddress(baseUrl, tile.Level, tile.Row, tile.Column); }
public static string GetAGSDynamicUrlAddress(string baseUrl, NameValueCollection dict, TileCoordinate tile) { return GetAGSDynamicUrlAddress(baseUrl, dict, tile.Level, tile.Row, tile.Column); }
private void RenderCursor(int dimension, TileCoordinate newMouseCoordinate) { _mark.Height = dimension; _mark.Width = dimension; RenderCursorElement(_mark, dimension, newMouseCoordinate); }
public VisualizationCommand(Vector2Int coordinate) { Coordinate = coordinate; }
private void ProcessNodeDepthFirst(ref PathfindingResult results, Map map, TileCoordinate targetCoords, TileCoordinate nodeCoords, TileCoordinate prevNodeCoords) { if (results.IsResultFound) { return; } var aggregator = new PathAggregator(nodeCoords, prevNodeCoords); if (results.Aggregator.ContainsKey(nodeCoords)) { return; } results.Visualizations.Enqueue(new VisualizationCommand(nodeCoords)); results.Aggregator.Add(nodeCoords, prevNodeCoords); if (nodeCoords == targetCoords) { results.IsResultFound = true; return; } var neighbours = map.GetNeighbouringTiles(nodeCoords); foreach (var potentialNeighbour in neighbours) { if (!potentialNeighbour.HasValue) { continue; } ProcessNodeDepthFirst(ref results, map, targetCoords, potentialNeighbour.Value, nodeCoords); } }
public static bool IsNewTileCoordinate(TileCoordinate newMouseCoordinate, TileCoordinate lastMouseCoordinate) { return(newMouseCoordinate != lastMouseCoordinate); }
public string GetTileUrl(TileCoordinate tile) { return TileHelper.GetOSMTileUrlAddressWithSubdomains(UrlTemplate, SubDomains, tile); }
private void BuildRiver(int levelDepth, int levelWidth, Vector3 riverOrigin, LevelData levelData) { HashSet <Vector3> visitedCoordinates = new HashSet <Vector3>(); // the first coordinate is the river origin Vector3 currentCoordinate = riverOrigin; bool foundWater = false; while (!foundWater) { // convert from Level Coordinate System to Tile Coordinate System and retrieve the corresponding TileData TileCoordinate tileCoordinate = levelData.ConvertToTileCoordinate((int)currentCoordinate.z, (int)currentCoordinate.x); TileData tileData = levelData.tilesData[tileCoordinate.tileZIndex, tileCoordinate.tileXIndex]; // save the current coordinate as visited visitedCoordinates.Add(currentCoordinate); // check if we have found water if (tileData.chosenHeightTerrainTypes[tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex].name == "water") { // if we found water, we stop foundWater = true; } else { // change the texture of the tileData to show a river tileData.texture.SetPixel(tileCoordinate.coordinateXIndex, tileCoordinate.coordinateZIndex, this.riverColor); tileData.texture.Apply(); // pick neighbor coordinates, if they exist List <Vector3> neighbors = new List <Vector3>(); if (currentCoordinate.z > 0) { neighbors.Add(new Vector3(currentCoordinate.x, 0, currentCoordinate.z - 1)); } if (currentCoordinate.z < levelDepth - 1) { neighbors.Add(new Vector3(currentCoordinate.x, 0, currentCoordinate.z + 1)); } if (currentCoordinate.x > 0) { neighbors.Add(new Vector3(currentCoordinate.x - 1, 0, currentCoordinate.z)); } if (currentCoordinate.x < levelWidth - 1) { neighbors.Add(new Vector3(currentCoordinate.x + 1, 0, currentCoordinate.z)); } // find the minimum neighbor that has not been visited yet and flow to it float minHeight = float.MaxValue; Vector3 minNeighbor = new Vector3(0, 0, 0); foreach (Vector3 neighbor in neighbors) { // convert from Level Coordinate System to Tile Coordinate System and retrieve the corresponding TileData TileCoordinate neighborTileCoordinate = levelData.ConvertToTileCoordinate((int)neighbor.z, (int)neighbor.x); TileData neighborTileData = levelData.tilesData[neighborTileCoordinate.tileZIndex, neighborTileCoordinate.tileXIndex]; // if the neighbor is the lowest one and has not been visited yet, save it float neighborHeight = tileData.heightMap[neighborTileCoordinate.coordinateZIndex, neighborTileCoordinate.coordinateXIndex]; if (neighborHeight < minHeight && !visitedCoordinates.Contains(neighbor)) { minHeight = neighborHeight; minNeighbor = neighbor; } } // flow to the lowest neighbor currentCoordinate = minNeighbor; } } }
public string GetTileUrl(TileCoordinate tile) { var gtile = TileHelper.ConvertTMSTileCoordinateToGoogleTileCoordinate(tile.Level, tile.Column, tile.Row); return TileHelper.GetOSMTileUrlAddress(MapServiceUrl, new TileCoordinate() { Level = tile.Level, Column = gtile.X, Row = gtile.Y }); }
/// <summary> /// Constructor. /// </summary> /// <param name="upperLeft"> /// the upper left tile coordinate </param> /// <param name="amountTilesHorizontal"> /// the amount of columns </param> /// <param name="amountTilesVertical"> /// the amount of rows </param> public TileGridLayout(TileCoordinate upperLeft, int amountTilesHorizontal, int amountTilesVertical) : base() { this.upperLeft = upperLeft; this.amountTilesHorizontal = amountTilesHorizontal; this.amountTilesVertical = amountTilesVertical; }
// Check whether this enemy is currently on the targetFinalPos tile protected bool IsOnTargetTile() { TileCoordinate dist = HelperFunctions.GetTileDistance(currentTilePos, targetFinalPos); return(dist.CoordX == 0 && dist.CoordZ == 0); }
// Calculate the tile index from its tile coordinates public int GetTileIndex(TileCoordinate tilePos) { return(tilePos.CoordZ * _sizeX + tilePos.CoordX); }
// Set the targetFinalPos that this enemy should move toward public void SetTargetTile(TileCoordinate tile) { targetFinalPos = tile; UpdateMovingDirection(); }
private void Hm_UriRequested(HttpMapTileDataSource sender, MapTileUriRequestedEventArgs args) { var res = TileCoordinate.ReverseGeoPoint(args.X, args.Y, args.ZoomLevel); args.Request.Uri = new Uri($"https://maps.googleapis.com/maps/api/staticmap?center={res.Latitude},{res.Longitude}&zoom={args.ZoomLevel}&maptype=traffic&size=256x256&key={AppCore.GoogleMapAPIKey}", UriKind.RelativeOrAbsolute); }
public void GenerateTrees(int levelDepth, int levelWidth, float distanceBetweenVertices, LevelData levelData) { // generate a tree noise map using Perlin Noise float[,] treeMap = this.noiseMapGeneration.GenerateSimplexNoiseMap(levelDepth, levelWidth, this.levelScale, 0, 0, seed, this.waves); float levelSizeX = levelWidth * distanceBetweenVertices; float levelSizeZ = levelDepth * distanceBetweenVertices; for (int zIndex = 0; zIndex < levelDepth; zIndex++) { for (int xIndex = 0; xIndex < levelWidth; xIndex++) { // convert from Level Coordinate System to Tile Coordinate System and retrieve the corresponding TileData TileCoordinate tileCoordinate = levelData.ConvertToTileCoordinate(zIndex, xIndex); TileData tileData = levelData.tileData[tileCoordinate.tileZIndex, tileCoordinate.tileXIndex]; int tileWidth = tileData.heightMap.GetLength(1); // calculate the mesh vertex index Vector3[] meshVertices = tileData.mesh.vertices; int vertexIndex = tileCoordinate.coordinateZIndex * tileWidth + tileCoordinate.coordinateXIndex; // get the terrain type of this coordinate TerrainType terrainType = tileData.chosenHeightTerrainTypes[tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; // get the biome of this coordinate Biome biome = tileData.chosenBiomes[tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; // check if it is a water terrain. Trees cannot be placed over the water if (terrainType.name != "water") { float treeValue = treeMap[zIndex, xIndex]; int terrainTypeIndex = terrainType.index; // compares the current tree noise value to the neighbor ones int neighborZBegin = (int)Mathf.Max(0, zIndex - this.neighborRadius[biome.index]); int neighborZEnd = (int)Mathf.Min(levelDepth - 1, zIndex + this.neighborRadius[biome.index]); int neighborXBegin = (int)Mathf.Max(0, xIndex - this.neighborRadius[biome.index]); int neighborXEnd = (int)Mathf.Min(levelWidth - 1, xIndex + this.neighborRadius[biome.index]); float maxValue = 0f; for (int neighborZ = neighborZBegin; neighborZ <= neighborZEnd; neighborZ++) { for (int neighborX = neighborXBegin; neighborX <= neighborXEnd; neighborX++) { float neighborValue = treeMap[neighborZ, neighborX]; // saves the maximum tree noise value in the radius if (neighborValue >= maxValue) { maxValue = neighborValue; } } } // if the current tree noise value is the maximum one, place a tree in this location if (treeValue == maxValue) { Vector3 treePosition = new Vector3(xIndex * distanceBetweenVertices, meshVertices[vertexIndex].y, zIndex * distanceBetweenVertices); GameObject tree = Instantiate(this.treePrefab[biome.index], treePosition, Quaternion.identity) as GameObject; tree.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); } } } } }
Vector3 CoordToWorldPoint(TileCoordinate tile)// change the coordinate to a vector 3 location { return(new Vector3(-width / 2 + .5f + tile.tileX, -height / 2 + .5f + tile.tileY)); }
// Get the type of the tile at the given (x, z) tile coordinate public TileData.TileType GetTile(TileCoordinate tilePos) { return(_mapData.GetTile(tilePos)); }
/// <summary> /// Given an array of tiles and a starting coordinate, /// find all reachable tiles (and paths to get to those tiles). /// This is implemented using a modified form of Djikstra's algorithm. /// /// We return a dictionary of <option, tuple<cost-to-option, path-to-option>>. /// </summary> /// <param name="tiles"></param> /// <param name="startCoord"></param> public static Dictionary <Coordinate, Tuple <int, List <Coordinate> > > FindReachableTiles( Unit unit, Tile[,] tiles) { int rows = Util.GetRows(tiles); int cols = Util.GetCols(tiles); int[,] dist = new int[rows, cols]; Coordinate[,] prev = new Coordinate[rows, cols]; var frontier = new MinHeap <TileCoordinateNode>(); TileCoordinate startTileCoordinate = new TileCoordinate( tiles[unit.location.r, unit.location.c], unit.location); TileCoordinateNode startNode = new TileCoordinateNode(startTileCoordinate, 0); frontier.Insert(startNode); for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { Coordinate coord = new Coordinate(r, c); if (!coord.Equals(unit.location)) { dist[coord.r, coord.c] = int.MaxValue; prev[coord.r, coord.c] = null; } else { dist[coord.r, coord.c] = 0; prev[coord.r, coord.c] = null; // doesn't matter for start coord } } } while (frontier.HeapSize() > 0) { TileCoordinateNode node = frontier.Pop(); TileCoordinate tileCoordinate = node.tileCoordinate; Coordinate coordinate = tileCoordinate.coordinate; foreach (TileCoordinate adjacentTileCoord in GetAllowableAdjacentTiles(tiles, coordinate, unit.board, unit.team)) { Coordinate adjacentCoord = adjacentTileCoord.coordinate; // watch for overflow here int calculatedDist = dist[coordinate.r, coordinate.c] + adjacentTileCoord.tile.movementCost; bool calculatedDistPreferrable = dist[adjacentCoord.r, adjacentCoord.c] == int.MaxValue || calculatedDist < dist[adjacentCoord.r, adjacentCoord.c]; if (calculatedDistPreferrable && calculatedDist <= unit.movementPoints) { dist[adjacentCoord.r, adjacentCoord.c] = calculatedDist; prev[adjacentCoord.r, adjacentCoord.c] = coordinate; TileCoordinateNode adjacentNode = new TileCoordinateNode(adjacentTileCoord, calculatedDist); if (!frontier.Contains(adjacentNode)) { frontier.Insert(adjacentNode); } else { frontier.DecreaseKey(adjacentNode, adjacentNode); } } } } // djikstra finished // now processing and adding to the return dict var answer = new Dictionary <Coordinate, Tuple <int, List <Coordinate> > >(); for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { Coordinate targetCoord = new Coordinate(r, c); int distanceToTarget = dist[r, c]; // cell must also be empty, unless it is the starting coord if (distanceToTarget != int.MaxValue && (targetCoord.Equals(unit.location) || unit.board[targetCoord.r, targetCoord.c] is null)) { /* * Console.WriteLine($"Distance from {unit.currentLocation}" + * $" to {targetCoordinate}" + * $" is: {distanceToTarget}"); */ //string ans = targetCoordinate.ToString(); List <Coordinate> pathToTarget = new List <Coordinate>(); Coordinate currentCoord = targetCoord; // all paths lead to the starting coordinate // and the starting coordinate's prev is null while (prev[currentCoord.r, currentCoord.c] != null) { // ans = $"{prev[targetCoordinate.r, targetCoordinate.c]}, {ans}"; pathToTarget.Insert(0, prev[currentCoord.r, currentCoord.c]); currentCoord = prev[currentCoord.r, currentCoord.c]; } pathToTarget.Add(targetCoord); // Console.WriteLine($"path to {targetCoord}: {String.Join(", ", pathToTarget)}"); answer.Add( targetCoord, new Tuple <int, List <Coordinate> >( distanceToTarget, pathToTarget) ); } } } return(answer); }
// Set the type of the tile at the given (x, z) tile coordinate // and recreate the mesh to reflect the changes public void SetTile(TileCoordinate tilePos, TileData.TileType type) { _mapData.SetTile(tilePos, type); CreateMesh(); }
private PathfindingResult CalculatePathDepthFirst(Map map, TileCoordinate from, TileCoordinate to) { var result = new PathfindingResult(); result.Path = new List <Vector2Int>(); result.UnvisitedSet = new HashSet <TileCoordinate>(); result.VisitedSet = new HashSet <TileCoordinate>(); result.Aggregator = new Dictionary <Vector2Int, Vector2Int>(); result.Visualizations = new Queue <VisualizationCommand>(); result.targetTile = to; ProcessNodeDepthFirst(ref result, map, to, from, new TileCoordinate(-1, -1)); result.ExtractPathFromAggregator(); return(result); }
// Return the vector corresponding to the tile coordinate (x, z) public Vector3 GetPositionAtTile(TileCoordinate tilePos) { return(new Vector3(tilePos.CoordX * _tileSize + _tileSize / 2, 0, tilePos.CoordZ * _tileSize + _tileSize / 2)); }
public PathfindingResult CalculatePath(Map map, TileCoordinate @from, TileCoordinate to) { return(CalculatePathDepthFirst(map, from, to)); }
public WalkMove(IChecker checker, TileCoordinate startLocation, TileCoordinate endLocation) : base(checker) { this._startLocation = startLocation; this._endLocation = endLocation; }