/// <summary>
 /// Подвинуть объект
 /// </summary>
 public void Move(IAquariumPositionContext aquarium, IAquariumMovableObjectEditable obj)
 {
     if (aquarium.IsPositionOutsideBorders(obj.X, obj.Y))
     {
         MoveBackToAquarium(aquarium, obj);
     }
     else
     {
         MoveAsUsual(aquarium, obj);
     }
 }
        /// <summary>
        /// Конструктор
        /// </summary>
        public AquariumHealthDecorator(IAquariumMovableObjectEditable aquariumObject, IAquariumObjectRenderer healthRenderer, IAquariumPopulationController aquariumPopulationController,
			int health = INITIAL_HEALTH, int minHealthDecrease = MIN_HEALTH_DECREASE, int maxHealthDecrease = MAX_HEALTH_DECREASE)
            : base(aquariumObject)
        {
            _healthRenderer = healthRenderer;
            _aquariumPopulationController = aquariumPopulationController;

            Health = health;

            _minHealthDecrease = minHealthDecrease;
            _maxHealthDecrease = maxHealthDecrease;
        }
        /// <summary>
        /// Обычный алгоритм движения
        /// </summary>
        private void MoveAsUsual(IAquariumPositionContext aquarium, IAquariumMovableObjectEditable obj)
        {
            int nextX = GetNextPosX(obj);

            // Можно ли передвинуться в текущем направлении движения
            bool canMove = aquarium.IsValidPosition(nextX, obj.Y);
            if (!canMove)
            {
                // Пробуем поменять направление движения
                Direction oppositeDirection = obj.MovementDirection.GetOpposite();
                obj.MovementDirection = oppositeDirection;

                nextX = GetNextPosX(obj);

                canMove = aquarium.IsValidPosition(nextX, obj.Y);
            }

            // Повторно проверяем, что можем передвинуться
            if (canMove)
            {
                obj.X = nextX;
            }
        }
        /// <summary>
        /// Подвинуть объект
        /// </summary>
        public void MoveBySin(IAquariumPositionContext aquarium, IAquariumMovableObjectEditable obj)
        {
            if (aquarium.IsPositionOutsideBorders(obj.X, obj.Y))
            {
                aquarium.FixPosition(obj);
            }
            else
            {
                int shiftX = obj.MovementDirection == Direction.Right ? 1 : -1;
                int nextX = obj.X + shiftX * (obj.Speed / 10 + obj.SizeX / 2);

                int shiftY = Convert.ToInt32(Math.Sin(DateTime.Now.Second) * 10);
                int nextY = obj.Y + shiftY;

                // Можно ли передвинуться в текущем направлении движения
                bool canMove = aquarium.IsValidPosition(nextX, nextY);
                if (!canMove)
                {
                    // Пробуем поменять направление движения
                    Direction oppositeDirection = obj.MovementDirection.GetOpposite();
                    obj.MovementDirection = oppositeDirection;

                    shiftX = obj.MovementDirection == Direction.Right ? 1 : -1;
                    nextX = nextX = obj.X + shiftX * (obj.Speed / 10 + obj.SizeX / 2);

                    canMove = aquarium.IsValidPosition(nextX, nextY);
                }

                // Повторно проверяем, что можем передвинуться
                if (canMove)
                {
                    obj.X = nextX;
                    obj.Y = nextY;
                }
            }
        }
 /// <summary>
 /// Подвинуть объект
 /// </summary>
 public void Move(IAquariumPositionContext aquarium, IAquariumMovableObjectEditable obj)
 {
     _strategy.MoveBySin(aquarium, obj);
 }
 public AquariumMovableObjectDecoratorBase(IAquariumMovableObjectEditable aquariumObject)
 {
     _aquariumObject = aquariumObject;
 }
 /// <summary>
 /// Скорректировать позицию объекта
 /// </summary>
 public void FixPosition(IAquariumMovableObjectEditable obj)
 {
     obj.X = Coerce(obj.X, MinX + obj.SizeX / 2, SizeX - obj.SizeX / 2);
     obj.Y = Coerce(obj.Y, MinY + obj.SizeY / 2, SizeY - obj.SizeY / 2);
 }
 /// <summary>
 /// Объект ушел за пределы акварима
 /// </summary>
 private void MoveBackToAquarium(IAquariumPositionContext aquarium, IAquariumMovableObjectEditable obj)
 {
     aquarium.FixPosition(obj);
 }
 /// <summary>
 /// Получить следующую координату при движении в заданном направлении
 /// </summary>
 private int GetNextPosX(IAquariumMovableObjectEditable obj)
 {
     int shift = obj.MovementDirection == Direction.Right ? 1 : -1;
     return obj.X + shift * (obj.Speed + obj.SizeX / 2);
 }