Search code examples
c++conditional-statementslogical-operators

What's the difference between a Logical AND operator and a nested if statement?


I thought there would be none yet for some reason my program doesn't work when I use a Logical AND instead of a nested if statement. I made a Tetris clone that has a hold feature which holds/stores a block when the player presses the C key. I had a boolean that prevents the player from uncontrollably swapping blocks.

For some reason this works:

if (bKey[5]) //When C key is pressed
        {
            if (!pieceHold) //boolean to prevent player from holding the C key and swapping blocks constantly/uncontrollably
            {
                if (!bPieceHeld) //check to see if player is not holding a block
                {
                    r++;
                    nHoldPiece = nCurrentPiece; //set empty hold piece into the current piece
                    nHoldRotation = nCurrentRotation; 
                    nCurrentPiece = nNextPiece; //set the current piece into the next piece
                    
                    nNextPiece = rng[r - 1];
                    nCurrentX = nFieldWidth / 2;
                    nCurrentY = 0;
                    bPieceHeld = 1;
                }
                else if (bPieceHeld) //if player is already holding block, swap held block with the current block
                {
                    int tempPiece = nCurrentPiece;
                    nCurrentPiece = nHoldPiece;
                    nHoldPiece = tempPiece;

                    int tempRotation = nCurrentRotation;
                    nCurrentRotation = nHoldRotation;
                    nHoldRotation = tempRotation;
                }
            }
            pieceHold = 1; //set boolean to true if C is already held to prevent accidental double swapping
        }
else
            pieceHold = 0; //set boolean false if C key is held

But this doesn't:

if (!pieceHold && bKey[5])
    {
        if (!bPieceHeld)
        {
                r++;
                nHoldPiece = nCurrentPiece;
                nHoldRotation = nCurrentRotation;
                nCurrentPiece = nNextPiece;
                
                nNextPiece = rng[r - 1];
                nCurrentX = nFieldWidth / 2;
                nCurrentY = 0;
                bPieceHeld = 1;
        }
        else if (bPieceHeld)
        {
                int tempPiece = nCurrentPiece;
                nCurrentPiece = nHoldPiece;
                nHoldPiece = tempPiece;

                int tempRotation = nCurrentRotation;
                nCurrentRotation = nHoldRotation;
                nHoldRotation = tempRotation;
        }
        pieceHold = 1;
    }
    else
        pieceHold = 0;

The player can still swap the blocks uncontrollably despite the bool pieceHold being there to supposedly prevent that. Why is that?


Solution

  • The outer if statement in the first code snippet contains an else part

    if (bKey[5]) 
            {
                //...
                pieceHold = 1; //set boolean to true if C is already held to prevent accidental double swapping
            }
    else
                pieceHold = 0; //set boolean false if C key is held
    

    So

     if (bKey[5]) 
     //...
     else
     //..
    

    is not the same as

    if (!pieceHold && bKey[5])
    //...
    else
    //...
    

    Pay attention to that this if-else statements

                if (!bPieceHeld) //check to see if player is not holding a block
                //..
                else if (bPieceHeld) 
    

    can be rewritten simpler like

                if (!bPieceHeld) //check to see if player is not holding a block
                //..
                else
    

    Also instead of manually swapping integers like

                int tempPiece = nCurrentPiece;
                nCurrentPiece = nHoldPiece;
                nHoldPiece = tempPiece;
    
                int tempRotation = nCurrentRotation;
                nCurrentRotation = nHoldRotation;
                nHoldRotation = tempRotation;
    

    you could write

               std::swap( nCurrentPiece, nHoldPiece );
               std::swap( nCurrentRotation, nHoldRotation );
    

    that makes your code more clear and readable.