此操作在C++:字符 c &= 0x5F 中做什么?

What does this operation do in C++: char c &= 0x5F?

本文关键字:0x5F 什么 操作 C++ 字符      更新时间:2023-10-16
#include <time.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
//using this to avoid repeating
typedef unsigned int uint;
using namespace std;
//directions enumerations
enum movDir { UP, DOWN, LEFT, RIGHT };
class tile
{
public:
    tile() : val( 0 ), blocked( false ) {}
    //unsigned integer
    uint val;
    bool blocked;
};
// Board, winning and losing, control keys,
class g2048
{
public:
    //we're not done, no one's won, score's 0 and we are gonna move
    g2048() : done( false ), win( false ), moved( true ), score( 0 ) {}
    //function loop
    void loop()
    {
        addTile();
        while( true )
        {
            if( moved )
                addTile();
            drawBoard();
            if( done )
                break;
            ControlKey();
        }
        string s = "Game Over!";
        if( win ) s = "You made it!";
        cout << s << endl << endl;
    } //end of func loop
private:
    //This is how the board looks like
    void drawBoard()
    {string
        system( "cls" );
        cout << "SCORE: " << score << endl << endl;
        for( int y = 0 ; y < 4 ; y++ )
        {
            cout << "+------+------+------+------+" << endl << "| ";
            for( int x = 0; x < 4; x++ )
            {
                if( !board[x][y].val )
                    //setw is to add in spaces in each box
                    cout << setw( 4 ) << " ";
                else
                    cout << setw( 4 ) << board[x][y].val;
                cout << " | ";
            }
            cout << endl;
        }
        cout << "+------+------+------+------+" << endl << endl;
    }

    void ControlKey()
    {
        moved = false;
        char c;
        //Control Keys
        cout << "(W)Up (S)Down (A)Left (D)Right ";
        cin >> c;
        /* Bitwise AND, the individual bits of c will be ANDed with
        the corresponding bits of the hex number 0x5F.
        This is a bitmasking, so the bit 5 of c gets cleared, while bits
         0 to 4 and 6 remain untouched. (all higher order bits will be cleared)
         */
        c &= 0x5F;
        switch ( c )
        {
            case 'W': move( UP );
                break;
            case 'A': move( LEFT );
                break;
            case 'S': move( DOWN );
                break;
            case 'D': move( RIGHT );
        }
        // can you still move?
        for( int y = 0; y < 4; y++ )
            for( int x = 0; x < 4; x++ )
                board[x][y].blocked = false;
    }

    void addTile()
    {
        for( int y = 0; y < 4; y++ )
            for( int x = 0; x < 4; x++ )
                //if board is not empty
                if( !board[x][y].val )
                {
                    uint a, b;
                    do
                    {
                        //rand() standard lib func that generates rand #
                        a = rand() % 4;
                        b = rand() % 4;
                    }
                    while( board[a][b].val );
                    int s = rand() % 100;
                    if( s > 89 ) board[a][b].val = 4;
                    else board[a][b].val = 2;
                    if( canMove() )
                        return;
                }
        done = true;
    }

    bool canMove()
    {
        for( int y = 0; y < 4; y++ )
            for( int x = 0; x < 4; x++ )
                //if the board's empty, you can move
                if( !board[x][y].val )
                    return true;
        for( int y = 0; y < 4; y++ )
            for( int x = 0; x < 4; x++ )
            {
                if( testAdd( x + 1, y, board[x][y].val ) )
                    return true;
                if( testAdd( x - 1, y, board[x][y].val ) )
                    return true;
                if( testAdd( x, y + 1, board[x][y].val ) )
                    return true;
                if( testAdd( x, y - 1, board[x][y].val ) )
                    return true;
            }
        return false;
    }
    //v is the board[x][y].val
    bool testAdd( int x, int y, uint v )
    {
        //out of range
        if( x < 0 || x > 3 || y < 0 || y > 3 )
            return false;
        return board[x][y].val == v;
    }
    // Verticall movement (Up, Down)
    void moveVert( int x, int y, int d )
    {
        if( board[x][y + d].val && board[x][y + d].val == board[x][y].val && !board[x][y].blocked && !board[x][y + d].blocked  )
        {
            board[x][y].val = 0;
            board[x][y + d].val *= 2;
            //update score
            score += board[x][y + d].val;
            board[x][y + d].blocked = true;
            moved = true;
        }
        else if( !board[x][y + d].val && board[x][y].val )
        {
            board[x][y + d].val = board[x][y].val;
            board[x][y].val = 0;
            moved = true;
        }
        if( d > 0 ) {
            if( y + d < 3 )
                moveVert( x, y + d,  1 );
        }
        else {
            if( y + d > 0 )
                moveVert( x, y + d, -1 );
        }
    }
    //Horizontal movement (Right, Left)
    void moveHori( int x, int y, int d )
    {
        if( board[x + d][y].val && board[x + d][y].val == board[x][y].val
           && !board[x][y].blocked && !board[x + d][y].blocked  )
        {
            board[x][y].val = 0;
            board[x + d][y].val *= 2;
            //update score
            score += board[x + d][y].val;
            board[x + d][y].blocked = true;
            moved = true;
        }
        else if( !board[x + d][y].val && board[x][y].val )
        {
            board[x + d][y].val = board[x][y].val;
            board[x][y].val = 0;
            moved = true;
        }
        if( d > 0 ) { 
            if( x + d < 3 ) 
                moveHori( x + d, y,  1 ); 
        }
        else        { 
            if( x + d > 0 )
                moveHori( x + d, y, -1 ); 
        }
    }
    void move( movDir d )
    {
        switch( d )
        {
            case UP:
                for( int x = 0; x < 4; x++ )
                {
                    int y = 1;
                    while( y < 4 )
                    { 
                        if( board[x][y].val )
                            moveVert( x, y, -1 ); 
                        y++;
                    }
                }
                break;
            case DOWN:
                for( int x = 0; x < 4; x++ )
                {
                    int y = 2;
                    while( y >= 0 )
                    { 
                        if( board[x][y].val )
                            moveVert( x, y, 1 ); 
                        y--;
                    }
                }
                break;
            case LEFT:
                for( int y = 0; y < 4; y++ )
                {
                    int x = 1;
                    while( x < 4 )
                    { 
                        if( board[x][y].val ) 
                            moveHori( x, y, -1 );
                        x++;
                    }
                }
                break;
            case RIGHT:
                for( int y = 0; y < 4; y++ )
                {
                    int x = 2;
                    while( x >= 0 )
                    { 
                        if( board[x][y].val ) 
                            moveHori( x, y, 1 ); 
                        x--;
                    }
                }
        }
    }
    tile board[4][4];
    bool win, done, moved;
    uint score;
};

int main()
{
    //srand() std lib func, seeding a rand num generator
    //return val of unsigned int time() ---> random value
    srand( static_cast <uint>( time( NULL ) ) );
    g2048 g; 
    g.loop();
    return system( "pause" );
}

如果没有 c &= 0x5F它只会继续绘制电路板而不对其进行任何更改。这条线有什么作用?这是2048的游戏。我认为这部分代码正在尝试和这个按位,但我真的不了解机制。究竟发生了什么,使简单的线条如此重要,以至于没有它,一切都错了?

在您的代码中,通过删除在上限和下部字符之间不同的位来执行c=toupper(c),这是错误的方法。

无需c&=0x5f请尝试使用caplock的代码

c &= 0x5F;

位计算 AND c & 0x5F并将结果分配给 c

如果您使用 ASCII 代码,我想它用于将小写字母转换为大写字母。