// 这个俄罗斯方块游戏,唯一的难点就是:任意个方块能组成多少个可旋转可移动的不同图形
//一般应用练习按键【多开】。
#include<Windows.h>
#include<stdio.h>
#include<ddraw.h>
#pragma comment(lib,"ddraw.lib")
#define nof(a) (sizeof(a)/sizeof(*a))
#define err {printf("%s(%i):\n",__FILE__,__LINE__),::ExitProcess(0);}
#define err0(v) if(!v){printf("%s(%i):\n",__FILE__,__LINE__),::ExitProcess(0);}
#define call(fun) if(fun){printf("%s(%i):\n",__FILE__,__LINE__),::ExitProcess(0);}
#define outi(i) printf("%s=%i=0x%X \n",#i,i,i)
#define outs(s) printf("%s=%s= \n",#s,s)
#define nof(a) (sizeof(a)/sizeof(*a))
#define cmpb(i,n) (unsigned(i)<unsigned(n))
#define cmpbe(i,n) (unsigned(i)<=unsigned(n))
#define cmpa(i,n) (unsigned(i)>unsigned(n))
#define get_time ::GetTickCount
int main();
int WINAPI WinMain (HINSTANCE,HINSTANCE,LPSTR,int){
return main();
}
LRESULT (CALLBACK window_proc)(HWND, UINT, WPARAM, LPARAM){
return 1;
}
struct xy{
int x;
int y;
xy(){
}
xy(int m){
x=m;
y=m;
}
xy(int x,int y){
this->x=x;
this->y=y;
}
xy operator *(xy&m){return xy(x *m.x,y *m.y);}
xy operator /(xy&m){return xy(x /m.x,y /m.y);}
xy operator %(xy&m){return xy(x %m.x,y %m.y);}
xy operator (xy&m){return xy(x m.x,y m.y);}
xy operator -(xy&m){return xy(x -m.x,y -m.y);}
xy operator <<(xy&m){return xy(x<<m.x,y<<m.y);}
xy operator >>(xy&m){return xy(x>>m.x,y>>m.y);}
xy operator &(xy&m){return xy(x &m.x,y &m.y);}
xy operator |(xy&m){return xy(x |m.x,y |m.y);}
xy operator ^(xy&m){return xy(x ^m.x,y ^m.y);}
xy operator *=(xy&m){x *=m.x;y *=m.y;return *this;}
xy operator /=(xy&m){x /=m.x;y /=m.y;return *this;}
xy operator %=(xy&m){x %=m.x;y %=m.y;return *this;}
xy operator =(xy&m){x =m.x;y =m.y;return *this;}
xy operator -=(xy&m){x -=m.x;y -=m.y;return *this;}
xy operator <<=(xy&m){x<<=m.x;y<<=m.y;return *this;}
xy operator >>=(xy&m){x>>=m.x;y>>=m.y;return *this;}
xy operator &=(xy&m){x &=m.x;y &=m.y;return *this;}
xy operator |=(xy&m){x |=m.x;y |=m.y;return *this;}
xy operator ^=(xy&m){x ^=m.x;y ^=m.y;return *this;}
xy operator *(int m){return xy(x *m,y *m);}
xy operator /(int m){return xy(x /m,y /m);}
xy operator %(int m){return xy(x %m,y %m);}
xy operator (int m){return xy(x m,y m);}
xy operator -(int m){return xy(x -m,y -m);}
xy operator <<(int m){return xy(x<<m,y<<m);}
xy operator >>(int m){return xy(x>>m,y>>m);}
xy operator &(int m){return xy(x &m,y &m);}
xy operator |(int m){return xy(x |m,y |m);}
xy operator ^(int m){return xy(x ^m,y ^m);}
xy operator *=(int m){x *=m;y *=m;return *this;}
xy operator /=(int m){x /=m;y /=m;return *this;}
xy operator %=(int m){x %=m;y %=m;return *this;}
xy operator =(int m){x =m;y =m;return *this;}
xy operator -=(int m){x -=m;y -=m;return *this;}
xy operator <<=(int m){x<<=m;y<<=m;return *this;}
xy operator >>=(int m){x>>=m;y>>=m;return *this;}
xy operator &=(int m){x &=m;y &=m;return *this;}
xy operator |=(int m){x |=m;y |=m;return *this;}
xy operator ^=(int m){x ^=m;y ^=m;return *this;}
bool operator <(xy&m){return((unsigned(x) <unsigned(m.x))&&(unsigned(y) <unsigned(m.y)));}
bool operator >(xy&m){return((unsigned(x) >unsigned(m.x))&&(unsigned(y) >unsigned(m.y)));}
bool operator <=(xy&m){return((unsigned(x)<=unsigned(m.x))&&(unsigned(y)<=unsigned(m.y)));}
bool operator >=(xy&m){return((unsigned(x)>=unsigned(m.x))&&(unsigned(y)>=unsigned(m.y)));}
bool operator ==(xy&m){return((unsigned(x)==unsigned(m.x))&&(unsigned(y)==unsigned(m.y)));}
bool operator <(int m){return((unsigned(x) <unsigned(m))&&(unsigned(y) <unsigned(m)));}
bool operator >(int m){return((unsigned(x) >unsigned(m))&&(unsigned(y) >unsigned(m)));}
bool operator <=(int m){return((unsigned(x)<=unsigned(m))&&(unsigned(y)<=unsigned(m)));}
bool operator >=(int m){return((unsigned(x)>=unsigned(m))&&(unsigned(y)>=unsigned(m)));}
bool operator ==(int m){return((unsigned(x)==unsigned(m))&&(unsigned(y)==unsigned(m)));}
xy operator !(){return xy( !x, !y);}
xy operator ~(){return xy( ~x, ~y);}
xy operator (){return xy( x, y);}
xy operator -(){return xy( -x, -y);}
xy get_number(){
xy m=0;
if(x>0)m.x= x;if(x<0)m.x=-x;
if(y>0)m.y= y;if(y<0)m.y=-y;
return m;
}
xy get_flag(){
xy m=0;
if(x>0)m.x= 1;if(x<0)m.x=-1;
if(y>0)m.y= 1;if(y<0)m.y=-1;
return m;
}
void x_y(){
int v=x;x=y;y=v;
}
int xx(){return x*x;}
int yy(){return y*y;}
int xx_yy(){
return (x*x y*y);
}
xy operator =(xy&m){
x=m.x;
y=m.y;
return *this;
}
xy operator =(int m){
x=m;
y=m;
return *this;
}
xy operator (int){
xy temp=*this;
x;
y;
return temp;
}
xy operator (){
x ;
y ;
return *this;
}
xy operator --(int){
xy temp=*this;
--x;
--y;
return temp;
}
xy operator --(){
x--;
y--;
return *this;
}
};
// 妄想扣篮的男人
// 俄罗斯方块
// 任意个方块能组成多少个可旋转可移动的不同图形
const int dm=4;
xy da[0x1000][dm];
int dn=0;
void da_get(xy*sa,int sn){
if(sn<dm){
for(int si=0;si<sn;si ){
static xy a4[]={
xy(0, 1),
xy(-1,0), xy( 1,0),
xy(0,-1),
};
for(int i=0;i<nof(a4);i ){
xy s=sa[si] a4[i];
for(int n=0;1;n ){
if(n<sn){
if(s==sa[n])break;
}else{
sa[sn]=s;
da_get(sa,sn 1);
break;
}
}
}
}
}else{
xy ta[dm];
for(int i=0;i<dm;i )ta[i]=sa[i];
int have=0;
for(int index=0;index<4;index ){
for(int i=0;i<dm;i ){// rotate
int x=ta[i].x;
int y=ta[i].y;
ta[i].x=y;
ta[i].y=-x;
}
{
xy m=xy(12341234,12341234);
for(int i=0;i<dm;i ){// move
if(m.x>ta[i].x)m.x=ta[i].x;
if(m.y>ta[i].y)m.y=ta[i].y;
}
for(int i=0;i<dm;i )ta[i]-=m;
}
for(int i=0;i<dm;i ){ // min_max
for(int n=i 1;n<dm;n ){
if((ta[i].y*dm ta[i].x)>(ta[n].y*dm ta[n].x)){
xy v=ta[i];
ta[i]=ta[n];
ta[n]=v;
}
}
}
for(int di=0;di<dn;di ){// find
int n=0;
for(;n<dm;n )if(da[di][n]==ta[n]){}else break;
if(n==dm){
have=1;
break;
}
}
if(have)break;
}
if(have==0){
for(int i=0;i<dm;i )da[dn][i]=ta[i];
if(dn<nof(da)){
dn ;
}else{
err;
}
}
}
}
void get_da(){
xy sa[dm];
int sn=0;
sa[sn ]=xy(0);
da_get(sa,sn);
for(int di=0;di<dn;di ){
printf("___________%i_______________\n",di 1);
char a[dm][dm]={};
for(int i=0;i<dm;i ){
int x=da[di][i].x;
int y=da[di][i].y;
if(0<=x&&x<dm){}else err;
if(0<=y&&y<dm){}else err;
a[y][x]=1;
}
for(int y=0;y<dm;y ){
for(int x=0;x<dm;x ){
if(a[y][x]){
printf("口");
}else printf(" ");
}
printf("\n");
}
}
}
struct xyr_t{
int x;
int y;
int r;
}xyr[4]={
{0,0,1},
{-1},{0,-1,},{ 1},
};
const int em=dm;
struct et{
int r;
xy o;
xy a[em];
xy b[em];
void get_b(){
for(int i=0;i<em;i )b[i]=a[i] o;
}
void change(xyr_t&m){
o =xy(m.x,m.y);
if(r&&m.r){
for(int i=0;i<em;i ){
xy m=a[i];
a[i]=xy(m.y,-m.x);
}
}
get_b();
}
}ea[nof(da)];
int en=0;
void get_ea(){
struct{int len;int i;} la[em],l;
for(int di=0;di<dn;di ){
for(int li=0;li<em;li ){
la[li].len=0;
la[li].i=li;
for(int ni=0;ni<em;ni ){
xy m=da[di][li]-da[di][ni];
if(m.x==0||m.y==0){
la[li].len =m.xx_yy();
}else{
la[li].len =m.xx_yy()*em;
}
}
}
for(int j=0;j<nof(la);j ){
for(int k=j 1;k<nof(la);k ){
if(la[j].len>la[k].len){
l=la[j];la[j]=la[k];la[k]=l;
}
}
}
ea[di].o=da[di][la[0].i];
if(em>2&&la[0].len==la[2].len){
ea[di].r=0;
}else{
ea[di].r=1;
}
for(int i=0;i<em;i )ea[di].a[i]=da[di][i]-ea[di].o;
}
en=dn;
////////////////
for(int ei=0;ei<en;ei ){
printf("___________%i_______________\n",ei 1);
char a[em][em]={};
for(int i=0;i<em;i ){
xy m=ea[ei].a[i] ea[ei].o;
int x=m.x;
int y=m.y;
if(0<=x&&x<em){}else err;
if(0<=y&&y<em){}else err;
if(ea[ei].r&&ea[ei].a[i]==xy(0)){
a[y][x]=2;
}else{
a[y][x]=1;
}
}
for(int y=0;y<em;y ){
for(int x=0;x<em;x ){
if(a[y][x]){
if(a[y][x]>1){
printf("中");
}else{
printf("口");
}
}else printf(" ");
}
printf("\n");
}
}
///////////////
}
const int fx=em*3;
const int fy=fx*2;
struct ft{
et e;
int a[fy][fx];
int n;
DWORD auto_time;
struct{
int v;
int pre;
int now;
}key[nof(xyr)];
void set_auto(){
auto_time=::GetTickCount() 1000;
}
void get_e(){
static int ei=-1;
e=ea[ei=(ei 1)%en];
set_auto();
for(int i=0;i<nof(xyr);i )key[i].pre=::GetAsyncKeyState(key[i].v)<0;
}
void init(){
get_e();
for(int x=0;x<fx;x )for(int y=0;y<fy;y )a[y][x]=0;
n=0;
//for(int x=0;x<fx;x )a[0][x]=1;
}
void change(xyr_t&m,int is_auto=0){
set_auto();
et t=e;
t.change(m);
int can=1;
for(int i=0;i<em;i ){
int x=t.b[i].x;
int y=t.b[i].y;
if(0<=x&&x<fx&&0<=y){
if(y<fy){
if(a[y][x]){can=0;break;}
}else{
}
}else{
{can=0;break;}
}
}
if(can){
e=t;
}else if(is_auto){;
int out=0;
for(int i=0;i<em;i ){
int x=e.b[i].x;
int y=e.b[i].y;
if(0<=x&&x<fx&&0<=y&&y<fy){
a[y][x]=1;
}else{
{out=1;break;}
}
}
if(out){
init();
}else{
int full_n=0;
int d=0;
for(int s=0;s<fy;s ){
int full=1;
for(int x=0;x<fx;x )if(a[s][x]==0){full=0;break;};
if(full){
full_n ;
}else{
for(int x=0;x<fx;x )a[d][x]=a[s][x];
d ;
}
}
for(;d<fy;d )for(int x=0;x<fx;x )a[d][x]=0;
if(full_n)n =1<<(full_n);
get_e();
}
}
}
void run(DWORD time){
for(int i=0;i<nof(xyr);i ){
key[i].now=::GetAsyncKeyState(key[i].v)<0;
int can=0;
if(i==2){
if(key[i].now)can=1;
}else{
if(key[i].pre&&!key[i].now)can=1;
}
if(can){
change(xyr[i]);
}
key[i].pre=key[i].now;
}
if(auto_time<time){
change(xyr[2],1);
}
}
}fa[2];
const int fn=nof(fa);
struct __init{__init(){
get_da();
get_ea();
for(int ei=0;ei<en;ei ){
ea[ei].o.x =fx/2-em/4;
ea[ei].o.y =fy;
ea[ei].get_b();
}
for(int ei=0;ei<en;ei ){
for(int i=0;i<em;i ){
int x=ea[ei].b[i].x;
int y=ea[ei].b[i].y;
if(0<=x&&x<fx&&0<=y){
}else{
err;
}
}
}
for(int fi=0;fi<fn;fi )fa[fi].init();
static int key[][nof(xyr)]={
{
{'W'},
{'A'},{'S'},{'D'},
},
{
{'I'},
{'J'},{'K'},{'L'},
},
{
{VK_UP},
{VK_LEFT},{VK_DOWN},{VK_RIGHT},
},
};
if(nof(key)<nof(fa))err;///////
for(int fi=0;fi<fn;fi ){
for(int i=0;i<nof(xyr);i )fa[fi].key[i].v=key[fi][i];
}
//////////////////////////////
}}
__init
;
HDC dc;
HBRUSH brush_all=::CreateSolidBrush(RGB(-1,-1,-1));
HBRUSH brush_back=::CreateSolidBrush(RGB(0,0,0));
HBRUSH brush_o=::CreateSolidBrush(RGB(0,0xc0,0));
HBRUSH brush_e=::CreateSolidBrush(RGB(0,0x80,0));
HBRUSH brush_a=::CreateSolidBrush(RGB(0x80,0x80,0x80));
void set(int x,int y,int w,int h,HBRUSH brush){
::SelectObject(dc,brush);
::BitBlt(dc,x,y,w,h,0,0,0,PATCOPY);
}
int main(){
HWND window;{
WNDCLASSEXA wc={sizeof(wc)};
wc.lpszClassName="wc";
wc.hCursor=::LoadCursor(0,IDC_ARROW);
wc.hbrBackground=::CreateSolidBrush(RGB(-1,-1,-1));
wc.lpfnWndProc=window_proc;
::RegisterClassExA(&wc);
window=::CreateWindowExA(0,wc.lpszClassName,"",WS_POPUP|WS_VISIBLE,0,0,1,1,0,0,0,0);
::SetCursor(::LoadCursor(0,IDC_ARROW));
}
IDirectDraw*draw;{
::DirectDrawCreate((GUID *)DDCREATE_HARDWAREONLY,&draw,0);
draw->SetCooperativeLevel(window,DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE);
}
IDirectDrawSurface*surface;{
DDSURFACEDESC desc={sizeof(desc)};
desc.dwFlags=DDSD_CAPS;
desc.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_3DDEVICE;
draw->CreateSurface(&desc,&surface,0);
}
DDSURFACEDESC desc={sizeof(desc)};{
surface->GetSurfaceDesc(&desc);
}
const int wx=desc.dwWidth;
const int wy=desc.dwHeight;
const int wx_fn=wx/fn;
int ux;
int uy;
int u;
{
int x=(wx_fn-2)/fx;
int y=wy/(fy 1);
if(x<y)u=x;else u=y;
ux=u*fx;
uy=u*fy;
}
const int font_h=u;
const HFONT font=::CreateFontA(-font_h,0,0,0,0,0,0,0,0,0,0,CLEARTYPE_QUALITY,0,"simsun");
const int font_w=font_h/2;
while(1){
DWORD time=::GetTickCount();
surface->GetDC(&dc);
set(0,0,wx,wy,brush_all);
for(int fi=0;fi<fn;fi ){
xy p;
p.x=(wx_fn-ux)/2 fi*wx_fn;
p.y=(wy-uy-u)/2;
::SelectObject(dc,font);
::SetTextColor(dc,RGB(0,0,0));
::SetBkMode(dc,TRANSPARENT);
char a[100];
int n=sprintf(a,"%i",fa[fi].n);
::TextOutA(dc,p.x,p.y,a,n);
p.y =u;
set(p.x,p.y,ux,uy,brush_back);
fa[fi].run(time);
for(int i=0;i<em;i ){
xy m=fa[fi].e.b[i];
if(m.y<fy){
m.y=fy-1-m.y;
set(p.x m.x*u,p.y m.y*u,u-1,u-1,(fa[fi].e.r&&fa[fi].e.a[i]==xy(0,0)?brush_o:brush_e));
}
}
for(int x=0;x<fx;x )for(int y=0;y<fy;y )if(fa[fi].a[y][x]){
set(p.x x*u,p.y (fy-1-y)*u,u-1,u-1,brush_a);
}
}
surface->ReleaseDC(dc);
if(::GetAsyncKeyState(VK_ESCAPE)<0)exit(0);
}
return 0;
}