Exemple #1
0
        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;
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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;
        }
Exemple #4
0
        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));
                }
            }
        }