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; // 这应该算是我退役前唯一能留下的作品了,两年的努力结晶与此。
} // 再见
这是完整版。
觉得好就评论吧。