Home > front end >  How to reduce the amount of checks of similar code blocks?
How to reduce the amount of checks of similar code blocks?

Time:03-25

I do not seem able to improve the following code:

    if(state[SDL_SCANCODE_M]){
        if(_ball.velocity.x < 0)
            _ball.velocity.x -= 20;
        else
            _ball.velocity.x  = 20;

        if(_ball.velocity.y < 0)
            _ball.velocity.y -= 20;
        else
            _ball.velocity.y  = 20;
    }

    if(state[SDL_SCANCODE_L]){
        if(_ball.velocity.x < 0)
            _ball.velocity.x  = 20;
        else
            _ball.velocity.x -= 20;

        if(_ball.velocity.y < 0)
            _ball.velocity.y  = 20;
        else
            _ball.velocity.y -= 20;
    }

They are pretty similar, but the operations are the opposite.

Is there any best practice or technique that allows to improve these kind of situations?

CodePudding user response:

This is quite easy:

// lambda or function it does not matter
auto upgradeVelocity = [](auto& velocity, auto deltaIfGreaterZero, auto deltaIfLessZero){
    velocity  = velocity < 0 ? deltaIfLessZero : deltaIfGreaterZero;
};

if(state[SDL_SCANCODE_M]){
    upgradeVelocity(_ball.velocity.x, -20, 20);
    upgradeVelocity(_ball.velocity.y, -20, 20);
}

if(state[SDL_SCANCODE_L]){
    upgradeVelocity(_ball.velocity.x, 20, -20);
    upgradeVelocity(_ball.velocity.y, 20, -20);
}

And you can see, the L state and M state is reciprocal, than you can do something like that:

auto delta = (state[SDL_SCANCODE_L] ? 20 : 0) - (state[SDL_SCANCODE_M] ? 20 : 0); 
upgradeVelocity(_ball.velocity.x, delta, -delta);
upgradeVelocity(_ball.velocity.y, delta, -delta);

This code may not be as clear as the previous one, but it short

CodePudding user response:

You can pre-compute some factor so to inverse the sign regarding the conditions.

Here is an example:

int xCoef = (_ball.velocity.x < 0) ? -1 : 1;
int yCoef = (_ball.velocity.y < 0) ? -1 : 1;

if(state[SDL_SCANCODE_M]){
    _ball.velocity.x  = xCoef * 20;
    _ball.velocity.y  = yCoef * 20;
}

if(state[SDL_SCANCODE_L]){
    _ball.velocity.x -= xCoef * 20;
    _ball.velocity.y -= yCoef * 20;
}

A more compact (branch-less) version that is a bit less clear (but probably more efficient) is the following:

int xCoef = (_ball.velocity.x < 0) ? -1 : 1;
int yCoef = (_ball.velocity.y < 0) ? -1 : 1;
int mPressed = state[SDL_SCANCODE_M] ? 1 : 0;
int lPressed = state[SDL_SCANCODE_L] ? 1 : 0;
_ball.velocity.x  = (mPressed - lPressed) * xCoef * 20;
_ball.velocity.y  = (mPressed - lPressed) * yCoef * 20;

Note that if state is a boolean array, you do not even need to use a ternary since booleans can be directly converted to 0-1 integer values.

  • Related