//#include <STDIO.H> //#include <conio.c> #include <time.H> #include <stdlib.H> #include <windows.h> #include <iostream> using namespace std; #define key_left 75 #define key_right 77 #define key_up 72 #define key_down 80 #define space 32 /*全局变量。方块。背景数组*/ int background[20][10]; /*int fang_kuai[2][2]={1,1, 1,1,};*/ int fang_kuai[7][4][4][4]={ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0, 0,0,0,0,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0, 1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0, 1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0,0, 0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, 1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0, 0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, 1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, }; /*方块模板*/ int shape,dir,next_shape,next_dir; struct position { int x; int y; } now_position; /*纪录现在方块的位置*/ int speed_level=1; int fall_to_land,be_lined; /*判断方块是否着地的*/ /*----------------------------------------*/ void clscreen(); void setxy(int x,int y); void display_back(); void display_interface(); void display_fk(int x,int y,int shape,int dir); void init(); //int getkey();/*取键盘的扫描码*/ void getinput(); void m_sound(int freq,int time); void eras_fk(int x,int y,int shape,int dir);/*擦除方块*/ void fk_down(bool quickly = false); bool is_illegal(int x,int y,int changed_dir);/*判断方块移动后坐标是否非法,非法1,合法0*/ int get_random(int n); /*生成一个0----n-1的随机数*/ void check_line(); /*检查是否有行可以消去,如果有就消去*/ void game_over(); /*----------------------------------*/ int main() { int i; init(); while (true) { display_back(); now_position.x=10; now_position.y=2;/*复原初始坐标*/ be_lined=0; /*一个方块刚出现时没有成行*/ shape=next_shape; dir=next_dir; next_shape=get_random(7); next_dir=get_random(4); eras_fk(55,5,shape,dir);/*擦去前一个方块*/ display_fk(55,5,next_shape,next_dir);/*显示下一个方块*/ display_fk(now_position.x,now_position.y,shape,dir);/*显示目前方块*/ fall_to_land=0; while (!fall_to_land) { for (i=15000-1500*speed_level;i>0;i--) { getinput(); }/*接受键盘输入*/ fk_down(); /*方块自动下落*/ } //m_sound(350,500); /*块落下的声音*/ check_line(); /*检查有没有可消去的行*/ if (be_lined) m_sound(250,1000); else m_sound(350,500); } return 0; } /*------------------------------------*/ void init() { int i,j; for (i=0;i<20;i++) for (j=0;j<10;j++) background[i][j]=0;/*背景数组赋初值0*/ next_shape=(get_random(7)+5)/7; next_dir=(get_random(4)+2)/4;/*预先产生一个方块*/ display_interface();/*画界面*/ } void display_interface() { clscreen(); setxy(40,5); printf("The Next: "); setxy(1,1); } /*-----------------------------------------*/ void display_back()/*显示背景*/ { int i,j; for (i=0;i<20;i++) { for (j=0;j<10;j++) { setxy(2*(j+1),i+2); /*数组下标到屏幕坐标的变换*/ if (!background[i][j])/*背景数组中值为0*/ printf(" "); else printf("[]"); } } } /*---------------------------------------*/ void display_fk(int x,int y,int shape,int dir)/*显示方块*/ { int i,j; for (i=0;i<4;i++) { for (j=0;j<4;j++) { if (fang_kuai[shape][dir][i][j]) { setxy((x+2*j),(y+i));/*结合现在方块的位置*/ printf("[]"); } } } } /*-----------------------------------*/ void getinput() { if(GetAsyncKeyState(VK_LEFT)){ if (!is_illegal(now_position.x-2,now_position.y,dir)) { eras_fk(now_position.x,now_position.y,shape,dir); now_position.x=now_position.x-2; display_fk(now_position.x,now_position.y,shape,dir); Sleep(1000); } else m_sound(440,500); /*如果没有遇阻,方块位置左移一格*/ }else if(GetAsyncKeyState(VK_RIGHT)){ if (!is_illegal(now_position.x+2,now_position.y,dir)) { eras_fk(now_position.x,now_position.y,shape,dir); now_position.x=now_position.x+2; display_fk(now_position.x,now_position.y,shape,dir); Sleep(1000); } else m_sound(440,500); /*如果没有遇阻,方块位置右移一格*/ }else if(GetAsyncKeyState(VK_UP)){ if (!is_illegal(now_position.x,now_position.y,(dir+1)%4)) { eras_fk(now_position.x,now_position.y,shape,dir); dir=(dir+1)%4; display_fk(now_position.x,now_position.y,shape,dir); Sleep(1000); } }else if(GetAsyncKeyState(VK_DOWN)){ fk_down(true); }else if(GetAsyncKeyState(VK_SPACE)){ game_over(); } } /*------------------------------------*/ void m_sound(int freq,int time) { Beep(freq,time); } /*--------------------------------*/ void eras_fk(int x,int y,int shape,int dir)/*擦除方块*/ { int i,j; for (i=0;i<4;i++) { for (j=0;j<4;j++) { if (fang_kuai[shape][dir][i][j]) { setxy((x+2*j),(y+i));/*结合现在方块的位置*/ printf(" "); } } } } /*----------------------------------------------------*/ void fk_down(bool quickly) /*方块下落*/ { int i,j,x,y; if (!is_illegal(now_position.x,now_position.y+1,dir))/*下落没有阻碍*/ { eras_fk(now_position.x,now_position.y,shape,dir); now_position.y=now_position.y+1; display_fk(now_position.x,now_position.y,shape,dir); if(quickly) { Sleep(10); }else { Sleep(1000); } } else /*不可再下落了*/ { /*方块并入背景*/ x=now_position.x; y=now_position.y; /*x,y表示方便*/ for (i=0;i<4;i++) { for (j=0;j<4;j++) { if (fang_kuai[shape][dir][i][j]==1) background[(y-2+i)][(x/2-1+j)]=1; } } fall_to_land=1; /*告诉主程序方块着地*/ } } /*-----------------------------------------------------*/ bool is_illegal(int x,int y,int changed_dir) { int i,j; bool illegal=false; /*先判断有没有出界,如果有x,y在界外并且此x,y处方块数组为1,就返回1*/ for (i=0;i<4;i++) for (j=0;j<4;j++) if (fang_kuai[shape][changed_dir][i][j]==1&&((x+j*2)>21 || (x+j*2)<2 || (y+i)>21 || (y+i)<2)) illegal=true; /*再判断是否有原方块阻碍*/ if (!illegal) { for (i=0;i<4;i++) for (j=0;j<4;j++) if (fang_kuai[shape][changed_dir][i][j]==1&&background[(y-2+i)][(x/2-1+j)]==1) illegal=true;/*有阻碍返回一*/ } return illegal; } /*-----------------------------------------------------*/ int get_random(int n) { int x; Sleep(500); /* randomize(); x=random(n); */ srand( (unsigned)time(NULL)); x=rand()%n; return(x); } /*--------------------------------------------------------------*/ void check_line() /*待修改*/ { /*检查背景数组*/ int i,j,k; int line,n; for (i=19;i>=0;i--) { k=1; /*开始默认成行*/ for (j=9;j>=0;j-- ) { if (background[i][j]==0) /*不成行的条件*/ k=0; } if (k==1) /*如果成行*/ { be_lined=1; /*成行标志*/ for (line=i;line>0;line--) for (n=9;n>=0;n--) background[line][n]=background[line-1][n]; /*逐次下移一行*/ i=i+1; /*把下一次待检的行重新设定*/ } } } /*--------------------------------------------------------------*/ void game_over() { clscreen(); setxy(35,1); printf("GAME OVER"); exit(0); } void clscreen() { system("cls"); } void setxy(int x,int y) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); COORD place; place.X = x; place.Y = y; SetConsoleCursorPosition(hConsole, place); } /* Colors defined for SetColor(int) */ enum { BLACK = 0, DARK_BLUE = 1, DARK_GREEN = 2, TEAL = 3, DARK_RED = 4, DARK_PURPLE = 5, GOLD = 6, GREY = 7, DARK_WHITE = 8, BLUE = 9, GREEN = 10, CYAN = 11, RED = 12, PURPLE = 13, YELLOW = 14, WHITE = 15 }; void SetColor(const int foreground, const int background) { int Color = foreground + (background * 16); HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, Color); return; }