public GameStateInternal(GameState state) { TickNumber = state.TickNumber; Enemies = new PlayerInternal[state.Players.Length - 1]; int enemyIndex = 0; foreach (var player in state.Players) { if (player.Id == Constants.MyId) { Me = new PlayerInternal(player); } else { var enemy = new PlayerInternal(player); enemy.UpdateTimeMap(); Enemies[enemyIndex++] = enemy; } } Bonuses = state.Bonuses.Select(b => new BonusInfo { Type = b.Type, Position = b.Position.ConvertToLogic(GameParams.CellSize), Steps = b.Steps }).ToArray(); PreviousState = null; }
private static bool CheckIsCollisionPossible(PlayerInternal me, PlayerInternal enemy, Point myPrevPosition, int simulationTicks, int timeForMove) { // TODO В будущем можно оптимизировать: вычислять соседей только один раз, а не для каждого врага for (int i = -1; i <= 1; i++) { var direction = (Direction)(((int)me.Direction.Value + i + 4) % 4); var pointToCheck = me.Position.MoveLogic(direction); if (IsCollision(pointToCheck)) { return(true); } pointToCheck = myPrevPosition.MoveLogic(direction); if (IsCollision(pointToCheck)) { return(true); } } var prevPoint = myPrevPosition.MoveLogic(me.Direction.Value.GetOpposite()); if (IsCollision(prevPoint)) { return(enemy.TimeMap[myPrevPosition.X, myPrevPosition.Y] - enemy.TimeMap[prevPoint.X, prevPoint.Y] < timeForMove); } return(false); bool IsCollision(Point point) { return(GameParams.MapSize.ContainsPoint(point) && enemy.TimeMap[point.X, point.Y] < simulationTicks + timeForMove); } }
public GameStateInternal(int tickNumber, PlayerInternal me, PlayerInternal[] enemies, BonusInfo[] bonuses, GameStateInternal previousState, int[,] dangerousMap) { _dangerousMap = dangerousMap; TickNumber = tickNumber; Me = me; Enemies = enemies; Bonuses = bonuses; PreviousState = previousState; }
public static unsafe Path GetShortestPathToHome(PlayerInternal player) { var queue = stackalloc int[GameParams.MapSize.Width * GameParams.MapSize.Height]; int queueHead = 0; int queueTail = 0; var visited = stackalloc bool[GameParams.MapSize.Width * GameParams.MapSize.Height]; var moves = stackalloc int[GameParams.MapSize.Width * GameParams.MapSize.Height]; var startPoint = player.PathToNextPositionLength == 0 ? player.Position : player.Position.MoveLogic(player.Direction.Value); if (player.Territory.Contains(startPoint)) { return(player.PathToNextPositionLength == 0 ? Path.Empty : new Path(new[] { startPoint })); } var prevPoint = player.PathToNextPositionLength > 0 ? player.Position : player.Position.MoveLogic(player.Direction.Value.GetOpposite()); visited[startPoint.X + startPoint.Y * GameParams.MapSize.Width] = true; moves[startPoint.X + startPoint.Y * GameParams.MapSize.Width] = 0; queue[queueHead++] = startPoint.X + startPoint.Y * GameParams.MapSize.Width; while (queueTail != queueHead) { int coord = queue[queueTail++]; var point = new Point(coord % GameParams.MapSize.Width, coord / GameParams.MapSize.Width); int currentPathLength = moves[coord]; foreach (var neighbor in point.GetNeighbors()) { if (point == startPoint && neighbor == prevPoint) { continue; } int neighborCoord = neighbor.X + neighbor.Y * GameParams.MapSize.Width; if (player.Territory.Contains(neighbor)) { moves[neighborCoord] = currentPathLength + 1; return(GetPath(neighbor)); } if (GameParams.MapSize.ContainsPoint(neighbor) && !visited[neighborCoord] && !player.Tail.AsPointsSet().Contains(neighbor)) { visited[neighborCoord] = true; moves[neighborCoord] = currentPathLength + 1; queue[queueHead++] = neighborCoord; } } } return(null); Path GetPath(Point currentPoint) { if (player.PathToNextPositionLength == 0) { int currentLength = moves[currentPoint.X + currentPoint.Y * GameParams.MapSize.Width]; var resultPath = new Point[currentLength]; for (int i = currentLength - 1; i >= 0; i--) { resultPath[i] = currentPoint; var validNeighbors = currentPoint.GetNeighbors().Where(p => GameParams.MapSize.ContainsPoint(p)); foreach (var validNeighbor in validNeighbors) { if (moves[validNeighbor.X + validNeighbor.Y * GameParams.MapSize.Width] == i) { currentPoint = validNeighbor; break; } } } return(new Path(resultPath)); } else { int currentLength = moves[currentPoint.X + currentPoint.Y * GameParams.MapSize.Width]; var resultPath = new Point[currentLength + 1]; for (int i = currentLength; i >= 1; i--) { resultPath[i] = currentPoint; var validNeighbors = currentPoint.GetNeighbors().Where(p => GameParams.MapSize.ContainsPoint(p)); foreach (var validNeighbor in validNeighbors) { if (moves[validNeighbor.X + validNeighbor.Y * GameParams.MapSize.Width] == i - 1) { currentPoint = validNeighbor; break; } } } resultPath[0] = startPoint; return(new Path(resultPath)); } } }