-5

Is there a way to shorten an if statement like this:

if(x == 1 && y == 1 && z == 1) -> if((x && y && z) == 1) or if((x,y,z) == 1)

Edit: Sorry for the inconvenience. Did it quick on my phone. Here is a full example:

This is a part of my connect fours game.

bool checkwin(string player) {
    for (int i = 0; i<10; i++) {
        for (int j = 0; j<10; j++) {
            if (grid[i][j] == player && grid[i + 1][j] == player && grid[i + 2][j] == player && grid[i + 3][j] == player) {
                return 1;
            }
            if (grid[i][j] == player && grid[i][j + 1] == player && grid[i][j + 2] == player && grid[i][j + 3] == player) {
                return 1;
            }

            if (grid[i][j] == player && grid[i + 1][j + 1] == player && grid[i + 2][j + 2] == player && grid[i + 3][j + 3] == player) {
                return 1;
            }

            if (grid[i][j] == player && grid[i - 1][j + 1] == player && grid[i - 2][j + 2] == player && grid[i - 3][j + 3] == player) {
                return 1;
            }
        }
    }
}
Akira
  • 4,385
  • 3
  • 24
  • 46
  • 7
    Focus on making your code readable. Let the compiler optimize the code. – Thomas Matthews Jul 06 '17 at 21:12
  • What @ThomasMatthews says, keep your code easy to read. It's already questionable when you're using variable names like 'x', 'y', and 'z'. – Just Rudy Jul 06 '17 at 21:17
  • Next time don't even try to make up your own semantics. You wrote (assuming those are integers) `x != 0 && y != 0 && z != 0` and `z == 1`, which is a bit different... – LogicStuff Jul 06 '17 at 21:17
  • 1
    @RudyM x, y and z could be a very reasonable name if you are referring to a 3D coordinate, for example. – Amadeus Jul 06 '17 at 21:19
  • 1
    Are you trying to save typing? Are you trying to fit more code on a screen? Are you trying to make the code easier to read and understand? Why do you want something shorter? How often do you need to do this? Maybe the real issue is whatever is causing you to need to do this so frequently that you want it to be shorter and perhaps a change elsewhere could fix that. – David Schwartz Jul 06 '17 at 21:23
  • 1
    Not sure what you mean by "shorten", but if x, y, and z were `unsigned` integer (you did not state their type), how about `if (x * y * z == 1)`? – franji1 Jul 06 '17 at 21:24
  • 1
    @franji1 Assuming you aren't worried about overflow. – David Schwartz Jul 06 '17 at 21:24
  • @DAle, `unsigned` can't equal -1 – franji1 Jul 06 '17 at 21:30
  • @Amadeus, valid point, but not enough context to know for sure. – Just Rudy Jul 07 '17 at 12:26
  • Possible duplicate of [Win conditions for a connect-4 like game](https://stackoverflow.com/questions/4636575/win-conditions-for-a-connect-4-like-game) – moooeeeep Jul 10 '17 at 06:42

3 Answers3

2

Actually if you use C++11 or higher you can do some shortening:

#include <iostream>
#include <string>
#include <tuple>

int main() {
    int x = 1;
    std::string y = "Hello";
    double z = 3.14;

    if(std::make_tuple(x, y, z) == std::make_tuple(1, "Hello", 3.14))
        std::cout << "Everything is okay." << std::endl;
    else
        std::cout << "Something went wrong." << std::endl;

    return 0;
}

Or for your case (if the type of your variables is int):

if(std::vector<int> { x, y, z } == std::vector<int> { 1, 1, 1 })
    std::cout << "Everything is okay." << std::endl;
else
    std::cout << "Something went wrong." << std::endl;

But remember, these techniques come handy when you have to test many inputs at once, or you have to overload the comparison operators for your type. In your example (as the comments point out too) this is unnecessary, the x == 1 && y == 1 && z == 1 is trivial enough.


After you edited your question it became clear that you intend to use objects (std::string) in comparison. In that case copying them into an std::tuple or into an array each time a comparison is made will occur a serious performance hit.

To don't make a significant overhead compared to expressions inside your if statements, you can use variadic templates like follows:

template<typename T, typename... Args>
bool equalToAll(T&& test, Args&&... args) {
    bool result = true;
    bool dummy[] { false, (result &= (test == args))... };
    return (static_cast<void>(dummy), result);
}

// Usage:
// equalToAll(player, grid[i][j], grid[i + 1][j], grid[i + 2][j], grid[i + 3][j])

This example performs a parameter pack expansion with list initializer which about you can read more here and here.

Akira
  • 4,385
  • 3
  • 24
  • 46
1

If you want to check that all variables are equal to each other, you can write this kind of helper

template <typename T>
bool all_equal(const std::initializer_list<T>& l) {
    return std::equal(l.begin() + 1, l.end(), l.begin());
}

Usage:

if (all_equal({a, b, c})) 

online version: http://ideone.com/8OC1yq

DAle
  • 8,990
  • 2
  • 26
  • 45
-3

If you had the int data stored in an array, you could do a include check and made the if statement a single conditional.

  • 1
    Whaaaaaaa huh?? – Captain Obvlious Jul 06 '17 at 21:32
  • For example, in Ruby you could do if [1, 2, 3].include?(input) do ... end. Just using Ruby to illustrate the point. I can't imagine this is preferred over consecutive && though and would require it to already be in an array. – broken_historian Jul 06 '17 at 21:51
  • @broken_historian So, why did you provide only a vague description of code, instead of an actual example, in addition to your description? It's difficult to understand your answer otherwise. – Algirdas Preidžius Jul 06 '17 at 22:13
  • Well we're not talking about Ruby we're talking about C++. Trying to do things the way other languages do it is how you get to where the OP is right now, _confused_. You're also assuming the OP understands Ruby or the concepts you're referring to. – Captain Obvlious Jul 06 '17 at 22:15