如何减少相似代码块的检查量?

How to reduce the amount of checks of similar code blocks?

我似乎无法改进以下代码:

    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;
    }

它们很相似,但操作相反。

是否有任何最佳实践或技术可以改善此类情况?

这很简单:

// 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);
}

你可以看到,L 状态和 M 状态是相互的,你可以这样做:

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);

这段代码可能没有上一段那么清晰,但是很短

你可以pre-compute一些因素来反转条件的符号。

这是一个例子:

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;
}

更紧凑的 (branch-less) 版本不太清楚(但可能更有效)如下:

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;

请注意,如果 state 是一个布尔数组,您甚至不需要使用三元数组,因为布尔值可以直接转换为 0-1 整数值。