简单的2048游戏(c语言)

这是一个C语言实现的2048游戏代码,包括游戏初始化、移动操作、判断游戏结束、生成随机数等功能。游戏使用4x4矩阵存储,支持上下左右四个方向的操作,并在每次操作后检查游戏是否结束。用户可以通过输入WASD键进行控制,当无法进行任何移动时游戏结束。代码还包含了界面刷新和用户交互的部分。
摘要由CSDN通过智能技术生成

这个代码很长。。。。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<windows.h>
#include<time.h>

int board[4][4]= {0,2,16,4,0,8,4,16,2}; //全局变量board记录4*4个单元格各自的值
int score=0;
void refresh_show()
{
    // 重设光标输出位置方式清屏可以减少闪烁,system("cls")为备用清屏命令,均为Windows平台相关
    COORD pos = { 0, 0 };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);

    /*其余代码*/
    int i,j;

    //int board[4][4]= {0,2,8,4,0,8,4,2,2};
    printf("                游戏名: 2048                     分数:%d\n",score);
    printf("             --------------------------------------------------\n\n");
    printf("                        ┌────┬────┬────┬────┐\n");
    for(i=0; i<4; i++)
    {
        printf("                        │");
        for(j=0; j<4; j++)
        {
            if(board[i][j]!=0)
                printf("%4d│",board[i][j]);
            else
                printf("    │");
        }

        printf("\n");
        if(i<3)
            printf("                        ├────┼────┼────┼────┤\n");
    }
//printf("\n");
    printf("                        └────┴────┴────┴────┘\n");
    printf("\n");
    printf("             --------------------------------------------------\n");
    printf("                            W↑  A←  →D  ↓S\n");

}
int if_game_over=0;
// 检查游戏是否结束 函数定义
int check_game_over()
{
    int flag=0,flag1=0;
    for(int i=0; i<4; i++)
    {
        for(int j=0; j<4; j++)
        {
            if(board[i][j]==0)
            {
                flag=1;
                break;
            }
        }
    }
    for(int i=0; i<=3; i++)
    {
        for(int j=0; j<=3; j++)
        {
            if(board[i][j]==board[i-1][j]||board[i][j]==board[i][j-1]||board[i][j]==board[i+1][j]||board[i][j]==board[i][j+1])
            {
                flag1=1;
                break;
            }
        }
    }
    if(flag==0&&flag1==0)
    {
        if_game_over=1;
    }
    else
    {
        if_game_over=0;
    }
    return if_game_over;
    // if_game_over=0,游戏不结束,=1游戏结束
}
int get_null_count()//统计空格
{
    int sum=0,i,j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (board[i][j] == 0)
                sum++;
        }
    }
    return sum;
}

void add_rand_num()
{
    srand(time(0));
    int n = rand() % get_null_count();// 确定在何处空位置生成随机数
    int i,j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (board[i][j] == 0)
            {
                if (n-- == 0)  //定位待生成的位置
                {
                    board[i][j] = (rand() % 3 ? 2 : 4);//rand() % 3的值为真(1或2)取前值2,反之,取 4 ,保证生成 2 的概率是 4 的 2 倍
                    return;
                }
            }
        }
    }
}

void reset_game()
{
    printf("合成一个+2分\n");
    score = 0;
    if_game_over = 0;

    // 了解到游戏初始化时出现的两个数一定会有个 2,所以先随机生成一个 2,其他均为 0
    int n = rand() % 16;
    int i,j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            board[i][j] = (n-- == 0 ? 2 : 0);
        }
    }
    // 前面已经生成了一个2,这里再生成一个随机的2或者4,且设定生成2的概率是4的两倍
    add_rand_num();

    // 在这里刷新界面并显示的时候,界面上已经默认出现了两个数字,其他的都为空(值为0)
    system("cls");
    refresh_show();
}
void moveLeft()
{
    int i,j,cur,next;
    //合并相邻相等数字
    for(i=0; i<4; i++)
    {
        for(j=0; j<4; j++)
        {
            cur=0;
            next=1;
            while(cur<4)
            {
                if(board[i][next]==board[i][cur]&&board[i][next]!=0)
                {
                    score+=2;
                    board[i][cur]=board[i][cur]*2;
                    board[i][next]=0;
                    next++;//相邻两个数相等,就合并,合并完成,更新cur,next
                }
                else if(board[i][next]==0)
                {
                    next++;
                }
                //next没有数字,更新next
                else
                {
                    cur++;
                    next=cur+1;  //其他情况,next指向数字与cur指向数字不一样,更新cur和next
                }
                if(next>=4)
                {
                    cur++;
                    next=cur+1;
                }
            }
        }
    }
    //移动数字到最左边
    for(i=0; i<4; i++)
    {
        cur=1;
        while(cur<4)
        {
            if(board[i][cur]==0)
                //从cur开始,依次往前移动后面的数
                cur++;
            else if(board[i][cur]!=0&&board[i][cur-1]==0)
            {
                board[i][cur-1]=board[i][cur];
                board[i][cur]=0;
                cur=1;
            }
            else
            {
                cur++;
            }
        }
    }
}
void moveRight()
{
    int i,j,cur,next;
    //合并相邻相等数字
    for(i=0; i<4; i++)
    {
        for(j=0; j<4; j++)
        {
            cur=3;
            next=cur-1;
            while(cur>=0)
            {
                if(board[i][next]==board[i][cur]&&board[i][next]!=0)
                {
                    score+=2;
                    board[i][cur]=board[i][cur]*2;
                    board[i][next]=0;
                    next--;//相邻两个数相等,就合并,合并完成,更新cur,next
                }
                else if(board[i][next]==0)
                {
                    next--;
                }
                //next没有数字,更新next
                else
                {
                    cur--;
                    next=cur-1;  //其他情况,next指向数字与cur指向数字不一样,更新cur和next
                }
                if(next<0)
                {
                    cur--;
                    next=cur-1;
                }
            }
        }
    }
    //移动数字到最右边
    for(i=0; i<4; i++)
    {
        cur=2;
        while(cur>=0)
        {
            if(board[i][cur]==0)
                //从cur开始,依次往hou移动qian面的数
                cur--;
            else if(board[i][cur]!=0&&board[i][cur+1]==0)
            {
                board[i][cur+1]=board[i][cur];
                board[i][cur]=0;
                cur=2;
            }
            else
            {
                cur--;
            }
        }
    }
}
void moveUp()
{
    int i,j,cur,next;
    //合并相邻相等数字
    for(i=0; i<4; i++)
    {
        for(j=0; j<4; j++)
        {
            cur=0;
            next=1;
            while(cur<4)
            {

                if(board[next][i]==board[cur][i]&&board[next][i]!=0)
                {
                    score+=2;
                    board[cur][i]=board[cur][i]*2;
                    board[next][i]=0;
                    next++;//相邻两个数相等,就合并,合并完成,更新cur,next
                }
                else if(board[next][i]==0)
                {
                    next++;
                }
                //next没有数字,更新next
                else
                {
                    cur++;
                    next=cur+1;  //其他情况,next指向数字与cur指向数字不一样,更新cur和next
                }
                if(next>=4)
                {
                    cur++;
                    next=cur+1;
                }
            }
        }
    }
    //移动数字到最上边
    for(i=0; i<4; i++)
    {
        cur=1;
        while(cur<4)
        {
            if(board[cur][i]==0)
                //从cur开始,依次往前移动后面的数
                cur++;
            else if(board[cur][i]!=0&&board[cur-1][i]==0)
            {
                board[cur-1][i]=board[cur][i];
                board[cur][i]=0;
                cur=1;
            }
            else
            {
                cur++;
            }
        }
    }
}
void moveDown()
{
    int i,j,cur,next;
    //合并相邻相等数字
    for(i=0; i<4; i++)
    {
        for(j=0; j<4; j++)
        {
            cur=3;
            next=cur-1;
            while(cur>=0)
            {
                if(board[next][i]==board[cur][i]&&board[next][i]!=0)
                {
                    score+=2;
                    board[cur][i]=board[cur][i]*2;
                    board[next][i]=0;
                    next--;//相邻两个数相等,就合并,合并完成,更新cur,next
                }
                else if(board[next][i]==0)
                {
                    next--;
                }
                //next没有数字,更新next
                else
                {
                    cur--;
                    next=cur-1;  //其他情况,next指向数字与cur指向数字不一样,更新cur和next
                }
                if(next<0)
                {
                    cur--;
                    next=cur-1;
                }
            }
        }
    }
    //移动数字到最上边
    for(i=0; i<4; i++)
    {
        cur=2;
        while(cur>=0)
        {
            if(board[cur][i]==0)
                //从cur开始,依次往前移动后面的数
                cur--;
            else if(board[cur][i]!=0&&board[cur+1][i]==0)
            {
                board[cur+1][i]=board[cur][i];
                board[cur][i]=0;
                cur=2;
            }
            else
            {
                cur--;
            }
        }
    }

}
int main()
{
    //show();
    //refresh_show();
    reset_game();//初始化
    int c;
    while(~scanf("%c",&c))
    {
        getchar();
        //printf("%d",check_game_over())
        int flag2=0;
        if(c=='A')
        {
            moveLeft();
        }
        else if(c=='D')
        {
            moveRight();
        }
        else if(c=='W')
        {
            moveUp();
        }
        else if(c=='S')
        {
            moveDown();
        }
        else
        {
            system("cls");
            refresh_show();
            printf("输错了,请重新输入\n");
            flag2=1;
        }
        if(flag2==0)
        {
            if(get_null_count()>0)
            {
                add_rand_num();
            }
            system("cls");
            refresh_show();
        }
        if (check_game_over()==1)
        {
            int x;
            printf("GAME OVER!!!!!\n");
            printf("最终得分:%d\n",score);
            printf("是否继续?输入'Y' or 输入'N'(Y代表继续,N代表结束)\n");
            scanf("%c",&x);
            getchar();
            if(x=='Y')
            {
                system("cls");
                reset_game();
                if_game_over=0;
                score=0;
                continue;
            }
            else
            {
                return 0;
            }
        }
    }
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值