示例#1
0
        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();
            }
        }
示例#3
0
        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)))));
 }