NotApollo
NotApollo

Reputation: 39

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?

Upvotes: 0

Views: 163

Answers (2)

cigien
cigien

Reputation: 60268

This nested if:

if (bKey[5]) 
{
   if (!pieceHold) 
   {
      // ...
   }
}

is equivalent to:

if (bKey[5] && !pieceHold)

In your example, you have swapped the conditions, which is not equivalent to the nested if.

Note that the condition is equivalent to the nested if, because && will short-circuit. That means, that !pieceHold is only evaluated if bKey[5] is true.

Upvotes: 7

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

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.

Upvotes: 1

Related Questions