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.