摘自@

#include<bits/stdc++.h>
#include<windows.h>
#include <conio.h>
using namespace std;

int gz[6][6];
int ppdd=0;
int jf=0,maxjf;
// 从第二个代码提取的显示函数
map<int,int>col;
int maxn,n=4;

int wcnt(int x){
    int cnt=0;
    while(x>0){
        ++cnt;
        x/=10;
    }
    return cnt;
}

void mid(int x,int d){
    if(x==0){
        cout<<"          ";
        return;
    }
    int w=wcnt(x);
    if((d-w)%2){
        for(int i=1;i<=(d-w)/2+1;i++){
            cout<<" ";
        }
    }else{
        for(int i=1;i<=(d-w)/2;i++){
            cout<<" ";
        }
    }
    cout<<x;
    for(int i=1;i<=(d-w)/2;i++){
        cout<<" ";
    }
}

void out(string s,int id=7,int tim=0){
    HANDLE handle=::GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(handle,&info);
    WORD colorBak=info.wAttributes;
    SetConsoleTextAttribute(handle,id);
    for(int i=0;i<(int)s.size();i++){
        cout<<s[i];
        if(tim>0) Sleep(tim);
    }
    SetConsoleTextAttribute(handle,colorBak);
}
void saveJF() {
    std::ofstream file("maxjf.txt");
    file << maxjf;
    file.close();
}
// 读取
void loadJF() {
    std::ifstream file("maxjf.txt");
    if (!file >> maxjf) {
		std::cout << "存档不存在,maxjf = 0" << std::endl;
    }else file >> maxjf;
    file.close();
}
void initColors(){
    col[0]=0;  // 空位置
    col[2]=3;
    col[4]=4;
    col[8]=6;
    col[16]=7;
    col[32]=8;
    col[64]=10;
    col[128]=11;
    col[256]=12;
    col[512]=14;
    col[1024]=3;
    col[2048]=4;
    col[4096]=6;
    col[8192]=7;
    col[16384]=8;
    col[32768]=10;
    col[65536]=11;
    col[131072]=12;
    col[262144]=14;
    col[524288]=3;
    col[1048576]=4;
}

// 完全复制第二个代码的print函数,只做最小修改
void printGameBoard(){
    system("cls");
    HANDLE handle=::GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(handle,&info);
    WORD colorBak=info.wAttributes;
    
    // 重新计算最大数字位数
    maxn = 0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            maxn=max(maxn,wcnt(gz[i][j]));
    
    // 完全按照第二个代码的显示逻辑
    out("                                                  \n",0xff);
    
    for(int i=1;i<=n;i++){
        for(int r=1;r<=5;r++){
            for(int j=1;j<=n;j++){
                SetConsoleTextAttribute(handle,16*col[gz[i][j]]);
                out("  ",0xff);
                if(r==3){
                    mid(gz[i][j],10);
                } else {
                    cout<<"          ";
                }
                SetConsoleTextAttribute(handle,colorBak);
            }
            out("  ",0xff);
            cout<<"\n";
        }
        out("                                                  \n",0xff);
    }
    
    SetConsoleTextAttribute(handle, colorBak);
}

bool IsKeyDown(int keyCode) {
    return (GetAsyncKeyState(keyCode) & 0x8000) != 0;
}

bool js(){	
for(int i=1;i<5;i++){
	for(int j=1;j<5;j++){		
		for(int jb=0;jb<4;jb++){
			if(gz[i-1][j]==0){
				return true;
			}else if(gz[i-1][j]==gz[i][j]&&gz[i-1][j]!=-1){
				return true;
			}
		}
	}
}
for(int i=4;i>=1;i--){
	for(int j=1;j<5;j++){	
		for(int jb=0;jb<4;jb++){
			if(gz[i+1][j]==0){
				return true;
			}else if(gz[i+1][j]==gz[i][j]&&gz[i+1][j]!=-1){
				return true;
			}
		}
	}
}
for(int i=1;i<5;i++){
	for(int j=1;j<5;j++){	
		for(int jb=0;jb<4;jb++){
			if(gz[i][j-1]==0){
				return true;
			}else if(gz[i][j-1]==gz[i][j]&&gz[i][j-1]!=-1){
				return true;
			}
		}
	}
}
for(int i=1;i<5;i++){
	for(int j=4;j>=1;j--){
		for(int jb=0;jb<4;jb++){
			if(gz[i][j+1]==0){
				return true;
			}else if(gz[i][j+1]==gz[i][j]&&gz[i][j+1]!=-1){
				return true;
			}
		}
	}
}
	return false;	
} 

void csh2048(){
	for(int i=0;i<6;i++){
		for(int j=0;j<6;j++){
			gz[i][j]=-1;
		}
	}
	for(int i=1;i<5;i++){
		for(int j=1;j<5;j++){
			gz[i][j]=0;
		}
	}
}

int main(){
	loadJF();
	bool pd2=true;
	srand(time(0));
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    initColors();
	while(1){
		system("cls");
		csh2048(); 
		if(true){
            // 使用彩色标题
            out("                                                  \n", 0xff);
            out("          ", 7);
            out("2", 12);
            out("0", 10);
            out("4", 9);
            out("8", 11);
            out("  GAME              \n", 7);
            out("                                                  \n", 0xff);
		}
		cout<<"当前记录积分:"<<maxjf<<endl;
		char c;
		cout<<"开始y不玩n"<<endl;
		cin>>c;
		if(c=='n'){
			cout<<"感谢游玩";
			Sleep(1000);
			return 0;
		}else{
			cout<<"4*4模式(作者太蠢,只会4*4)";
			Sleep(1000);
			system("cls");
			cout<<"是"; Sleep(60);cout<<"否"; Sleep(60);cout<<"看"; Sleep(60);cout<<"操"; Sleep(60);cout<<"作"; Sleep(60);cout<<"提"; Sleep(60);cout<<"示"; Sleep(60);cout<<"?"; Sleep(60);cout<<endl; cout<<"是"; Sleep(60);cout<<"y"; Sleep(60);cout<<"否"; Sleep(60);cout<<"n"; Sleep(60);
			cin>>c;
			if(c=='y'){
				cout<<"上下左右分别对应键盘右下方的四个箭头↑↓←→\n";
				Sleep(700);
				cout<<"按任意键继续..."<<endl;
				_getch();
			} 
			cout<<"游戏开始!!!\n";
			Sleep(500); 
			system("cls");
			jf=0;
			while(1){
				//准备工作--------------------------------------------------------------- 
				int b[16],e=0,h=0,x,y,maxe=0,n;
				for(int i=1;i<5;i++){
					for(int j=1;j<5;j++){
						maxe=max(maxe,gz[i][j]);
						h++;
						if(gz[i][j]==0){
							b[e]=h;
							e++;
						}
					}
				}
				if(maxe==2048){
                    printGameBoard();
                    HANDLE handle=::GetStdHandle(STD_OUTPUT_HANDLE);
                    CONSOLE_SCREEN_BUFFER_INFO info;
                    GetConsoleScreenBufferInfo(handle,&info);
                    WORD colorBak=info.wAttributes;
                    SetConsoleTextAttribute(handle, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
					cout<<"You Win!!!"<<endl;
                    SetConsoleTextAttribute(handle, colorBak);
					cout<<"积分:"<<jf<<endl;
					maxjf=max(maxjf,jf);
                    cout<<"按任意键返回主菜单..."<<endl;
                    _getch();
					break; 
				}
				int random_number;
				if(e==1){
					random_number=0;
				} else{
					n=rand()%(e+1);
					n=rand()%(e+1);
					n=rand()%(e-1)+1;
					random_number=n;
				}
				
				if(true){
					if(b[random_number]==1){
						x=1;y=1;
					}if(b[random_number]==2){
						x=1;y=2;
					}if(b[random_number]==3){
						x=1;y=3;
					}if(b[random_number]==4){
						x=1;y=4;
					}if(b[random_number]==5){
						x=2;y=1;
					}if(b[random_number]==6){
						x=2;y=2;
					}if(b[random_number]==7){
						x=2;y=3;
					}if(b[random_number]==8){
						x=2;y=4;
					}if(b[random_number]==9){
						x=3;y=1;
					}if(b[random_number]==10){
						x=3;y=2;
					}if(b[random_number]==11){
						x=3;y=3;
					}if(b[random_number]==12){
						x=3;y=4;
					}if(b[random_number]==13){
						x=4;y=1;
					}if(b[random_number]==14){
						x=4;y=2;
					}if(b[random_number]==15){
						x=4;y=3;
					}if(b[random_number]==16){
						x=4;y=4;
					}
				}
				int p[3]={1,2,4},sc,sc1;
				if(true){
						sc1=rand()%6;
						sc1=rand()%6;
						sc1=rand()%4+1;
				}
				if(sc1<=3)sc1=2;
				if(sc1>3&&sc<=4)sc1=3;
				sc=p[sc1-1];
				if(pd2==true){
					gz[x][y]=sc;
				}else{
					pd2=true;
				}
				
				// 使用新的方块效果打印游戏板
				printGameBoard();
				
				// 在"墙"下面显示积分
                cout<<"积分:"<<jf<<"  最高记录:"<<maxjf<<endl;
                cout<<"使用方向键移动 (↑↓←→)"<<endl;
				
				if(js()==false){
                    printGameBoard();
                    HANDLE handle2=::GetStdHandle(STD_OUTPUT_HANDLE);
                    CONSOLE_SCREEN_BUFFER_INFO info2;
                    GetConsoleScreenBufferInfo(handle2,&info2);
                    WORD colorBak2=info2.wAttributes;
                    SetConsoleTextAttribute(handle2, FOREGROUND_RED | FOREGROUND_INTENSITY);
					cout<<"WA!"<<endl;
                    SetConsoleTextAttribute(handle2, colorBak2);
					cout<<"积分:"<<jf<<endl;
					maxjf=max(maxjf,jf);
					saveJF();
                    cout<<"按任意键返回主菜单..."<<endl;
                    _getch();
					break; 
				}
				bool cs;
				cs=true;
				char ch;
				if (_kbhit()) { 
            		ch = _getch();
            		switch (ch) {
                		case 72:{
                			for(int i=1;i<5;i++){
								for(int j=1;j<5;j++){
									bool pd=true;
									int x1=i,y1=j;
									for(int jb=0;jb<4;jb++){
										if(gz[x1-1][y1]==0){
											cs=false;
											ppdd=1;
											gz[x1-1][y1]=gz[x1][y1];
											gz[x1][y1]=0;
											x1--;
										}else if(gz[x1-1][y1]==gz[x1][y1]&&pd==true&&gz[x1-1][y1]!=-1){
											cs=false;
											ppdd=1;
											gz[x1-1][y1]*=2;
											jf+=gz[x1-1][y1];
											gz[x1][y1]=0;
											pd=false;
											x1--;
										}
									}
								}
							}
							break;
						}
               			case 80:{
               			for(int i=4;i>=1;i--){
							for(int j=1;j<5;j++){
								bool pd=true;
								int x1=i,y1=j;
								for(int jb=0;jb<4;jb++){
									if(gz[x1+1][y1]==0){
										cs=false;
										ppdd=1;
										gz[x1+1][y1]=gz[x1][y1];
										gz[x1][y1]=0;
										x1++;
									}else if(gz[x1+1][y1]==gz[x1][y1]&&pd==true&&gz[x1+1][y1]!=-1){
										cs=false;
										ppdd=1;
										gz[x1+1][y1]*=2;
										gz[x1][y1]=0;
										jf+=gz[x1+1][y1];
										pd=false;
										x1++;
									}
								}
							}
						}
               				break;
               			}
              	  		case 75:{
              	  				for(int i=1;i<5;i++){
									for(int j=1;j<5;j++){
										bool pd=true;
										int x1=i,y1=j;
										for(int jb=0;jb<4;jb++){
											if(gz[x1][y1-1]==0){
												cs=false;
												ppdd=1;
												gz[x1][y1-1]=gz[x1][y1];
												gz[x1][y1]=0;
												y1--;
											}else if(gz[x1][y1-1]==gz[x1][y1]&&pd==true&&gz[x1][y1-1]!=-1){
												cs=false;
												ppdd=1;
												gz[x1][y1-1]*=2;
												gz[x1][y1]=0;
												pd=false;
												jf+=gz[x1][y1-1];
												y1--;
											}
										}
									}
								}
							break;
						}
              	  		case 77:{
              	  			for(int i=1;i<5;i++){
								for(int j=4;j>=1;j--){
									bool pd=true;
									int x1=i,y1=j;
									for(int jb=0;jb<4;jb++){
										if(gz[x1][y1+1]==0){
											cs=false;
											ppdd=1;
											gz[x1][y1+1]=gz[x1][y1];
											gz[x1][y1]=0;
											y1++;
										}else if(gz[x1][y1+1]==gz[x1][y1]&&pd==true&&gz[x1][y1+1]!=-1){
											cs=false;
											ppdd=1;
											gz[x1][y1+1]*=2;
											gz[x1][y1]=0;
											jf+=gz[x1][y1+1];
											pd=false;
											y1++;
										}
									}
								}
							}
							break;
						}
            		}
        		}
				if(cs==true){
					if(ppdd==0){
						cout<<"无法移动,换个方向试试"<<endl;
					}pd2=false;
					ppdd=0;
					_getch();
					continue;
				}
			}
		}
	} 
}