public int[,] Initial() { var homePoints = new List <(Point Point, Direction SourceDirection, int PathLength)>(); var map = Game.GetNewMap <int>(); Utils.FastCopyArray(Game.NoEnemiesDangerousMap, map, GameParams.MapSize.Width * GameParams.MapSize.Height); var visited = Game.GetNewMap <bool>(); map[_position.X, _position.Y] = 0; visited[_position.X, _position.Y] = true; var queue = new Queue <Point>(GameParams.MapSize.Width * GameParams.MapSize.Height); queue.Enqueue(_position); while (queue.Count > 0) { var currentPoint = queue.Dequeue(); int currentLength = map[currentPoint.X, currentPoint.Y]; foreach (var direction in EnumValues.GetAll <Direction>()) { var neighbor = currentPoint.MoveLogic(direction); if (!GameParams.MapSize.ContainsPoint(neighbor) || _tail.AsPointsSet().Contains(neighbor)) { continue; } if (_territory.Contains(neighbor) && !_territory.Contains(currentPoint)) { homePoints.Add((neighbor, direction, currentLength + 1)); } if (visited[neighbor.X, neighbor.Y]) { continue; } map[neighbor.X, neighbor.Y] = currentLength + 1; visited[neighbor.X, neighbor.Y] = true; queue.Enqueue(neighbor); } } if (homePoints.Count == 0) { return(map); } for (int y = 0; y < GameParams.MapSize.Height; y++) { for (int x = 0; x < GameParams.MapSize.Width; x++) { map[x, y] = Math.Min(map[x, y], homePoints.Min(p => p.Point.GetDistanceTo(new Point(x, y), p.SourceDirection))); } } return(map); }
public int[,] DoubleSides() { var map = Game.GetNewMap <int>(); Utils.FastCopyArray(Game.NoEnemiesDangerousMap, map, GameParams.MapSize.Width * GameParams.MapSize.Height); var visited = Game.GetNewMap <bool>(); var mapAfterHome = Game.GetNewMap <int>(); var visitedAfterHome = Game.GetNewMap <bool>(); map[_position.X, _position.Y] = 0; visited[_position.X, _position.Y] = true; var queue = new Queue <(Point Point, bool AfterHome, Direction?VisitHomeDirection)>(GameParams.MapSize.Width * GameParams.MapSize.Height); queue.Enqueue((_position, false, null)); bool visitHome = false; while (queue.Count > 0) { (var currentPoint, bool afterHome, var visitHomeDirection) = queue.Dequeue(); if (!afterHome) { int currentLength = map[currentPoint.X, currentPoint.Y]; foreach (var direction in EnumValues.GetAll <Direction>()) { var neighbor = currentPoint.MoveLogic(direction); if (!GameParams.MapSize.ContainsPoint(neighbor) || _tail.AsPointsSet().Contains(neighbor)) { continue; } if (_territory.Contains(neighbor) && !_territory.Contains(currentPoint) && !visitedAfterHome[neighbor.X, neighbor.Y]) { queue.Enqueue((neighbor, true, direction)); mapAfterHome[neighbor.X, neighbor.Y] = currentLength + 1; visitHome = true; } if (visited[neighbor.X, neighbor.Y]) { continue; } map[neighbor.X, neighbor.Y] = currentLength + 1; visited[neighbor.X, neighbor.Y] = true; queue.Enqueue((neighbor, false, null)); } } else { int currentLength = mapAfterHome[currentPoint.X, currentPoint.Y]; foreach (var direction in EnumValues.GetAll <Direction>()) { var neighbor = currentPoint.MoveLogic(direction); if (!GameParams.MapSize.ContainsPoint(neighbor) || visitedAfterHome[neighbor.X, neighbor.Y] || visitHomeDirection == direction.GetOpposite()) { continue; } mapAfterHome[neighbor.X, neighbor.Y] = currentLength + 1; visitedAfterHome[neighbor.X, neighbor.Y] = true; queue.Enqueue((neighbor, true, null)); } } } if (!visitHome) { return(map); } for (int y = 0; y < GameParams.MapSize.Height; y++) { for (int x = 0; x < GameParams.MapSize.Width; x++) { map[x, y] = Math.Min(map[x, y], mapAfterHome[x, y]); } } return(map); }