private bool UpdateUnitStates(bool force)
        {
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var logicIndex = 0; logicIndex < _logicExecutors.Count; logicIndex++)
            {
                var logic = _logicExecutors[logicIndex];

                lock (logic.UnitsStatesLock)
                {
                    logic.UnitsStates.Clear();

                    // ReSharper disable once ForCanBeConvertedToForeach
                    for (var unitIndex = 0; unitIndex < logic.Units.Count; unitIndex++)
                    {
                        if (!force && IsStopping())
                        {
                            return(false);
                        }

                        var unit = logic.Units[unitIndex];

                        var previousMove = _previousMoves.GetValueOrDefault(unit) ?? MoveInfo.Empty;

                        // ReSharper disable once RedundantArgumentDefaultValue
                        var previousMoveState = _moveInfoStates.GetValueOrDefault(unit, MoveInfoStates.Handled);
                        var unitState         = new ChickenUnitState(unit, previousMove, previousMoveState);
                        logic.UnitsStates.Add(unit, unitState);
                    }
                }
            }

            return(true);
        }
Exemple #2
0
        private Point2D ChooseTargetPoint(GameState state, ChickenUnitState unitState)
        {
            var point = new Point(
                RandomGenerator.Next(state.Data.NominalSize.Width),
                RandomGenerator.Next(state.Data.NominalSize.Height));
            var result = GameHelper.NominalToReal(point);

            lock (_targetPointsLock)
            {
                _unitIdToTargetPointMap[unitState.UniqueId] = result;
            }

            return(result);
        }
Exemple #3
0
        private Point2D GetShotTargetPosition(
            ChickenUnitState unitState,
            ChickenViewData enemyUnit)
        {
            if (!_features.IsAnySet(Features.PredictiveShot))
            {
                return(enemyUnit.Position);
            }

            Point2D?predictiveShotTargetPosition = null;

            var enemyUnitBeakTip   = GameHelper.GetBeakTipPosition(enemyUnit.Position, enemyUnit.BeakAngle);
            var enemyUnitVector    = enemyUnitBeakTip - enemyUnit.Position;
            var enemyToMeVector    = unitState.Position - enemyUnit.Position;
            var cosAlpha           = enemyUnitVector.GetAngleCosine(enemyToMeVector);
            var distanceToEnemySqr = enemyToMeVector.GetLengthSquared();
            var distanceToEnemy    = distanceToEnemySqr.Sqrt();

            if (!(cosAlpha.Abs() - 1f).IsZero())
            {
                var equation = new QuadraticEquation(
                    GameConstants.ShotToChickenRectilinearSpeedRatio.Sqr() - 1f,
                    2f * distanceToEnemy * cosAlpha,
                    -distanceToEnemySqr);

                float d1, d2;
                if (equation.GetRoots(out d1, out d2) > 0)
                {
                    var d = new[] { d1, d2 }
                    .Where(item => item > 0f)
                    .OrderBy(item => item)
                    .FirstOrDefault();
                    if (d.IsPositive())
                    {
                        predictiveShotTargetPosition = GameHelper.GetNewPosition(
                            enemyUnit.Position,
                            enemyUnit.BeakAngle,
                            d);
                    }
                }
            }

            var result = predictiveShotTargetPosition
                         ?? GameHelper.GetNewPosition(
                enemyUnit.Position,
                enemyUnit.BeakAngle,
                GameConstants.ChickenUnit.DefaultRectilinearSpeed);

            return(result);
        }
Exemple #4
0
        private MoveDirection FindSafestMove(IEnumerable <ShotViewData> allShots, ChickenUnitState unitState)
        {
            var safetyCircle   = new CirclePrimitive(unitState.Position, _dangerousRadius);
            var dangerousShots = new List <ShotViewData>(unitState.View.Shots.Count);

            //// ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var shot in allShots)
            {
                if (unitState.Position.GetDistance(shot.Position) > _tooCloseShot)
                {
                    continue;
                }

                var shotDirection    = shot.Angle.ToUnitVector();
                var shotToUnitVector = unitState.Position - shot.Position;
                var angle            = shotDirection.GetAngle(shotToUnitVector);
                if (angle.DegreeValue.Abs() >= MathHelper.QuarterRevolutionDegrees)
                {
                    continue;
                }

                var shotLine = new LinePrimitive(
                    shot.Position,
                    shot.Position + shot.Angle.ToUnitVector() * _boardDiagonalSize);
                if (CollisionDetector.CheckCollision(shotLine, safetyCircle))
                {
                    dangerousShots.Add(shot);
                }
            }

            if (dangerousShots.Count <= 0)
            {
                return(null);
            }

            var safeMoves = GameHelper.BasicMoveDirections.ToDictionary(item => item, item => 0);

            foreach (var dangerousShot in dangerousShots)
            {
                var shotVector = dangerousShot.Angle.ToUnitVector();

                var maxDistanceMove = MoveDirection.None;
                var maxDistanceSqr  = float.MinValue;
                foreach (var moveDirection in GameHelper.BasicMoveDirections)
                {
                    var potentialPosition = GameHelper.GetNewPosition(
                        unitState.Position,
                        unitState.BeakAngle,
                        moveDirection,
                        GameConstants.ChickenUnit.DefaultRectilinearSpeed);
                    var shotToUnitVector = potentialPosition - dangerousShot.Position;
                    var shotToUnitVectorLengthSquared = shotToUnitVector.GetLengthSquared();
                    var angleCosine = shotVector.GetAngleCosine(shotToUnitVector);
                    var distanceSqr = shotToUnitVectorLengthSquared
                                      - shotToUnitVectorLengthSquared * angleCosine.Sqr();
                    if (distanceSqr > maxDistanceSqr)
                    {
                        maxDistanceSqr  = distanceSqr;
                        maxDistanceMove = moveDirection;
                    }
                }

                safeMoves[maxDistanceMove]++;
            }

            var actuallySafeMovePair = safeMoves
                                       .Where(pair => pair.Value > 0)
                                       .OrderByDescending(pair => pair.Value)
                                       .FirstOrDefault();

            return(actuallySafeMovePair.Value > 0 ? actuallySafeMovePair.Key : null);
        }