C++ 2048小游戏

· · 个人记录

背景:(课间,我去ljh大佬那玩)

我:ljh,我最近玩2048,最高是14.9W分,你呢 qwq ?

ljh: 2048 啊,(思考ing)几百万吧 。

我:!!???!!!(O_o)!

于是我就写了一个…

#include<bits/stdc++.h>
#include<windows.h> // 我的退役之作:" 2048 "  qwq 
#include<conio.h>
using namespace std;
const int n=4; // 表格边长 qwq 
const int maxn=n*n+n;
const int Speed=250; // 单位 ms(毫秒),250ms 接近大脑的反应速度 qwq 
const int model=10; // 生成 4的概率( 标准 : 10% )qwq 
inline void title_(){
    char title[1001];
    sprintf(title,"title 2048  作者:解承豫"); // 改变标题所要改的内容  qwq 
    system(title); // 改变标题  qwq 
    return ;
}
inline int toint(float a){ // 可以将文字输出点瞬移到指定坐标(x,y)的操作的函数的调用值的函数!qwq 
    return ((int)(a*10+5))/10;
}
inline void Setpos(float x,float y){ // 可以将文字输出点瞬移到指定坐标(x,y)的操作的函数!qwq 
    COORD pos;
    pos.X=toint(y*2),pos.Y=toint(x);
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
    return ; 
}
inline void Color(unsigned short a,unsigned short b){ // 颜色设置 qwq  
    HANDLE Handle=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(Handle,a+b*0x10);
    return ;
}
int num[maxn][maxn];
struct node{
    float x,y; // float-->处理 0.5的单字节情况 qwq  
};
node place[maxn][maxn]; // 方块打印位置 qwq 
string xls="\n\n\n\n\n\n\n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n                                   \n"; // 2048的表格 qwq 
string number[maxn]={"      ","   2  ","   4  ","   8  ","  16  ","  32  ","  64  ","  128 ","  256 ","  512 "," 1024 "," 2048 "," 4096 "," 8192 "," 16384"," 32768"," 65536","131072"};
int num_color[maxn]={15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15}; // 数字的颜色(这里都是白色,可以根据个人喜好调改 qwq) 
int num_back[maxn]={15,7,8,10,10,2,3,11,11,9,1,1,5,5,5,13,13,0}; // 数字对应的方块的颜色 qwq 
int num_score[maxn]={0,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072};
int a[maxn],b[maxn],c[maxn][maxn];
int best_square,score;
inline void place_num(){ // 输出位置赋值 + (初始化) qwq 
    best_square=0,score=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            num[i][j]=0; // 表格清零 qwq 
            place[i][j].x=(i-1)*4+8;
            place[i][j].y=(j-1)*4+1.5;
        }
    }
}
inline bool move(int dir){ // 移动方块(重要)qwq 
    if(dir==0) return false; // 没有指令操作时,直接返回 false(下一步) qwq 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            c[i][j]=num[i][j]; // 记录此步情况 qwq 
        }
    }
    if(dir==1){ // 1: 向上移 qwq  
        for(int j=1;j<=n;j++){ // 对于每一列 qwq 
            int len=0,len2=0;
            for(int i=1;i<=n;i++){
                if(num[i][j]) a[++len]=num[i][j];
            }
            for(int i=1;i<=len;i++){
                if(a[i]){
                    if(a[i]==a[i+1]) a[i+1]=0,b[++len2]=a[i]+1,score+=num_score[b[len2]];
                    else b[++len2]=a[i];
                }
            }
            for(int i=1;i<=len2;i++) num[i][j]=b[i];
            for(int i=len2+1;i<=n;i++) num[i][j]=0;
            for(int i=1;i<=n;i++) a[i]=0,b[i]=0; // 初始化 a,b 数组 qwq 
        }
    }
    if(dir==2){ // 2: 向下移 qwq  
        for(int j=1;j<=n;j++){ // 对于每一列 qwq 
            int len=0,len2=0;
            for(int i=n;i>=1;i--){
                if(num[i][j]) a[++len]=num[i][j];
            }
            for(int i=1;i<=len;i++){
                if(a[i]){
                    if(a[i]==a[i+1]) a[i+1]=0,b[++len2]=a[i]+1,score+=num_score[b[len2]];
                    else b[++len2]=a[i];
                }
            }
            for(int i=n;i>n-len2;i--) num[i][j]=b[n-i+1];
            for(int i=n-len2;i>=1;i--) num[i][j]=0;
            for(int i=1;i<=n;i++) a[i]=0,b[i]=0; // 同位同上 qwq 
        }
    }
    if(dir==3){ // 3: 向左移 qwq  
        for(int i=1;i<=n;i++){ // 对于每一行 qwq 
            int len=0,len2=0;
            for(int j=1;j<=n;j++){
                if(num[i][j]) a[++len]=num[i][j];
            }
            for(int j=1;j<=len;j++){
                if(a[j]){
                    if(a[j]==a[j+1]) a[j+1]=0,b[++len2]=a[j]+1,score+=num_score[b[len2]];
                    else b[++len2]=a[j];
                }
            }
            for(int j=1;j<=len2;j++) num[i][j]=b[j];
            for(int j=len2+1;j<=n;j++) num[i][j]=0;
            for(int j=1;j<=n;j++) a[j]=0,b[j]=0; 
        }
    }
    if(dir==4){ // 4: 向右移 qwq  
        for(int i=1;i<=n;i++){ // 对于每一行 qwq 
            int len=0,len2=0;
            for(int j=n;j>=1;j--){
                if(num[i][j]) a[++len]=num[i][j];
            }
            for(int j=1;j<=len;j++){
                if(a[j]){
                    if(a[j]==a[j+1]) a[j+1]=0,b[++len2]=a[j]+1,score+=num_score[b[len2]];
                    else b[++len2]=a[j];
                }
            }
            for(int j=n;j>n-len2;j--) num[i][j]=b[n-j+1];
            for(int j=n-len2;j>=1;j--) num[i][j]=0;
            for(int j=1;j<=n;j++) a[j]=0,b[j]=0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dir==5&&num[i][j]<=2) num[i][j]=0; // 外挂!(清除所有的 2和 4 )qwq 
            best_square=max(best_square,num[i][j]); // 记录最大方块 qwq 
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(c[i][j]!=num[i][j]) return true; // (重要) 用来对是否 print_num() 进行判断 (while()中的条件) qwq 
        }
    }
    return false;
}
inline int move_direction(){ // 移动方向判断 qwq 
    int t=0; 
    if(GetAsyncKeyState(VK_UP)||GetAsyncKeyState('W')) t=1;
    if(GetAsyncKeyState(VK_DOWN)||GetAsyncKeyState('S')) t=2;
    if(GetAsyncKeyState(VK_LEFT)||GetAsyncKeyState('A')) t=3;
    if(GetAsyncKeyState(VK_RIGHT)||GetAsyncKeyState('D')) t=4;
    if(GetAsyncKeyState('M')) t=5; // M键:外挂!qwq 
    return t;
}
inline void make_num(){ // 随机生成 2或 4 qwq 
    int x,y,z;
    do{
        x=rand()%n+1;
        y=rand()%n+1;
    } while(num[x][y]);
    z=rand()%100+1;
    num[x][y]=(z<=model?1:0)+1; // 生成4的概率为 model%(model=10)(标准值:10% )qwq 
    return ;
}
inline void print_num(){ // (重要) 打印方块(方格) qwq 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=0;k<n-1;k++){
                Setpos(place[i][j].x+k,place[i][j].y);
                Color(num_color[num[i][j]],num_back[num[i][j]]);
                if(k!=1) printf("      ");
                else cout<<number[num[i][j]];
            }
        }
    } 
    return ;
}
inline void print_2048(){ // 2048页面 qwq 
    for(int i=0;i<xls.length();i++){ // 打印表格 qwq 
        if(xls[i]!='\n'&&xls[i]!=' ') Color(7,15);
        else if(xls[i]==' '&&xls[i-1]!='\n') Color(0,15);
        else Color(0,15);
        cout<<xls[i];
    }
    for(int i=1;i<=5;i++){ // 打印2048标志物 qwq 
        Setpos(i,1);
        Color(15,num_back[11]);
        printf("          ");
    }
    Setpos(3,1);
    printf("   2048   "); // 2048 qwq 
    Setpos(1,7);
    Color(0,15);
    printf("  最大合成    分数");
    return ;
}
inline void print_score(){
    Setpos(3,8.5);
    if(best_square){
        Color(num_back[best_square],15);
        cout<<number[best_square];
    } // 处理最大合成数目的颜色 qwq  
    else{
        Color(0,15);
        printf("   0  ");
    }
    Color(0,15);
    cout<<"     "<<score;
    return ;
}
inline void test(){ // 调试颜色 + 测试 + 外挂 (去掉不影响游戏进行) qwq 
    num[1][1]=1,num[1][2]=2,num[1][3]=3,num[1][4]=4;
    num[2][1]=8,num[2][2]=7,num[2][3]=6,num[2][4]=5;
    num[3][1]=9,num[3][2]=10,num[3][3]=11,num[3][4]=12;
    num[4][1]=16,num[4][2]=15,num[4][3]=14,num[4][4]=13;
    return ;
}
inline int right(){ // 判定结束 qwq  
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(num[i][j]==num[i+1][j]||num[i][j]==num[i-1][j]||num[i][j]==num[i][j+1]||num[i][j]==num[i][j-1]) return true;
        }
    }
    return false;
}
inline bool over(){ // 结束函数 qwq 
    Sleep(2000);
    system("cls");
    Setpos(7,5);
    printf("Game Over");
    Sleep(3000);
    Setpos(10,6);
    cout<<"最大合成:";
    Color(num_back[best_square],15);
    cout<<number[best_square];
    Setpos(12,6);
    Color(0,15);
    cout<<"分数:"<<score;
    Setpos(16,3);
    cout<<"按R键重新开始,按E键退出";
    while(true){
        if(GetAsyncKeyState('R')) return true;
        if(GetAsyncKeyState('E')) return false;
    }
}
int main(){
    system("mode con cols=36 lines=26"); // ( cols:36 ,lines:26 )设置*.exe的长和宽 qwq 
    CONSOLE_CURSOR_INFO cursor_info={1,0}; // 不显示输入光标的指令语句 1 qwq 
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); // 不显示输入光标的指令语句 2 qwq 
    srand((unsigned)time(NULL)); // 随机性取数指针 qwq 
    system("color F0");
    title_();
    place_num();
    print_2048();
    make_num();
   //test();
    print_num();
    print_score();
    while(true){
        if(!right()){ // 当不能再移动时 qwq 
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    score+=num_score[num[i][j]]; // 结束统分 qwq 
                }
            }
            print_score(); // 显示最后分数 qwq 
            Sleep(2000);
            break;
        }
        if(!move(move_direction())) continue;
        Sleep(Speed/3);
        print_num();
        print_score();
        Sleep(Speed); // 移动与生成新方块之间的时间间隔 (细节) qwq  
        make_num();
        print_num();
    }
    if(over()) return main();
    return 0; // 这应该算是我退役前唯一能留下的作品了,两年的努力结晶与此。 
} // 再见

这是完整版。

觉得好就评论吧。