private static void Move(int characterId) { // Find spot to move to that is open and doesn't have anybody else. Character current = CharacterManager.ActiveCharacters[characterId]; List <AlgorithmTile> possiblePositions = MapAlgorithms.ResultMapToAlgorithmTileList( MapAlgorithms.BfsReturnRange(RawMapManager.Map, current.Position, Math.Min(current.Movement, current.CurrentEnergy), true, true) ); // Randomize list for (int i = possiblePositions.Count - 1; i >= 1; i--) { int swap = Random.Range(0, i); AlgorithmTile tmp = possiblePositions[i]; possiblePositions[i] = possiblePositions[swap]; possiblePositions[swap] = tmp; } MapPosition newPosition = current.Position; for (int i = 0; i < possiblePositions.Count; i++) { if (RawMapManager.Map[possiblePositions[i].Position.Z][possiblePositions[i].Position.X].TileId == 0 && RawMapManager.Map[possiblePositions[i].Position.Z][possiblePositions[i].Position.X].CharacterId == -1) { newPosition = possiblePositions[i].Position; break; } } /* string message = current.Position.ToString(); * message += Environment.NewLine; * foreach (var i in possiblePositions) { * message += $", {i}"; * } * print(message);*/ ActionManager.MoveCharacter(characterId, newPosition); }
public static AlgorithmTile[][] BfsReturnRange(MapTile[][] map, MapPosition start, int range, bool excludeOccupied, bool excludeWall) { // Set up resultMap board AlgorithmTile[][] resultMap = new AlgorithmTile[map.Length][]; for (int i = 0; i < map.Length; i++) { resultMap[i] = new AlgorithmTile[map[i].Length]; } for (int z = 0; z < resultMap.Length; z++) { for (int x = 0; x < resultMap[z].Length; x++) { resultMap[z][x] = new AlgorithmTile(new MapPosition(x, z), false, -1); } } // BFS MapPosition[] cardinalDirections = { new MapPosition(0, 1), new MapPosition(1, 0), new MapPosition(0, -1), new MapPosition(-1, 0) }; Queue <MapPosition> nextPositions = new Queue <MapPosition>(); resultMap[start.Z][start.X].Distance = 0; resultMap[start.Z][start.X].Visited = true; nextPositions.Enqueue(start); while (nextPositions.Any()) { MapPosition current = nextPositions.Dequeue(); // Check to see if the current position is the furthest possible distance from start if (resultMap[current.Z][current.X].Distance >= range) { int dist = resultMap[current.Z][current.X].Distance; continue; } for (int i = 0; i < 4; i++) { MapPosition considering = current + cardinalDirections[i]; // Outside map? if (considering.X < 0 || considering.X >= resultMap[0].Length || considering.Z < 0 || considering.Z >= resultMap.Length) { continue; } // Already visited? if (resultMap[considering.Z][considering.X].Visited) { continue; } if (excludeOccupied && RawMapManager.Map[considering.Z][considering.X].CharacterId != -1) { continue; } if (excludeWall && RawMapManager.Map[considering.Z][considering.X].TileId == 1) { continue; } resultMap[considering.Z][considering.X].Visited = true; resultMap[considering.Z][considering.X].Distance = resultMap[current.Z][current.X].Distance + 1; nextPositions.Enqueue(considering); } } return(resultMap); }