Пример #1
0
        protected override void OnMakeMove(GameState gameState, LogicMoveResult moves)
        {
            foreach (var unitState in gameState.UnitStates)
            {
                if (unitState.IsDead)
                {
                    lock (_targetPointsLock)
                    {
                        _unitIdToTargetPointMap.Remove(unitState.UniqueId);
                    }

                    continue;
                }

                Point2D targetPoint;
                lock (_targetPointsLock)
                {
                    targetPoint = _unitIdToTargetPointMap.GetValueOrDefault(unitState.UniqueId, unitState.Position);
                }

                var needNewTargetPoint = unitState.PreviousMoveState.IsRejected() ||
                                         unitState.Position.GetDistance(targetPoint)
                                         .IsZero(GameConstants.ChickenUnit.DefaultRectilinearSpeed);
                if (needNewTargetPoint)
                {
                    targetPoint = ChooseTargetPoint(gameState, unitState);
                }

                var move     = GameHelper.GetBestMoveDirection(unitState.Position, unitState.BeakAngle, targetPoint);
                var turn     = GameHelper.GetBestBeakTurnNormalized(unitState.Position, unitState.BeakAngle, targetPoint);
                var fireMode = unitState.CanShoot && RandomGenerator.Next(10) == 0 ? FireMode.Regular : FireMode.None;

                var moveInfo = new MoveInfo(move, turn, fireMode);
                moves.Set(unitState, moveInfo);
            }
        }
Пример #2
0
        protected override void OnMakeMove(GameState gameState, LogicMoveResult moves)
        {
            var allShots = gameState
                           .UnitStates
                           .SelectMany(item => item.View.Shots)
                           .Distinct(KeyedEqualityComparer.For <ShotViewData> .Create(state => state.UniqueId))
                           .ToArray();

            var enemyUnits = gameState
                             .UnitStates
                             .SelectMany(item => item.View.Chickens.Where(visibleUnit => visibleUnit.Team != this.Team))
                             .Distinct(KeyedEqualityComparer.For <ChickenViewData> .Create(data => data.UniqueId))
                             .ToArray();

            foreach (var unitState in gameState.UnitStates)
            {
                if (unitState.IsDead)
                {
                    continue;
                }

                MoveDirection safestMoveDirection = null;
                if (_features.IsAnySet(Features.TurningAway))
                {
                    safestMoveDirection = FindSafestMove(allShots, unitState);
                }

                if (unitState.PreviousMoveState.IsRejected())
                {
                    var blockedDirections = _blockedDirectionMap.GetValueOrDefault(unitState.UniqueId);
                    if (blockedDirections == null)
                    {
                        blockedDirections = new HashSet <MoveDirection>();
                        _blockedDirectionMap[unitState.UniqueId] = blockedDirections;
                    }

                    blockedDirections.Add(unitState.PreviousMove.MoveDirection);

                    var moveDirection = GameHelper
                                        .BasicActiveMoveDirections
                                        .FirstOrDefault(item => !blockedDirections.Contains(item));
                    var unblockingMove = moveDirection == null || moveDirection.IsNone
                        ? new MoveInfo(MoveDirection.None, BeakTurn.FullyClockwise, FireMode.None)
                        : new MoveInfo(moveDirection, BeakTurn.None, FireMode.None);
                    moves.Set(unitState, unblockingMove);
                    continue;
                }

                _blockedDirectionMap.Remove(unitState.UniqueId);

                var possibleActions = new List <PossibleActionInfo>(unitState.View.Chickens.Count);

                //// ReSharper disable once LoopCanBeConvertedToQuery
                foreach (var enemyUnit in enemyUnits)
                {
                    var shotTargetPosition = GetShotTargetPosition(unitState, enemyUnit);

                    var moveDirection = safestMoveDirection
                                        ?? GameHelper.GetBestMoveDirection(
                        unitState.Position,
                        unitState.BeakAngle,
                        shotTargetPosition);

                    var turn = GameHelper.GetBestBeakTurn(
                        unitState.Position,
                        unitState.BeakAngle,
                        shotTargetPosition);

                    possibleActions.Add(
                        new PossibleActionInfo
                    {
                        EnemyUnit       = enemyUnit,
                        MoveDirection   = moveDirection,
                        BeakTurn        = turn,
                        DistanceSquared = unitState.Position.GetDistanceSquared(enemyUnit.Position)
                    });
                }

                var bestAction = possibleActions
                                 .OrderBy(item => item.DistanceSquared)
                                 .ThenBy(item => item.BeakTurn)
                                 .FirstOrDefault();
                if (bestAction == null)
                {
                    var minBorderDistance = gameState.Data.BoardBorder.Edges.Min(
                        item => GameHelper.GetDistanceToLine(unitState.Position, item.Start, item.End));
                    if (minBorderDistance <= _tooCloseBorderDistance)
                    {
                        var boardCenter = new Point2D(gameState.Data.RealSize) / 2f;
                        var direction   = GameHelper.GetBestMoveDirection(
                            unitState.Position,
                            unitState.BeakAngle,
                            boardCenter);

                        moves.Set(unitState, new MoveInfo(direction, BeakTurn.None, FireMode.None));
                        continue;
                    }

                    if (safestMoveDirection != null)
                    {
                        moves.Set(unitState, new MoveInfo(safestMoveDirection, BeakTurn.None, FireMode.None));
                    }
                    else
                    {
                        var seekingMove = new MoveInfo(
                            unitState.PreviousMoveState.IsRejected() || minBorderDistance <= _rotateOnlyBorderDistance
                                ? MoveDirection.None
                                : MoveDirection.MoveForward,
                            BeakTurn.FullyClockwise,
                            FireMode.None);
                        moves.Set(unitState, seekingMove);
                    }

                    continue;
                }

                var beakTurn = bestAction.BeakTurn.NormalizeBeakTurn();
                var doFire   = bestAction.BeakTurn.IsInRange(BeakTurn.ValueRange) ||
                               bestAction.DistanceSquared <= _forceFireDistanceSquared;

                var move = new MoveInfo(
                    bestAction.MoveDirection,
                    beakTurn,
                    doFire ? FireMode.Regular : FireMode.None);
                moves.Set(unitState, move);
            }
        }