Thread: how to simplify an if statment test

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    how to simplify an if statment test

    in my game of checkers i need to test weather a piece is moving in the right direction. i could write
    Code:
    bool calculate_move(char board[][ROW_MAX +1][MESSAGE], int current_player, int piece_coordinate_x,
                        int piece_coordinate_y, int move_coordinate_x, int move_coordinate_y)
    {
        if (((current_player == PLAYER_WHITE) && (move_coordinate_y - piece_coordinate_y == 1)) || ((current_player == PLAYER_BLACK) && (piece_coordinate_y - move_coordinate_y)))
        {
            return false;
        }
        else if ((move_coordinate_y - piece_coordinate_y == 1) && ((move_coordinate_x - piece_coordinate_x == -1) ||
                (move_coordinate_x - piece_coordinate_x == 1)))
        {
            current_player ? move_1_square(board,"b", piece_coordinate_x, piece_coordinate_y, move_coordinate_x,
                                           move_coordinate_y, current_player) : move_1_square(board, "w",piece_coordinate_x,
                                           piece_coordinate_y, move_coordinate_x, move_coordinate_y, current_player);
            return true;
        }
        else
        {
            // call piece take piece
            return true;
        }
    }
    but hat is a real mouthfull
    or i could write
    Code:
    int x;
        x = current_player ? (piece_coordinate_y - move_coordinate_y) (move_coordinate_y - piece_coordinate_y)
        if (x < 0)
        {
            return false;
        }
        else if ((move_coordinate_y - piece_coordinate_y == 1) && ((move_coordinate_x - piece_coordinate_x == -1) ||
                (move_coordinate_x - piece_coordinate_x == 1)))
        {
            current_player ? move_1_square(board,"b", piece_coordinate_x, piece_coordinate_y, move_coordinate_x,
                                           move_coordinate_y, current_player) : move_1_square(board, "w",piece_coordinate_x,
                                           piece_coordinate_y, move_coordinate_x, move_coordinate_y, current_player);
            return true;
        }
        else
        {
            // call piece take piece
            return true;
        }
    }
    but that adds extra lines

    can i use an if statement like this
    Code:
        if ((current_player ? (piece_coordinate_y - move_coordinate_y) : (move_coordinate_y - piece_coordinate_y)) < 0)
        {
            return false;
        }
        else if ((move_coordinate_y - piece_coordinate_y == 1) && ((move_coordinate_x - piece_coordinate_x == -1) ||
                (move_coordinate_x - piece_coordinate_x == 1)))
        {
            current_player ? move_1_square(board,"b", piece_coordinate_x, piece_coordinate_y, move_coordinate_x,
                                           move_coordinate_y, current_player) : move_1_square(board, "w",piece_coordinate_x,
                                           piece_coordinate_y, move_coordinate_x, move_coordinate_y, current_player);
            return true;
        }
        else
        {
            // call piece take piece
            return true;
        }
    }
    any advise on which way is best would be appreciated
    coop

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I would be inclined to start with:
    Code:
    bool calculate_move(char board[][ROW_MAX +1][MESSAGE], int current_player,
                        int piece_coordinate_x, int piece_coordinate_y,
                        int move_coordinate_x, int move_coordinate_y)
    {
        if ((current_player == PLAYER_WHITE && (move_coordinate_y - piece_coordinate_y == 1)) ||
            (current_player == PLAYER_BLACK && (piece_coordinate_y - move_coordinate_y)))
        {
            return false;
        }
        else
        {
            const int move_piece_coordinate_x_diff = move_coordinate_x - piece_coordinate_x;
            if ((move_coordinate_y - piece_coordinate_y == 1) &&
                (move_piece_coordinate_x_diff == -1 || move_piece_coordinate_x_diff == 1))
            {
                const char *const player_label = (current_player == PLAYER_BLACK) ? "b" : "w";
                move_1_square(board, player_label,
                              piece_coordinate_x, piece_coordinate_y,
                              move_coordinate_x, move_coordinate_y, current_player);
            }
            return true;
        }
    }
    This makes it clear when you'll return false and when you'll return true. When you return true, you might also do something under certain conditions, and that's expressed in the inner if statement. It's possible to also restructure this to move the return false to the end, and invert the outer if statement's condition.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Here's a useful technique you can use to simplify boolean expressions: K maps.

    With computer languages you can set a logical variable (let's say A) to a condition and it's inverse to the complementary condition... for example, if you want to test (x > 0) you can call this A and (x <= 0) "not A". As an example, if you have an if statement as:
    Code:
    if ( x > 0 || ( x <= 0 && y == 3 ) ) ...
    Then A ≡ (x > 0); ~A ≡ (x <= 0); B ≡ (y == 3). Which gives us the equation: S=A + ~A*B ( + is OR; * is AND in this context ).
    Apply this to a bidimensional K map and you'll get S = A + B, so the code is simplified to:
    Code:
    if ( x > 0 || y == 3) ...
    Last edited by flp1969; 05-06-2019 at 04:24 AM.

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    thanks for the advice i shall implement the if clause however i dont understand the else part.

    are you declaring a constant int variable called move_piece_coordinate_x_diff and then setting it to the value of move_coordinate_x - piece_coordinate_x but don't seem to then use it
    then setting a constant char with a constant pointer called player_label and setting the pointer to either b or w.
    then passing the address of the pointer to the function move_1_square with the rest of the parameters.

    sorry to be thick
    coop

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cooper1200
    are you declaring a constant int variable called move_piece_coordinate_x_diff and then setting it to the value of move_coordinate_x - piece_coordinate_x but don't seem to then use it
    It is used in the if statement.

    Quote Originally Posted by cooper1200
    then setting a constant char with a constant pointer called player_label and setting the pointer to either b or w.
    then passing the address of the pointer to the function move_1_square with the rest of the parameters.
    Yes. I'd say that this is effectively an abuse of the ternary operator:
    Code:
    current_player ? move_1_square(board,"b", piece_coordinate_x, piece_coordinate_y, move_coordinate_x,
                                   move_coordinate_y, current_player) : move_1_square(board, "w",piece_coordinate_x,
                                   piece_coordinate_y, move_coordinate_x, move_coordinate_y, current_player);
    It is terribly difficult to see what is going on. It would have been better to write it as:
    Code:
    if (current_player)
    {
        move_1_square(board, "b", piece_coordinate_x, piece_coordinate_y,
                      move_coordinate_x, move_coordinate_y, current_player);
    }
    else
    {
        move_1_square(board, "w", piece_coordinate_x, piece_coordinate_y,
                      move_coordinate_x, move_coordinate_y, current_player);
    }
    or if you absolutely must use the ternary operator:
    Code:
    current_player ? move_1_square(board, "b", piece_coordinate_x, piece_coordinate_y,
                                   move_coordinate_x, move_coordinate_y, current_player)
                   : move_1_square(board, "w", piece_coordinate_x, piece_coordinate_y,
                                   move_coordinate_x, move_coordinate_y, current_player);
    When you do this, you can easily see that they only differ by the "b" versus "w" arguments. Therefore, it makes sense to have a pointer point to one of them depending on the value of current_player, then just have a single instance of the call to move_1_square. This is an application of the DRY principle: Don't Repeat Yourself. It is also why I came up with move_piece_coordinate_x_diff.
    Last edited by laserlight; 05-06-2019 at 04:39 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    ok i understand now and because passing an array as a parameter to a function you effectively are passing a pointer.

    why declare the player label and the definition (char) as constant though

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cooper1200
    why declare the player label and the definition (char) as constant though
    As they exist purely to serve as placeholders for the result of some intermediate computation, they aren't supposed to be modified, so they should be const, as attempting to modify them is most likely indicative of a bug.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry i meant why
    Code:
    const char *const  player_lable
    //rather than
    const  char *player_lable
    //or
    char const* player_lable
    coop

  9. #9
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    on the subject of "DRY" and my use of the ternary operator when i applied your reasoning to my whole code so far i found several places where i had done it. i even found 1 place where i had the same thing either side of the : part!!

    coop

  10. #10
    Registered User I C everything's Avatar
    Join Date
    Apr 2019
    Posts
    101
    Quote Originally Posted by flp1969 View Post
    Here's a useful technique you can use to simplify boolean expressions: K maps.

    With computer languages you can set a logical variable (let's say A) to a condition and it's inverse to the complementary condition... for example, if you want to test (x > 0) you can call this A and (x <= 0) "not A". As an example, if you have an if statement as:
    Code:
    if ( x > 0 || ( x <= 0 && y == 3 ) ) ...
    Then A ≡ (x > 0); ~A ≡ (x <= 0); B ≡ (y == 3). Which gives us the equation: S=A + ~A*B ( + is OR; * is AND in this context ).
    Apply this to a bidimensional K map and you'll get S = A + B, so the code is simplified to:
    Code:
    if ( x > 0 || y == 3) ...
    I am interested in how you write c,alternative ifs using boolean equations
    Easiest way,if i tranform boolean false true in c to integer?does it become an useful mask either zero ,or biggest integer?
    So it later can be used with variable AND mask changes variable alternarive way to use if else
    you tell me you can C,why dont you C your own bugs?

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by I C everything View Post
    I am interested in how you write c,alternative ifs using boolean equations
    Easiest way,if i tranform boolean false true in c to integer?does it become an useful mask either zero ,or biggest integer?
    So it later can be used with variable AND mask changes variable alternarive way to use if else
    You do know that C/C++ boolean operators expect to find 0 as false and anything else as true, don't you?

    Don't care if the type is _Bool, char, short int, int, long int, long long int, float, double or a pointer...

    And the result of an boolean expression is always 0 or 1 (defined by the standard).
    Last edited by flp1969; 05-06-2019 at 10:02 AM.

  12. #12
    Registered User I C everything's Avatar
    Join Date
    Apr 2019
    Posts
    101
    Quote Originally Posted by flp1969 View Post
    You do know that C/C++ boolean operators expect to find 0 as false and anything else as true, don't you?

    Don't care if the type is _Bool, char, short int, int, long int, long long int, float, double or a pointer...

    And the result of an boolean expression is always 0 or 1 (defined by the standard).
    thats good enough to do something like
    Code:
    x=x+(inkey==rightkey)-(inkey==leftkey);
    y=y+(inkey==downkey)-(inkey==upkey);
    for readibility,keep the replaced IF ELSE in comments or pseudocode in comments

    well in some cases its just to make a function that returns 0 or FFFFFFFF instead when mask is needed,for example mask ARGB pixels
    you tell me you can C,why dont you C your own bugs?

  13. #13
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by I C everything View Post
    thats good enough to do something like
    Code:
    x=x+(inkey==rightkey)-(inkey==leftkey);
    y=y+(inkey==downkey)-(inkey==upkey);
    Another useful example... Let's say you want to sort an array of ints using qsort:
    Code:
    static int compare(int *a, int *b) { return (*a > *b) - (*a < *b); }
    ...
    void sort( int *ptr, size_t items ) { qsort( ptr, items, sizeof( int ), compare ); }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do I simplify this code so its smaller
    By jeremy duncan in forum C++ Programming
    Replies: 4
    Last Post: 05-17-2016, 05:36 AM
  2. Help simplify this Tic-Tac-Toe program
    By moombah256 in forum C++ Programming
    Replies: 1
    Last Post: 10-15-2012, 12:04 PM
  3. Can someone help me simplify this?
    By Shackdaddy836 in forum C Programming
    Replies: 1
    Last Post: 10-07-2011, 02:56 PM
  4. Simplify Fraction Help
    By CaliJoe in forum C++ Programming
    Replies: 1
    Last Post: 05-01-2009, 01:17 PM
  5. simplify this?
    By markg in forum C Programming
    Replies: 2
    Last Post: 10-25-2005, 08:09 PM

Tags for this Thread