0

Currently using C++20, GCC 11.1.0

I'm coding for simple movement in a game loop.

Following the abstract pseudocode below, how would I be able to translate this into code? I was thinking of using either goto to just skip right into the scope that uses the values, or std::optional to check whether the values exist or not.

The reason I'm trying to do this instead of just adding the bottom if statement into the A...D if statements is because the bottom if statement could become very large, and may add redundancy. Or should I just refactor the if statement into a separate function?

if (direction is left && ...)
{
    int xVelocity {left_calculation...};
}

else if (direction is right && ...)
{
    int xVelocity {right_calculation...};
}

else if (direction is up && ...)
{
    int yVelocity {up_calculation...};
}

else if (direction is down && ...)
{
    int yVelocity {down_calculation...};
}


if (x has a value or y has a value)
{
    // Do something with those values...
}
spaL
  • 604
  • 7
  • 21
  • What does "most efficient" mean? Can you define what "most efficient" means to you, in objective, concrete terms. Otherwise this is purely opinion-based, which would not be an appropriate question for Stackoverflow. – Sam Varshavchik Aug 14 '22 at 00:04
  • Note: You can't declare a variable, `int x {A_x_calculation...};`, inside the scope of the `if` and use it outside the `if`. – user4581301 Aug 14 '22 at 00:05
  • Does this answer your question? [Does C++ have some equivalent of SQL coalesce?](https://stackoverflow.com/questions/73339549/does-c-have-some-equivalent-of-sql-coalesce) – lorro Aug 14 '22 at 00:07
  • @user4581301 I did it intentionally to show that `x` and `y` are initialized in those if statements. If I initialize it outside then they will always have a value (default 0) – spaL Aug 14 '22 at 00:07
  • 1
    You could pack the processing code up into a function and call the function as needed inside the various `if` statements that determine the values of `x` and `y`. – user4581301 Aug 14 '22 at 00:07
  • Before you use `goto`, consider [this](https://www.explainxkcd.com/wiki/index.php/292:_goto) – anastaciu Aug 14 '22 at 00:08
  • In order to be able to advise, we'd need to know if `A_x_calculation` and `B_x_calculation`, etc. are essentially the same logic applied to `A`, `B`, etc. respectively, or if those are distinct logics. – lorro Aug 14 '22 at 00:08
  • @user4581301 yea that seems like the best option so far – spaL Aug 14 '22 at 00:10
  • @anastaciu I know, which is why I was hesitant on using `goto` – spaL Aug 14 '22 at 00:10
  • The next thing is to explain what "x has a value and/or y has a value" mean. It seems that the pseudocode either sets both x and y, on some code path, or doesn't. How does x wind up with a value, but not y, or vice versa? – Sam Varshavchik Aug 14 '22 at 00:17
  • Please clarify: What behaviour do you want if the A case and the C case both enter? – user4581301 Aug 14 '22 at 00:17
  • I've edited the post further. Basically the four if statements cover the four possible directions my game character can move, and based on the direction, x and y represent the velocity of the game character. – spaL Aug 14 '22 at 00:21
  • Still unclear. Can you go down and right at the same time? – user4581301 Aug 14 '22 at 00:22
  • No, you can only move in one direction – spaL Aug 14 '22 at 00:24
  • Then this boils down to a simple `switch` statement, where each branch sets `x` and `y`. and the rest is history. There are not that many different ways to boil an egg, that can be compared against each other to determine which one is more "efficient", in some unclear manner. – Sam Varshavchik Aug 14 '22 at 00:26
  • OK. Try this: Make a function that takes `x` and `y` by reference and returns `bool`. Put the `if` statements in this function. Each if ends with a `return true;`. If the end of the function is reached, `return false;` Back in the main function you have something like `if (the_func(x,y)) {do stuff }` – user4581301 Aug 14 '22 at 00:28
  • @user4581301 That could work, thanks – spaL Aug 14 '22 at 00:31
  • How do you expect to interpret a single boolean to select one of four alternative code paths, that you've described? – Sam Varshavchik Aug 14 '22 at 00:36
  • Like [VikingOfValhalla](https://stackoverflow.com/a/73348361/3135317) suggested, I'd *DEFINITELY* consider using a [switch()/case](https://www.guru99.com/c-switch-case-statement.html) block if at all possible. It's efficient, it supports handling the same "response" for multiple different cases (e.g. up or down, or right or left). – FoggyDay Aug 14 '22 at 00:53

2 Answers2

0

You can represent optionality via std::option:

std::optional xVelocityOpt =
    direction == left  ? std::make_optional(left_calculation)
  : direction == right ? std::make_optional(right_calculation)
                       : {};

std::optional yVelocityOpt =
    direction == up    ? std::make_optional(up_calculation)
  : direction == down  ? std::make_optional(down_calculation)
                       : {};

if (xVelocityOpt || yVelocityOpt)
{
    // you can use the actual values as
    // *xVelocityOpt and *yVelocityOpt
    // ...
}

... but I'd also consider using simple int velocities and represent empty as 0 (if what you mean by the variables are delta v in physics).

lorro
  • 10,687
  • 23
  • 36
0

If instead of x,y you use delta_x,delta_y for relative value change then your problem solves itself. Then your if is just:

int delta_x = 0;
int delta_y = 0;
...
if( delta_x | delta_y )
  on_xy_changed(old_x + delta_x, old_y + delta_y);
Bartosz Charuza
  • 491
  • 1
  • 7