예제 #1
0
        public ChickenElement GetElement()
        {
            // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
            if (_cachedElement == null)
            {
                _cachedElement = new ChickenElement(this.NextPosition, this.NextBeakAngle);
            }

            return(_cachedElement);
        }
예제 #2
0
 private void ResetCachedElement()
 {
     _cachedElement = null;
 }
예제 #3
0
        private bool ProcessChickenUnitMoves(IList <ChickenUnit> aliveChickens)
        {
            //// TODO: [vmcl] Use bisection to get conflicting units closer to each other
            //// TODO: [vmcl] Optimize number of collision checks!
            //// TODO: [vmcl] Divide move: eg. unit couldn't move but could turn beak or vice versa

            _moveInfoStates.Clear();
            for (var unitIndex = 0; unitIndex < aliveChickens.Count; unitIndex++)
            {
                if (IsStopping())
                {
                    return(false);
                }

                var unit = aliveChickens[unitIndex];
                _moveInfoStates[unit] = MoveInfoStates.Handled;

                var moveInfo = _moveInfos.GetValueOrDefault(unit);
                if (moveInfo == null)
                {
                    continue;
                }

                DebugHelper.WriteLine(
                    "{0} is processing move {{{1}}} of chicken {{{2}}}.",
                    GetType().Name,
                    moveInfo,
                    unit);

                var movementAndNewPosition = GameHelper.GetMovementAndNewPosition(
                    unit.Position,
                    unit.BeakAngle,
                    moveInfo.MoveDirection,
                    GameConstants.ChickenUnit.DefaultRectilinearSpeed);

                var beakMovementAndNewAngle = GameHelper.GetBeakMovementAndNewAngle(unit.BeakAngle, moveInfo.BeakTurn);

                var newPositionElement = new ChickenElement(
                    movementAndNewPosition.Position,
                    beakMovementAndNewAngle.Position);
                if (HasOutOfBoardCollision(newPositionElement))
                {
                    _moveInfoStates[unit] = MoveInfoStates.RejectedBoardCollision;
                    DebugHelper.WriteLine(
                        "Blocked collision of chicken {{{0}}} with game board border.",
                        unit);
                    continue;
                }

                ChickenUnit conflictingChicken = null;

                // ReSharper disable once LoopCanBeConvertedToQuery
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var conflictingIndex = 0; conflictingIndex < aliveChickens.Count; conflictingIndex++)
                {
                    var aliveChicken = aliveChickens[conflictingIndex];
                    if (aliveChicken == unit)
                    {
                        continue;
                    }

                    if (CollisionDetector.CheckCollision(newPositionElement, aliveChicken.GetElement()))
                    {
                        conflictingChicken = aliveChicken;
                        break;
                    }
                }

                if (conflictingChicken != null)
                {
                    _moveInfoStates[unit] = MoveInfoStates.RejectedOtherUnitCollision;
                    DebugHelper.WriteLine(
                        "Blocked collision of chicken {{{0}}} with {{{1}}}.",
                        unit,
                        conflictingChicken);
                    continue;
                }

                unit.SetMovement(movementAndNewPosition.Movement, beakMovementAndNewAngle.Movement);

                DebugHelper.WriteLine("Chicken {{{0}}} has moved.", unit);
            }

            return(true);
        }