用C++实现小游戏2048

用C++写了一个简单2048小游戏,最大数字达到2048即为结束

方向键控制移动

用C++实现小游戏2048_第1张图片

#include 
#include 
#include 
#include 
#include 

using namespace std;

int nums[4][4];
int emp = 16, score = 0; // 空格子数, 分数
int maxv = 2; // 场上最大数,到达2048时,结束游戏
int dirc_st = 0b0000; // 状态变量,表示可操作的方向

// 绘制地图函数
void drawmap()
{
    // 先清屏幕
    system("cls");
    puts("          ---- 2 0 4 8 ----");
    puts("               by DNA\n");
    cout << "              得分: " << score  << '\n' << endl;
  
    for (int col = 1; col <= 17; col++)
    {
        cout << "  ";
        if (col % 4 == 1)   puts(" -------------------------------- ");
        else if (col % 4 == 2 || col % 4 == 0)   puts("|       |       |       |       |");
        else
        {
            cout << '|';
            for (int row = 0; row <= 3; row++)
                if (nums[col / 4][row] != 0)
                    printf("%5d  |", nums[col / 4][row]);
                else
                    printf("       |");
            puts("");
        }
    }



    // 测试
    /*
    puts("");
    cout << "empty = " << emt << endl;
    cout << "max :" << maxv << endl;
    cout << "方向状态" << endl;
    cout << "上 : " << (dirc_st >> 3 & 1) << endl;
    cout << "下 : " << (dirc_st >> 2 & 1) << endl;
    cout << "左 : " << (dirc_st >> 1 & 1) << endl;
    cout << "右 : " << (dirc_st >> 0 & 1) << endl;
    */
}

// 产生新数字
void newnums()
{
    // 产生2:67% 产生4:33%
    int newnumber = (rand() % 3) ? 2 : 4;

    int x, y;
    do
    {
        x = rand() % 4, y = rand() % 4;
    } while (nums[x][y] != 0);

    nums[x][y] = newnumber;
    score += newnumber;
    emp --;
}

// 状态判断
void statecheck()
{
    dirc_st = 0b0000; // 分别代表当前状态是否可以上下左右移动
    // 上
    for (int i = 1; i <= 3; i ++ )
        for (int j = 0; j <= 3; j++)
        {
            if (nums[i][j] != 0 && nums[i - 1][j] == 0 || 
                nums[i][j] != 0 && nums[i - 1][j] == nums[i][j])
            { dirc_st |= 0b1000; break; }
        }
    //下
    for (int i = 0; i <= 2; i++)
        for (int j = 0; j <= 3; j++)
        {
            if (nums[i][j] != 0 && nums[i + 1][j] == 0 ||
                nums[i][j] != 0 && nums[i + 1][j] == nums[i][j]) 
            { dirc_st |= 0b0100; break; }
        }
    //左
    for (int j = 1; j <= 3; j++)
        for (int i = 0; i <= 3; i++)
        {
            if (nums[i][j] != 0 && nums[i][j - 1] == 0 ||
                nums[i][j] != 0 && nums[i][j - 1] == nums[i][j])
            { dirc_st |= 0b0010; break; }
        }
    //右
    for (int j = 0; j <= 2; j++)
        for (int i = 0; i <= 3; i++)
        {
            if (nums[i][j] != 0 && nums[i][j + 1] == 0 ||
                nums[i][j] != 0 && nums[i][j + 1] == nums[i][j]) 
            { dirc_st |= 0b0001; break; }
        }
}

/* 四向移动 : 先初步处理,再同时向目标方向移动 
 * 比如某行为 0 2 2 8 左移,先处理成 0 4 0 8,再处理成 4 8 0 0
 */
void left()
{
    for (int i = 0; i <= 3; i++) // 处理每一行
    {
        for (int j = 0; j <= 3; j++)
            if (nums[i][j] == 0)    continue;
            else
            {
                for (int k = j + 1; k <= 3; k++)
                {
                    if (nums[i][k] == 0)    continue;
                    else if (nums[i][j] == nums[i][k])
                    {
                        nums[i][j] += nums[i][k];
                        nums[i][k] = 0;
                        emp++, score += nums[i][j];
                        maxv = max(maxv, nums[i][j]);
                        break;
                    }
                    else break;
                }
            }
    }

    // 全体左移
    for (int i = 0; i <= 3; i++) // 处理每一行
    {
        int idx = 0; // 新位置
        for (int j = 0; j <= 3; j++)
        {
            if (nums[i][j] == 0) continue;
            else
            {
                nums[i][idx] = nums[i][j];
                if (j != idx) nums[i][j] = 0;
                idx++;
            }
        }
    }
}

void right()
{
    for (int i = 0; i <= 3; i++) // 处理每一行
    {
        for (int j = 3; j >= 0; j--)
            if (nums[i][j] == 0)    continue;
            else
            {
                for (int k = j - 1; k >= 0; k--)
                {
                    if (nums[i][k] == 0)    continue;
                    else if (nums[i][j] == nums[i][k])
                    {
                        nums[i][j] += nums[i][k];
                        nums[i][k] = 0;
                        emp++, score += nums[i][j];
                        maxv = max(maxv, nums[i][j]);
                        break;
                    }
                    else break;
                }
            }
    }

    // 全体右移
    for (int i = 0; i <= 3; i++) // 处理每一行
    {
        int idx = 3; // 新位置
        for (int j = 3; j >= 0; j--)
        {
            if (nums[i][j] == 0) continue;
            else
            {
                nums[i][idx] = nums[i][j];
                if (j != idx) nums[i][j] = 0;
                idx--;
            }
        }
    }
}

void up()
{
    for (int i = 0; i <= 3; i++) // 处理每一列
    {
        for (int j = 0; j <= 3; j++)
            if (nums[j][i] == 0)    continue;
            else
            {
                for (int k = j + 1; k <= 3; k++)
                {
                    if (nums[k][i] == 0)    continue;
                    else if (nums[j][i] == nums[k][i])
                    {
                        nums[j][i] += nums[k][i];
                        nums[k][i] = 0;
                        emp++, score += nums[j][i];
                        maxv = max(maxv, nums[j][i]);
                        break;
                    }
                    else break;
                }
            }
    }

    // 全体上移
    for (int i = 0; i <= 3; i++) // 处理每一列
    {
        int idx = 0; // 新位置
        for (int j = 0; j <= 3; j++)
        {
            if (nums[j][i] == 0) continue;
            else
            {
                nums[idx][i] = nums[j][i];
                if (j != idx) nums[j][i] = 0;
                idx++;
            }
        }
    }
}

void down()
{
    for (int i = 0; i <= 3; i++) // 处理每一列
    {
        for (int j = 3; j >= 0; j--)
            if (nums[j][i] == 0)    continue;
            else
            {
                for (int k = j - 1; k >= 0; k--)
                {
                    if (nums[k][i] == 0)    continue;
                    else if (nums[j][i] == nums[k][i])
                    {
                        nums[j][i] += nums[k][i];
                        nums[k][i] = 0;
                        emp++, score += nums[j][i];
                        maxv = max(maxv, nums[j][i]);
                        break;
                    }
                    else break;
                }
            }
    }

    // 全体下移
    for (int i = 0; i <= 3; i++) // 处理每一列
    {
        int idx = 3; // 新位置
        for (int j = 3; j >= 0; j--)
        {
            if (nums[j][i] == 0) continue;
            else
            {
                nums[idx][i] = nums[j][i];
                if (j != idx) nums[j][i] = 0;
                idx--;
            }
        }
    }
}

// 游戏结束函数
void game_over()
{
    puts("");
    cout << "  无路可走,游戏结束\n  你的得分是 " << score << " 分" << endl;
}

// 达成2048
void game_win()
{
    puts("");
    cout << "  2048 出现了,游戏结束\n  你的得分是 " << score << " 分\n  去挑战更高分数吧!" << endl;
}

// 初始化函数
void init()
{
    int x = rand() % 4;
    int y = rand() % 4;
    nums[x][y] = 2;
    emp--;

    statecheck();
    drawmap();
}

// 游戏主体
void game()
{
    while (true)
    {
        int ch = _getch();
        switch (ch)
        {
        case 72: 
            if (dirc_st >> 3 & 1)   up();
            else {
                cout << "\n  不能往上" << endl;  continue;
            }
            break;

        case 80: 
            if (dirc_st >> 2 & 1)   down();
            else {
                cout << "\n  不能往下" << endl;  continue;
            }
            break;

        case 75: 
            if (dirc_st >> 1 & 1)   left();
            else {
                cout << "\n  不能往左" << endl;  continue;
            }
            break;

        case 77:
            if (dirc_st  & 1)   right();
            else {
                cout << "\n  不能往右" << endl;  continue;
            }
            break;

        default:
            break;
        }

        if (ch != 224 ) newnums();
        statecheck();
        drawmap();

        // 出现2048结束
        if (maxv >= 2000)
        {
            game_win();
            break;
        }

        // 无路可走结束
        if (dirc_st == 0)
        {
            game_over();
            break;
        }      
    }
}

int main()
{
    srand(time(0));
    init();

    game();

    system("pause");

    return 0;
}

你可能感兴趣的:(小游戏)