- 单臂大回旋(风车)式旋转
- 支持自定义方块
- 支持修改棋盘大小
- 暴肝一晚,码风混乱,欢迎拍砖/fad
###还有些bug
1判定问题:
一直旋转可能产生原力(卡过下落时间)…减缓掉落
2积分加速还没有严格测试,手太残了,没测出来
食用方式
编译生成.exe
同文件夹下放1.txt,并输入方块信息
4.23更新:下键加速下落
4.25更新:双缓存防闪屏
4.25更新1:修复结束不显示:Game over
参考资料:https://blog.csdn.net/oHanTanYanYing/article/details/72179593
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <windows.h>
#include <algorithm>
using namespace std;#define Col 14 //1,2,3,4最小公倍数 列 +2框
#define Row 20 //10层 行 +2#define min_col 0
#define min_row 0
#define max_col Col-1
#define max_row Row-1#define edge 3#define Max_long 5 //长
#define Max_width 5 //宽
#define Max_score_len 10
struct Shape
{int shape[Max_width][Max_long];int ture_long;int ture_width;int xx;int yy;int xx1; //旋转定位点 int yy1;int fig; //1,2,3,4 分别从初始逆时针
};
//0---
//---1
class Russia
{private:int score;int speed; //系统毫秒%speed=0时下落一节, speed =2000 - 200*(score%3) ||1000 int map[Row][Col]; //0未占用,1已占用 2下落块 edge画边界 int sum_shapes; //形状总数 HANDLE h[2];COORD coord;DWORD bytes;CONSOLE_CURSOR_INFO cci;int now_h;char *version;public:Shape *list;Russia();~Russia();void play(); //开始游戏int work(Shape); //回合运行 -1 game overvoid In_shapes(string); //输入形状 void display(); //展现棋盘 void check(int,int); //检查并修理 void draw(Shape &,int); //0清空,1填充 void draw2(Shape &,int); //填充2 int judge(Shape &,int ,int ,int); //新的中心位置,新的姿态 void new_display();void turn_char(char *);
};
Russia::Russia():version("修改信息:2020.4.25 by ssy9")
{CONSOLE_CURSOR_INFO cci = {1, 0};h[0] = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);h[1] = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);cci.bVisible = 0;cci.dwSize = 1;SetConsoleCursorInfo(h[0], &cci);SetConsoleCursorInfo(h[1], &cci);coord.Y = 0;coord.X = 0;bytes = 0;now_h = 0;memset(map,0,sizeof(map));for(int i=0;i<Row;i++){for(int j=0;j<Col;j++){if(i==0||j==0||i==Row-1||j==Col-1){map[i][j] = edge;}}}score = 0;
}Russia::~Russia()
{free(list);
}
void Russia::In_shapes(string fn)
{fn +='\0';ifstream file;file.open(fn.c_str(),ios::in);file>>this->sum_shapes;list = (Shape *)malloc(sizeof(Shape)*sum_shapes);for(int i=0;i<sum_shapes;i++){file>>(list[i].ture_long)>>(list[i].ture_width);for(int j=0;j<list[i].ture_width;j++){for(int k=0;k<list[i].ture_long;k++){file>>list[i].shape[j][k];}}}file.close();
}
void Russia::display()
{for(int i=0;i<Row;i++){for(int j=0;j<Col;j++){switch(map[i][j]){case 0:cout<<" ";break;case 1:case 2: cout<<"█";break;case edge:cout<<"※";break;}//cout<<map[i][j];}cout<<endl;}cout<<"-------------------------------------------"<<endl;cout<<"你的分数为:"<<score<<endl;
}void Russia::turn_char(char *p)
{int len = 1,tem=1;while(this->score/tem!=0){tem*=10;len++;}int top = 0;int tem_score = this->score;while(len--){tem/=10;if(tem==0)tem=1;p[top++]='0'+tem_score/tem;tem_score%=tem;}
}void Russia::new_display()
{coord.X = 0;coord.Y = 0;for(int i=0;i<Row;i++){char tem[(Col+5)*2];int tail = 0;memset(tem,0,sizeof(tem));for(int j=0;j<Col;j++){switch(map[i][j]){case 0:strcat(&tem[tail]," ");tail+=2;break;case 1:case 2: strcat(&tem[tail],"█");tail+=2;break;case edge:strcat(&tem[tail],"※");tail+=2;break;}//cout<<map[i][j];}coord.Y=i;WriteConsoleOutputCharacterA(h[now_h],&tem[0],strlen(tem),coord,&bytes);}//system("cls");//system("mode con cols=30 lines=26");SetConsoleActiveScreenBuffer(h[now_h]);coord.Y++;WriteConsoleOutputCharacterA(h[now_h],"--------------------",20,coord,&bytes);coord.Y++;char name[Max_score_len+10] = "score: ";turn_char(&name[7]);WriteConsoleOutputCharacterA(h[now_h],name,strlen(name),coord,&bytes);coord.Y+=3;WriteConsoleOutputCharacterA(h[now_h],version,strlen(version),coord,&bytes);Sleep(100);now_h=(now_h+1)%2;
}void Russia::play()
{while(1){//计算速度speed = 1000 - 100*(score/2);if(speed<30)speed = 30; //此处修改速度int rand_shape = rand()%sum_shapes;if(work(list[rand_shape])==-1){coord.Y=1;coord.X=Col*2+3;WriteConsoleOutputCharacterA(h[(now_h+1)%2],"Game over",9,coord,&bytes); //cout<<"score:"<<score<<endl;//cout<<"Game over"<<endl;system("pause");return;}}
}
void Russia::check(int top,int bottom) //top<=bottom
{for(int i=top;i<=bottom;i++){int jud = 1;for(int j=1;j<=Col-2;j++){if(map[i][j]==0){jud = 0; //不能清理 }}if(jud == 1){score++;for(int j=i-1;j>=1;j--){int jud1=0; //全0标记 for(int k=1;k<=Col-2;k++){map[j+1][k] = map[j][k];jud1=(jud1|map[j+1][k]);}if(jud == 0) //全是0 复制完毕 {break;}}}}
}
void Russia::draw(Shape &now_shape,int tar)
{switch(now_shape.fig){case 1:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[now_shape.yy+j][now_shape.xx+i]!=1)map[now_shape.yy+j][now_shape.xx+i] = ((now_shape.shape[j][i]&tar));}}break;case 2:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[now_shape.yy-i][now_shape.xx+j]!=1)map[now_shape.yy-i][now_shape.xx+j] = ((now_shape.shape[j][i]&tar));}}break;case 3:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[now_shape.yy-j][now_shape.xx-i]!=1)map[now_shape.yy-j][now_shape.xx-i] = ((now_shape.shape[j][i]&tar)); //}} break;case 4:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[now_shape.yy+i][now_shape.xx-j]!=1)map[now_shape.yy+i][now_shape.xx-j] = ((now_shape.shape[j][i]&tar));}} break; }
}
void Russia::draw2(Shape &now_shape,int tar)
{switch(now_shape.fig){case 1:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(tar==0){if(map[now_shape.yy+j][now_shape.xx+i]==2)map[now_shape.yy+j][now_shape.xx+i]=0;}if(tar==1){if(map[now_shape.yy+j][now_shape.xx+i]==0)map[now_shape.yy+j][now_shape.xx+i] = ((now_shape.shape[j][i]&tar)<<1);}}}break;case 2:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(tar==1)if(map[now_shape.yy-i][now_shape.xx+j]==0)map[now_shape.yy-i][now_shape.xx+j] = ((now_shape.shape[j][i]&tar)<<1);if(tar==0)if(map[now_shape.yy-i][now_shape.xx+j]==2)map[now_shape.yy-i][now_shape.xx+j]=0;}}break;case 3:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(tar==1)if(map[now_shape.yy-j][now_shape.xx-i]==0)map[now_shape.yy-j][now_shape.xx-i] = ((now_shape.shape[j][i]&tar)<<1); //if(tar==0)if(map[now_shape.yy-j][now_shape.xx-i]==2)map[now_shape.yy-j][now_shape.xx-i]=0;}} break;case 4:for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(tar==1)if(map[now_shape.yy+i][now_shape.xx-j]==0)map[now_shape.yy+i][now_shape.xx-j] = ((now_shape.shape[j][i]&tar)<<1);if(tar==0)if(map[now_shape.yy+i][now_shape.xx-j]==2)map[now_shape.yy+i][now_shape.xx-j]=0;}} break; }
}
int Russia::judge(Shape &now_shape,int new_x,int new_y,int new_fig)
{switch(new_fig){case 1:if(new_x<=0||new_x>=Col-1||new_y<=0||new_y>=Row-1)return 0; //是否越界 if((new_x+now_shape.ture_long-1>=max_col)||(new_y+now_shape.ture_width-1>=max_row))return 0;for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[new_y+j][new_x+i]&now_shape.shape[j][i]) //是否重合 return 0;}}return 1;break;case 2:if(new_x<=0||new_x>=Col-1||new_y<=0||new_y>=Row-1)return 0;if((new_x+now_shape.ture_width-1>=max_col)||(new_y-now_shape.ture_long+1<=min_row))return 0;for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){//cout<<(map[new_y-i][new_x+j]&now_shape.shape[j][i])<<endl;if((map[new_y-i][new_x+j]&now_shape.shape[j][i])==1)return 0;}}return 1;break;case 3:if(new_x<=0||new_x>=Col-1||new_y<=0||new_y>=Row-1)return 0;if((new_x-now_shape.ture_long+1<=min_col)||(new_y-now_shape.ture_width+1<=min_row))return 0;for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[new_y-j][new_x-i]&now_shape.shape[j][i]) //return 0;}} return 1;break;case 4:if(new_x<=0||new_x>=Col-1||new_y<=0||new_y>=Row-1)return 0;if((new_x-now_shape.ture_width+1<=min_col)||(new_y+now_shape.ture_long-1>=max_row))return 0;for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if(map[new_y+i][new_x-j]&now_shape.shape[j][i])return 0;}} return 1;break; }
}
int Russia::work(Shape now_shape)
{//初始化位置 now_shape.yy=1;now_shape.xx=1+rand()%(Col-2-now_shape.ture_long);now_shape.yy1=now_shape.ture_width;now_shape.xx1=now_shape.xx+now_shape.ture_long-1;now_shape.fig=1;//检查该位置是否重合for(int i=0;i<now_shape.ture_long;i++){for(int j=0;j<now_shape.ture_width;j++){if((map[j+now_shape.yy][i+now_shape.xx]&now_shape.shape[j][i])==1) //重合不合法 {/*system("cls");cout<<"score:"<<score<<endl;cout<<"Game over"<<endl;system("pause");*/return -1;}}}while(clock()%speed!=0){}//基准时间 while(clock()%speed==0){}draw2(now_shape,1);//system("cls");new_display();//开始下落int drop_faster = 0;int last_clock=0;while(1){if((clock()%speed<=50&&last_clock==1)||drop_faster==1) //下落 {drop_faster = 0;//判断能不能落if(judge(now_shape,now_shape.xx,now_shape.yy+1,now_shape.fig)==1)//能落 {draw2(now_shape,0); //清空now_shape.yy++; //下降draw2(now_shape,1); //填补//system("cls");new_display(); }else{draw(now_shape,0);draw(now_shape,1);//system("cls");new_display(); break;}}else //显示并读取键盘状态 {if(clock()%speed!=0){last_clock = 1; //更新flag }int last_state = 0;if(GetKeyState(38)<0&&last_state==0) //逆时针旋转 {last_state = 1; //更新状态 int ttem=now_shape.fig%4+1;if(judge(now_shape,now_shape.xx,now_shape.yy,ttem)==1){draw2(now_shape,0); //清空now_shape.fig=ttem;draw2(now_shape,1); //填补//system("cls");new_display(); } }if(GetKeyState(37)<0&&last_state==0) //左{last_state = 1; //更新状态 if(judge(now_shape,now_shape.xx-1,now_shape.yy,now_shape.fig)==1){draw2(now_shape,0); //清空now_shape.xx--;draw2(now_shape,1); //填补//system("cls");new_display(); } }if(GetKeyState(39)<0&&last_state==0) //右 {last_state = 1; //更新状态 if(judge(now_shape,now_shape.xx+1,now_shape.yy,now_shape.fig)==1){draw2(now_shape,0); //清空now_shape.xx++;draw2(now_shape,1); //填补//system("cls");new_display(); } }if(GetKeyState(40)<0&&last_state==0){last_state=1;drop_faster = 1;}}} check(min_row+1,max_row-1);return 1;
}Russia russia;
int main()
{//system("mode con cols=30 lines=26");//SetConsoleTitle("俄罗斯方块 by ssy9"); srand(time(0));russia.In_shapes("1.txt");russia.play();return 0;
}
补充说明:
从1.txt里读取方块数据
一个方块数
每个方块长 宽
1,0表示占位
例:可以直接拷贝进1.txt食用:
10
4 2
1 1 1 1
1 0 0 1
4 1
1 1 1 1
4 2
1 1 1 1
0 0 0 1
3 2
1 1 0
0 1 1
2 2
1 1
0 1
2 2
1 0
1 1
2 2
1 1
1 1
3 3
1 1 0
0 1 1
0 0 1
3 3
1 1 1
1 0 1
1 1 1
3 3
1 1 1
1 1 0
1 0 0
其余内容见:https://www.jianshu.com/p/6d9732872d0b