public Path(IEnumerable <Point> points) { _list = new List <Point>(points); _pointsSet = new PointsSet(_list); if (_list.Count != _pointsSet.Count) { throw new ArgumentException(); } }
public PlayerInternal(PlayerInfo player) : this(player.Id) { Score = player.Score; Territory = new PointsSet(player.Territory.Select(p => p.ConvertToLogic(GameParams.CellSize))); Tail = new Path(player.Lines.Select(p => p.ConvertToLogic(GameParams.CellSize))); Direction = player.Direction; foreach (var bonus in player.Bonuses) { switch (bonus.Type) { case BonusType.Nitro: NitroStepsLeft = bonus.RemainingSteps; break; case BonusType.Slowdown: SlowdownStepsLeft = bonus.RemainingSteps; break; case BonusType.Saw: break; default: throw new ArgumentOutOfRangeException(); } } switch (player.Direction) { case Core.Direction.Left: int leftPath = (player.Position.X - GameParams.CellSize/2)%GameParams.CellSize; PathToNextPositionLength = leftPath == 0 ? 0 : GameParams.CellSize - leftPath; Position = new Point(player.Position.X + PathToNextPositionLength, player.Position.Y).ConvertToLogic(GameParams.CellSize); break; case Core.Direction.Up: PathToNextPositionLength = (player.Position.Y - GameParams.CellSize/2)%GameParams.CellSize; Position = new Point(player.Position.X, player.Position.Y - PathToNextPositionLength).ConvertToLogic(GameParams.CellSize); break; case Core.Direction.Right: PathToNextPositionLength = (player.Position.X - GameParams.CellSize/2)%GameParams.CellSize; Position = new Point(player.Position.X - PathToNextPositionLength, player.Position.Y).ConvertToLogic(GameParams.CellSize); break; case Core.Direction.Down: int downPath = (player.Position.Y - GameParams.CellSize/2)%GameParams.CellSize; PathToNextPositionLength = downPath == 0 ? 0 : GameParams.CellSize - downPath; Position = new Point(player.Position.X, player.Position.Y + PathToNextPositionLength).ConvertToLogic(GameParams.CellSize); break; case null: Position = player.Position.ConvertToLogic(GameParams.CellSize); break; default: throw new ArgumentOutOfRangeException(); } }
public static unsafe int GetShortestPathToOutsideLength(Point startPoint, Direction direction, PointsSet territory) { 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]; 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()) { int neighborCoord = neighbor.X + neighbor.Y * GameParams.MapSize.Width; if (!GameParams.MapSize.ContainsPoint(neighbor) || visited[neighborCoord] || currentPathLength == 0 && neighbor == startPoint.MoveLogic(direction.GetOpposite())) { continue; } if (!territory.Contains(neighbor)) { return(currentPathLength + 1); } visited[neighborCoord] = true; moves[neighborCoord] = currentPathLength + 1; queue[queueHead++] = neighborCoord; } } return(-1); }
public unsafe PointsSet Capture(PointsSet territory, IEnumerable <Point> tail) { #if DEBUG GameDebugData.Current.CaptureCount++; #endif var visited = stackalloc byte[GameParams.MapSize.Width * GameParams.MapSize.Height]; const byte emptyCell = 0; const byte territoryCell = 1; const byte tailCell = 2; const byte outsideCell = 3; int minX = GameParams.MapSize.Width - 1; int minY = GameParams.MapSize.Height - 1; int maxX = 0; int maxY = 0; foreach (var point in tail) { if (point.X < minX) { minX = point.X; } else if (point.X > maxX) { maxX = point.X; } if (point.Y < minY) { minY = point.Y; } else if (point.Y > maxY) { maxY = point.Y; } visited[point.X + point.Y * GameParams.MapSize.Width] = tailCell; } foreach (var point in territory) { if (point.X < minX) { minX = point.X; } else if (point.X > maxX) { maxX = point.X; } if (point.Y < minY) { minY = point.Y; } else if (point.Y > maxY) { maxY = point.Y; } visited[point.X + point.Y * GameParams.MapSize.Width] = territoryCell; } int totalBoxSize = (maxX - minX + 1) * (maxY - minY + 1); var queue = stackalloc int[totalBoxSize]; int queueHead = 0; int queueTail = 0; int outsideCount = 0; for (int x = minX; x <= maxX; x++) { if (visited[x + minY * GameParams.MapSize.Width] == emptyCell) { visited[x + minY * GameParams.MapSize.Width] = outsideCell; outsideCount++; queue[queueHead++] = x + minY * GameParams.MapSize.Width; } if (visited[x + maxY * GameParams.MapSize.Width] == emptyCell) { visited[x + maxY * GameParams.MapSize.Width] = outsideCell; outsideCount++; queue[queueHead++] = x + maxY * GameParams.MapSize.Width; } } for (int y = minY + 1; y <= maxY - 1; y++) { if (visited[minX + y * GameParams.MapSize.Width] == emptyCell) { visited[minX + y * GameParams.MapSize.Width] = outsideCell; outsideCount++; queue[queueHead++] = minX + y * GameParams.MapSize.Width; } if (visited[maxX + y * GameParams.MapSize.Width] == emptyCell) { visited[maxX + y * GameParams.MapSize.Width] = outsideCell; outsideCount++; queue[queueHead++] = maxX + y * GameParams.MapSize.Width; } } while (queueTail != queueHead) { int pointInt = queue[queueTail++]; var point = new Point(pointInt % GameParams.MapSize.Width, pointInt / GameParams.MapSize.Width); foreach (var neighbor in point.GetNeighbors()) { if (neighbor.X < minX || neighbor.X > maxX || neighbor.Y < minY || neighbor.Y > maxY) { continue; } if (visited[neighbor.X + neighbor.Y * GameParams.MapSize.Width] != emptyCell) { continue; } visited[neighbor.X + neighbor.Y * GameParams.MapSize.Width] = outsideCell; outsideCount++; queue[queueHead++] = neighbor.X + neighbor.Y * GameParams.MapSize.Width; } } var result = new Point[totalBoxSize - outsideCount - territory.Count]; int index = 0; for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { if (visited[x + y * GameParams.MapSize.Width] == emptyCell || visited[x + y * GameParams.MapSize.Width] == tailCell) { result[index++] = new Point(x, y); } } } return(new PointsSet(result)); }
public static PointsSet GetBoundary(this PointsSet pointsSet) { return(new PointsSet(pointsSet.Where(p => p.GetEightNeighbors().Any(n => !pointsSet.Contains(n))))); }