<>C Language Tetris
<> Look at the effect first
<> The code is as follows
/************************************* * Tetris * 1. Game start interface , Display interface * 2.
Generation of squares , And determine whether there are squares in the position where the blocks are generated , Quit the game if you have one * 3. Movement of squares , rotate , Move left and right , Can it be moved * 4. Square to the end , Is the line full , Generate new squares *
@author zhoufei * @date 2018-6-24 ***************************************/ #
include <stdio.h> #include <stdlib.h> #include <windows.h> #define UI_WIDTH 14
// The width of the display interface #define UI_HEIGHT 25 // Height of interface #define WALL 1 #define BLOCK 2 #define
VK_UP 72// Key up and down the second value around , Arrow keys have two values , The first is 224, namely 72,... #define VK_DOWN 80 #define
VK_LEFT 75 #define VK_RIGHT 77 #define TRUE 1 #define FALSE 0 void initia();
// Some work of initialization void gameShow(); /* Game display interface */ void moveBlock(); /* Movement of squares */ short
isCanMoveBlock(short x, short y); // Can I move the square void produceBlock(); // Generating squares void
toBottom(short x, short y); // The operation after the square is in the end ,bottom: bottom short cur_block_coord_x ,
cur_block_coord_y; // Abscissa and ordinate of the current block //int game_arr[UI_HEIGHT][UI_WIDTH]; // Interface array of the game
short next_blockarr[4][4]; // An array to hold the next block short cur_boxindex,next_boxindex;
// Record the subscript of the current block and the next block int score; // achievement char player_name[10] = " Your brother " ; // Player's name
HANDLE hOutput; struct _game_arr{ short info; // Array used to store the game interface short var;
// It is used to record whether a position of the array is occupied , When the square doesn't move , // This location is occupied , When the move box is occupied, it cannot be moved , use 1 Indicates occupancy ,0 Indicates not occupied }
game_arr[UI_HEIGHT][UI_WIDTH]; struct _block { short a[4][2];
/* An array that defines the shape of a block , Each block has 4 Small pieces , use 4 That's ok 2 Column to record the relative of each square coordinate , */ short next; // The number of the next block };
struct _block block[19]= { // Initialize each game box , All in all 19 Total block shape {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(" Tetris "));
SMALL_RECT rc= {0,0,UI_WIDTH*2+15,UI_HEIGHT+3}; // Set window size , Width and height
SetConsoleWindowInfo(hOutput,TRUE,&rc); srand(time(NULL)); initia(); // Hide cursor for buffer
CONSOLE_CURSOR_INFO cci; cci.bVisible = 0; cci.dwSize =1; SetConsoleCursorInfo(
hOutput, &cci); produceBlock(); moveBlock(); } void initia() { // Some work of initialization 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;} //.var=1 Indicates that the point is occupied if(j == 0 || j == UI_WIDTH-1) {game_arr[i][j].info =
WALL; game_arr[i][j].var = 1;continue;} } } printf(
"\n\n\t Welcome to our hotel \n\t Please enter a nickname !>:"); scanf("%s",&player_name); next_boxindex = rand(
) % 19; // Two blocks are randomly generated for the first time } /* Game display interface */ void gameShow() { //1 Show borders , Space , block short i,j;
system("cls"); puts("\n\t\t< Tetris >"); 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("-");// Painting horizontal
else printf("|"); continue; } if(game_arr[i][j].info == BLOCK) printf("▉"); } if
(i == 1) printf(" Next block "); if(i >= 2 && i <= 5) // Next block { printf(" "); for(j = 0
; j < 4; j++) { if(next_blockarr[i-2][j] == 0) printf(" "); // To reduce 2, Because from i It's up to you 2 Starting
else printf("▉"); } } if(i == 10) printf(" game player :%s",player_name); if(i == 11)
printf(" score :%d",score); if(i == UI_HEIGHT-6) printf(" operation "); if(i == UI_HEIGHT-5)
printf(" ↑ rotate "); if(i == UI_HEIGHT-4) printf(" ← Shift left "); if(i == UI_HEIGHT-3) printf
(" → Shift right "); if(i == UI_HEIGHT-2) printf(" ↓ Move down "); printf("\n"); } } /* The generation of each block */
void produceBlock() { // Place a box in the middle of the game interface short i,j; cur_boxindex = next_boxindex;
next_boxindex= rand() % 19; // The number of blocks is generated randomly cur_block_coord_x = (UI_WIDTH-2)/2;
// Fall from the middle cur_block_coord_y = 1; for(i = 0; i < 4; i++) for(j = 0; j < 4; j++)
next_blockarr[i][j] = 0; // Each time a new block is generated , Clear the array that holds the next block 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)) // The place where the new square was created is occupied , sign out { printf(" game over , make persistent efforts !");getch();exit(0);
} } /* Movement of squares */ void moveBlock() { short i,j,to_bottom = FALSE; // to the end short old_x =
cur_block_coord_x,old_y = cur_block_coord_y; // Used to record the position of the old block short old_boxindex =
cur_boxindex; // Record the subscript of the box , Press the up button to change the box while(1) { old_x = cur_block_coord_x,old_y =
cur_block_coord_y; old_boxindex = cur_boxindex; while(kbhit()) // User key { //
getch(); 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; // If it can't be rotated, it should be restored break; case VK_DOWN: for(i = 0; i < 4; i++)
// You can go down once 4 individual if(isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1))
cur_block_coord_y++; else {to_bottom = TRUE;break;}// to the end 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(); // Refresh after pressing the key } to_bottom = FALSE; toBottom(cur_block_coord_x,
cur_block_coord_y);gameShow();// to the end } else { if(j++ % 10 == 0) // Auto move down , Put it in front , { if(
isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1)) cur_block_coord_y++;
else to_bottom = TRUE; // to the end } 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();
// Refresh after pressing the key } } Sleep(20); } } short isCanMoveBlock(short x, short y) { // Can I move the square
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; // If the position is filled with squares , It cannot be moved return TRUE; }
void toBottom(short x, short y) {
// Operation after square to the bottom ,1. Change the status of the box's position to 1, Indicates occupied .2. Is it full , Disappear , Change state 3. Generate new squares 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; //2. Is it full , Disappear , Change state for(i = UI_HEIGHT - 2; i >= 1; i--) // There are two rows of walls , Search from the bottom up
{ for(j = 1; j <= UI_WIDTH - 2; j++) { if( !game_arr[i][j].var) break;
// If a line is free, jump out of the loop , Continue searching for the next line if(j == UI_WIDTH - 2) // The line is full , Disappear , At this time, the i Yes, it's full { score += 10;
int h,v; for(v = i; v >= 2; v--) // The first i Line start , { 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; } }// To start from the bottom line again , after i--,i = UI_HEIGHT - 2, There will be more than one line disappear together, some lines can not be eliminated i = UI_HEIGHT - 1;
} } }produceBlock(); }
Technology