public override void AgentStep(float[] action)
    {
        myStepCountInLastSession++;

        reward = -0.005f;

        rocket.UpdateEngineForceDirections();

        if (paramsText1 != null && Time.frameCount % 15 == 0)
        {
            paramsText1.text = string.Format("Success:{0},Fail:{1},stp:{2},",
                                             solved, failed, myStepCountInLastSession);

            paramsText3.text = string.Format("Fail: Position:{0}, Accident:{1}, Speed:{2}, Rotation:{3}",
                                             failCounterPosition, failCounterAccident, failCounterSpeed, failCounterRotation);
        }

        // ----------------------------------------------------------------------------------------
        //                                   Movement
        // ----------------------------------------------------------------------------------------
        switch ((int)action[0])
        {
        case 0:
            // do nothing - engine is off - rocket falls down
            break;

        case 1:
            // power on engine - rocket moves up
            rocket.EngineMainEmitBurst();
            audioControl.PlaySfxMainEngine();
            break;

        case 2:
            // left engine on
            rocket.EngineDownLeftEmitBurst();
            audioControl.PlaySfxSideEngine();
            break;

        case 3:
            // right engine on
            rocket.EngineDownRightEmitBurst();
            audioControl.PlaySfxSideEngine();
            break;

        case 4:
            // right engine on
            rocket.EngineStopEmitBurst();
            audioControl.PlaySfxSideEngine();
            break;

        case 5:
            rocket.EngineUpLeftEmitBurst();
            audioControl.PlaySfxSideEngine();
            break;

        case 6:
            rocket.EngineUpRightEmitBurst();
            audioControl.PlaySfxSideEngine();
            break;

        default:
            break;
        }

        // ----------------------------------------------------------------------------------------
        //                             Reward \ Punish
        // ----------------------------------------------------------------------------------------

        //// Small punishments\rewards, disabled in this version

        //float targetingAngle = rocket.GetTargetingAngle(planet2.gameObject);
        ////Debug.Log("Targeting angle: " + targetingAngle);

        //const float ALLOWED_ANGLE_DEVIATION = 20; // degrees

        //const float GRAVITY_RANGE_PLANET_1 = 6;

        //// 1) Add small punishment if rocket is in gravity range of planet 1
        //if (Vector3.Distance(rocket.transform.position, planet1.transform.position) < GRAVITY_RANGE_PLANET_1)
        //{
        //    reward += -0.005f;
        //}

        //// 2) Add small punishment if rocket's landing angle (rocket's orientation) for target
        //// planet is more then DELTA
        //// we need angle close to 180 degrees
        //else if (Math.Abs(targetingAngle - 180) > ALLOWED_ANGLE_DEVIATION)
        //{
        //    // punish if angle deviation is to big
        //    reward += -0.005f;
        //}

        //// 3) punish if speed is to high
        ////if (!IsRocketSpeedOk())
        ////{
        ////    reward += -0.05f;
        ////    //failed++;
        ////    //reward = -1f;
        ////    //done = true;

        ////    //ResetObjectsPosInScene();
        ////    //UpdateSessionReward();
        ////    //PrintEndSessionReward(false);
        ////    //return;
        ////}

        // ---------------------------------- FAILURE ---------------------------------------------
        if (rocket.GetLocalPosY() < failureBorderBottom ||
            rocket.GetLocalPosY() > failureBorderTop ||
            rocket.GetLocalPosX() > failureBorderRight ||
            rocket.GetLocalPosX() < failureBorderLeft)
        {
            failed++;
            reward = -1f;
            done   = true;

            failCounterPosition++;

            Debug.Log("Fail: position: " + failCounterPosition);
            ShowFailText("Fail: position");

            previousDistanceToTarget = GetDistanceToTarget();

            /**
             * This is required to reset rocket rotation when switching to a new session - when
             * rocket moves into left or right vertical wall (presumably at a high speed) and
             * forward button (main engine) is pressed - the session is over with a failure (that
             * is expected), but the new session is started with rocket rotating around z-axis
             * rapidly - it looks like in this case Agent.Reset() logic is not enough... Why?
             *
             * Workaround: Adding rocket.Reset() here fixes this issue.
             */
            ResetObjectsPosInScene();
            UpdateSessionReward();
            PrintEndSessionReward(false);
            return;
        }

        if (rocket.AccidentOccured())
        {
            failed++;
            reward = -1f;
            done   = true;

            failCounterAccident++;

            audioControl.PlaySfxAccident();

            Debug.Log("Fail: accident: " + failCounterAccident);
            ShowFailText("Fail: accident");

            ResetObjectsPosInScene();
            UpdateSessionReward();
            PrintEndSessionReward(false);
            return;
        }


        if (!IsPlayerBrain() && !IsRocketSpeedOk())
        {
            failed++;
            reward = -1f;
            done   = true;

            failCounterSpeed++;

            Debug.Log("Fail: speed: " + failCounterSpeed);
            ShowFailText("Fail: speed");

            ResetObjectsPosInScene();
            UpdateSessionReward();
            PrintEndSessionReward(false);
            return;
        }

        if (!IsPlayerBrain() && Math.Abs(rocket.GetAngularVelocityZ()) > 0.8)
        {
            failed++;
            reward = -1f;
            done   = true;

            failCounterRotation++;

            Debug.Log("Fail: angular velocity: " + failCounterRotation);
            ShowFailText("Fail: rotation speed");

            ResetObjectsPosInScene();
            UpdateSessionReward();
            PrintEndSessionReward(false);
            return;
        }

        // ------------------------------------- SUCCESS ------------------------------------------

        if (rocket.IsOnPlanet() && IsRocketSpeedOk())
        {
            reward = 1;
            solved++;
            done = true;

            ShowSuccessText();

            previousDistanceToTarget = GetDistanceToTarget();
            ResetObjectsPosInScene();
            UpdateSessionReward();
            PrintEndSessionReward(true);
            return;
        }

        previousDistanceToTarget = GetDistanceToTarget();
        UpdateSessionReward();
    }