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); }
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); }
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); }
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); }