C语言俄罗斯方块
先看效果


代码如下
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define UI_WIDTH 14
#define UI_HEIGHT 25
#define WALL 1
#define BLOCK 2
#define VK_UP 72
#define VK_DOWN 80
#define VK_LEFT 75
#define VK_RIGHT 77
#define TRUE 1
#define FALSE 0
void initia();
void gameShow();
void moveBlock();
short isCanMoveBlock(short x, short y);
void produceBlock();
void toBottom(short x, short y);
short cur_block_coord_x ,cur_block_coord_y;
short next_blockarr[4][4];
short cur_boxindex,next_boxindex;
int score;
char player_name[10] = "你大哥" ;
HANDLE hOutput;
struct _game_arr{short info; short var;
}game_arr[UI_HEIGHT][UI_WIDTH];
struct _block
{short a[4][2]; short next;
};
struct _block block[19]=
{ {1,1,1,2,1,3,2,3,1},{0,2,1,2,2,2,0,3,2},{0,1,1,1,1,2,1,3,3},{2,1,0,2,1,2,2,2,0},{1,1,1,2,0,3,1,3,5},{0,1,0,2,1,2,2,2,6},{1,1,2,1,1,2,1,3,7},{0,2,1,2,2,2,2,3,4},{1,1,0,2,1,2,2,2,9},{1,1,1,2,2,2,1,3,10},{0,2,1,2,2,2,1,3,11},{1,1,0,2,1,2,1,3,8},{1,1,1,2,2,2,2,3,13},{1,2,2,2,0,3,1,3,12},{2,1,1,2,2,2,1,3,15},{0,2,1,2,1,3,2,3,14},{1,0,1,1,1,2,1,3,17},{0,2,1,2,2,2,3,2,16},{1,1,2,1,1,2,2,2,18},
};
void main()
{hOutput = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTitle(TEXT("俄罗斯方块"));SMALL_RECT rc = {0,0,UI_WIDTH*2+15,UI_HEIGHT+3}; SetConsoleWindowInfo(hOutput,TRUE,&rc);srand(time(NULL));initia();CONSOLE_CURSOR_INFO cci;cci.bVisible = 0;cci.dwSize =1;SetConsoleCursorInfo(hOutput, &cci);produceBlock();moveBlock();
}
void initia()
{short i,j;for(i = 0; i < UI_HEIGHT; i++){for(j = 0; j < UI_WIDTH; j++){if(i == 0 || i == UI_HEIGHT-1) {game_arr[i][j].info = WALL; game_arr[i][j].var = 1;continue;} if(j == 0 || j == UI_WIDTH-1) {game_arr[i][j].info = WALL; game_arr[i][j].var = 1;continue;}}}printf("\n\n\t欢迎你的到来\n\t请您输入一个昵称吧!>:");scanf("%s",&player_name);next_boxindex = rand() % 19;
}
void gameShow()
{short i,j;system("cls");puts("\n\t\t<俄罗斯方块>");for(i = 0; i < UI_HEIGHT; i++){for(j = 0; j < UI_WIDTH; j++){if(game_arr[i][j].info == 0) {printf("+");continue;}if(game_arr[i][j].info == WALL){if(i == 0 || i == UI_HEIGHT-1) printf("-");else printf("|"); continue;}if(game_arr[i][j].info == BLOCK) printf("▉");}if(i == 1) printf(" 下一个方块");if(i >= 2 && i <= 5) {printf(" ");for(j = 0; j < 4; j++){if(next_blockarr[i-2][j] == 0) printf(" "); else printf("▉");}}if(i == 10) printf(" 玩家:%s",player_name);if(i == 11) printf(" 得分:%d",score);if(i == UI_HEIGHT-6) printf(" 操作");if(i == UI_HEIGHT-5) printf(" ↑旋转");if(i == UI_HEIGHT-4) printf(" ←左移");if(i == UI_HEIGHT-3) printf(" →右移");if(i == UI_HEIGHT-2) printf(" ↓下移");printf("\n");}
}
void produceBlock()
{short i,j;cur_boxindex = next_boxindex;next_boxindex = rand() % 19; cur_block_coord_x = (UI_WIDTH-2)/2; cur_block_coord_y = 1;for(i = 0; i < 4; i++)for(j = 0; j < 4; j++)next_blockarr[i][j] = 0; for(i = 0; i < 4; i++){game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK ;next_blockarr[block[next_boxindex].a[i][1]][block[next_boxindex].a[i][0]] = BLOCK;}if( !isCanMoveBlock(cur_block_coord_x,cur_block_coord_y)) {printf("游戏结束,再接再厉!");getch();exit(0);}
}
void moveBlock()
{short i,j,to_bottom = FALSE; short old_x = cur_block_coord_x,old_y = cur_block_coord_y; short old_boxindex = cur_boxindex; while(1){old_x = cur_block_coord_x,old_y = cur_block_coord_y;old_boxindex = cur_boxindex;while(kbhit()) { switch(getch()){case VK_UP: cur_boxindex = block[cur_boxindex].next;if(!isCanMoveBlock(cur_block_coord_x, cur_block_coord_y))cur_boxindex = old_boxindex; break;case VK_DOWN: for(i = 0; i < 4; i++) if(isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1)) cur_block_coord_y++;else {to_bottom = TRUE;break;}break;case VK_LEFT: if(isCanMoveBlock(cur_block_coord_x - 1, cur_block_coord_y)) cur_block_coord_x--;break;case VK_RIGHT: if(isCanMoveBlock(cur_block_coord_x + 1, cur_block_coord_y)) cur_block_coord_x++;break;}}if(to_bottom){if(old_x != cur_block_coord_x || old_y != cur_block_coord_y || old_boxindex != cur_boxindex){for(i = 0;i < 4; i++)game_arr[old_y+block[old_boxindex].a[i][1]][old_x+block[old_boxindex].a[i][0]].info = 0;for(i = 0;i < 4; i++)game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK;gameShow(); }to_bottom = FALSE; toBottom(cur_block_coord_x, cur_block_coord_y);gameShow();}else{if(j++ % 10 == 0) {if(isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1)) cur_block_coord_y++;else to_bottom = TRUE; }if(old_x != cur_block_coord_x || old_y != cur_block_coord_y || old_boxindex != cur_boxindex){for(i = 0;i < 4; i++)game_arr[old_y+block[old_boxindex].a[i][1]][old_x+block[old_boxindex].a[i][0]].info = 0;for(i = 0;i < 4; i++)game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK;gameShow(); }}Sleep(20);}
}
short isCanMoveBlock(short x, short y)
{short i;for(i=0;i<4;i++)if(game_arr[y+block[cur_boxindex].a[i][1]][x+block[cur_boxindex].a[i][0]].var)return FALSE; return TRUE;
}
void toBottom(short x, short y)
{ short i,j;for(i = 0; i < 4; i++)game_arr[y+block[cur_boxindex].a[i][1]][x+block[cur_boxindex].a[i][0]].var = 1;for(i = UI_HEIGHT - 2; i >= 1; i--) {for(j = 1; j <= UI_WIDTH - 2; j++){if( !game_arr[i][j].var)break;if(j == UI_WIDTH - 2) {score += 10; int h,v;for(v = i; v >= 2; v--) {for(h = 1; h <= UI_WIDTH - 2; h++){game_arr[v][h].info = game_arr[v-1][h].info;game_arr[v][h].var = game_arr[v-1][h].var;}}i = UI_HEIGHT - 1;}}}produceBlock();
}