当前位置:网站首页>All codes of Tetris
All codes of Tetris
2022-07-26 10:06:00 【SingleDog_ seven】
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#define ROW 29 // Number of lines in the game area
#define COL 20 // Number of columns in the game area
#define DOWN 80 // Direction key : Next
#define LEFT 75 // Direction key : Left
#define RIGHT 77 // Direction key : Right
#define SPACE 32 // Space bar
#define ESC 27 //Esc key
struct Face
{
int data[ROW][COL + 10]; // Used to mark whether there is a square at the specified position (1 To have ,0 For nothing )
int color[ROW][COL + 10]; // Used to record the square color code of the specified position
}face;
struct Block
{
int space[4][4];
}block[7][4]; // Used to store 7 Each of the basic shape blocks 4 Two forms of information , common 28 Kind of
// hide cursor
void HideCursor();
// The cursor jumps
void CursorJump(int x, int y);
// Initialization interface
void InitInterface();
// Initialization block information
void InitBlockInfo();
// color setting
void color(int num);
// Draw a square
void DrawBlock(int shape, int form, int x, int y);
// Space overlay
void DrawSpace(int shape, int form, int x, int y);
// Legitimacy judgment
int IsLegal(int shape, int form, int x, int y);
// Judge the score and end
int JudeFunc();
// Game body logic function
void StartGame();
// Read the highest score from the file
void ReadGrade();
// Update the highest score to the file
void WriteGrade();
int max, grade; // Global variables
int main()
{
#pragma warning (disable:4996) // Eliminate warnings
max = 0, grade = 0; // Initialize variable
system("title tetris "); // Set up cmd The name of the window
system("mode con lines=29 cols=60"); // Set up cmd Window size
HideCursor(); // hide cursor
ReadGrade(); // Read the highest score from the file to max Variable
InitInterface(); // Initialization interface
InitBlockInfo(); // Initialization block information
srand((unsigned int)time(NULL)); // Set the starting point of random number generation
StartGame(); // Start the game
return 0;
}
// hide cursor
void HideCursor()
{
CONSOLE_CURSOR_INFO curInfo; // Structure variables that define cursor information
curInfo.dwSize = 1; // If there is no assignment , Invalid hidden cursor
curInfo.bVisible = FALSE; // Set the cursor to invisible
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // Get the console handle
SetConsoleCursorInfo(handle, &curInfo); // Set cursor information
}
// The cursor jumps
void CursorJump(int x, int y)
{
COORD pos; // Structure variables that define the cursor position
pos.X = x; // Abscissa setting
pos.Y = y; // Ordinate setting
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); // Get the console handle
SetConsoleCursorPosition(handle, pos); // Set cursor position
}
// Initialization interface
void InitInterface()
{
color(7); // Color set to white
int i,j;
for(i=0;i< ROW;i++)
{
int j;
for ( j = 0; j < COL + 10; j++)
{
if (j == 0 || j == COL - 1 || j == COL + 9)
{
face.data[i][j] = 1; // Mark the position with a square
CursorJump(2 * j, i);
printf("■");
}
else if (i == ROW - 1)
{
face.data[i][j] = 1; // Mark the position with a square
printf("■");
}
else
face.data[i][j] = 0; // Mark that there is no square in this position
}
}
for (i = COL; i < COL + 10; i++)
{
face.data[8][i] = 1; // Mark the position with a square
CursorJump(2 * i, 8);
printf("■");
}
CursorJump(2 * COL, 1);
printf(" Next block :");
CursorJump(2 * COL + 4, ROW - 19);
printf(" Move left :←");
CursorJump(2 * COL + 4, ROW - 17);
printf(" Move right :→");
CursorJump(2 * COL + 4, ROW - 15);
printf(" Speed up :↓");
CursorJump(2 * COL + 4, ROW - 13);
printf(" rotate : Space ");
CursorJump(2 * COL + 4, ROW - 11);
printf(" Pause : S");
CursorJump(2 * COL + 4, ROW - 9);
printf(" sign out : Esc");
CursorJump(2 * COL + 4, ROW - 7);
printf(" restart :R");
CursorJump(2 * COL + 4, ROW - 5);
printf(" The highest record :%d", max);
CursorJump(2 * COL + 4, ROW - 3);
printf(" Current score :%d", grade);
}
// Initialization block information
void InitBlockInfo()
{
int i,j,shape,form;
//“T” shape
for ( i = 0; i <= 2; i++)
block[0][0].space[1][i] = 1;
block[0][0].space[2][1] = 1;
//“L” shape
for ( i = 1; i <= 3; i++)
block[1][0].space[i][1] = 1;
block[1][0].space[3][2] = 1;
//“J” shape
for ( i = 1; i <= 3; i++)
block[2][0].space[i][2] = 1;
block[2][0].space[3][1] = 1;
for ( i = 0; i <= 1; i++)
{
//“Z” shape
block[3][0].space[1][i] = 1;
block[3][0].space[2][i + 1] = 1;
//“S” shape
block[4][0].space[1][i + 1] = 1;
block[4][0].space[2][i] = 1;
//“O” shape
block[5][0].space[1][i + 1] = 1;
block[5][0].space[2][i + 1] = 1;
}
//“I” shape
for ( i = 0; i <= 3; i++)
block[6][0].space[i][1] = 1;
int temp[4][4];
for ( shape = 0; shape < 7; shape++) //7 Species shape
{
for ( form = 0; form < 3; form++) //4 Form ( There is already a kind of , Each one here needs to be added 3 Kind of )
{
// For the first form Form
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
temp[i][j] = block[shape][form].space[i][j];
}
}
// Will be the first form One form rotates clockwise , Get the first form+1 Form
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
block[shape][form + 1].space[i][j] = temp[3 - j][i];
}
}
}
}
}
// color setting
void color(int c)
{
switch (c)
{
case 0:
c = 13; //“T” The square is set to purple
break;
case 1:
case 2:
c = 12; //“L” Xinghe “J” The square is set to red
break;
case 3:
case 4:
c = 10; //“Z” Xinghe “S” The square is set to green
break;
case 5:
c = 14; //“O” The square is set to yellow
break;
case 6:
c = 11; //“I” The square is set to light blue
break;
default:
c = 7; // Other default settings are white
break;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); // color setting
// notes :SetConsoleTextAttribute It's a API( Application programming interface )
}
// Draw a square
void DrawBlock(int shape, int form, int x, int y)
{
int i,j;
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
if (block[shape][form].space[i][j] == 1) // If there is a square in this position
{
CursorJump(2 * (x + j), y + i); // The cursor jumps to the specified position
printf("■"); // Output block
}
}
}
}
// Space overlay
void DrawSpace(int shape, int form, int x, int y)
{
int i,j;
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
if (block[shape][form].space[i][j] == 1) // If there is a square in this position
{
CursorJump(2 * (x + j), y + i); // The cursor jumps to the specified position
printf(" "); // Print space overlay ( Two spaces )
}
}
}
}
// Legitimacy judgment
int IsLegal(int shape, int form, int x, int y)
{
int i,j;
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
// If the box falls, there will already be a box , It is illegal.
if ((block[shape][form].space[i][j] == 1) && (face.data[y + i][x + j] == 1))
return 0; // illegal
}
}
return 1; // legal
}
// Judge the score and end
int JudeFunc()
{
// Judge whether to score
int i,j,m,n;
for ( i = ROW - 2; i > 4; i--)
{
int sum = 0; // Record No. i Number of squares in a row
for ( j = 1; j < COL - 1; j++)
{
sum += face.data[i][j]; // Statistics No i Number of squares in a row
}
if (sum == 0) // There are no squares in this line , There is no need to judge the level above it ( There is no need to continue to judge whether to score )
break; // Out of the loop
if (sum == COL - 2) // The line is full of squares , Can score
{
grade += 10; // Add... To the full line 10 branch
color(7); // Color set to white
CursorJump(2 * COL + 4, ROW - 3); // The cursor jumps to the position where the current score is displayed
printf(" Current score :%d", grade); // Update current score
for ( j = 1; j < COL - 1; j++) // Clear the block information of the obtained Branch
{
face.data[i][j] = 0; // This position is cleared after scoring , Mark as no square
CursorJump(2 * j, i); // The cursor jumps to this position
printf(" "); // Print space overlay ( Two spaces )
}
// Move the entire row above the cleared row down one grid
for (m = i; m >1; m--)
{
sum = 0; // Record the number of squares in the previous line
for ( n = 1; n < COL - 1; n++)
{
sum += face.data[m - 1][n]; // Count the number of squares in the previous line
face.data[m][n] = face.data[m - 1][n]; // Move the identification of the box on the previous line to the next line
face.color[m][n] = face.color[m - 1][n]; // Move the color number of the box on the previous line to the next line
if (face.data[m][n] == 1) // Moving down the previous line is the box , Print box
{
CursorJump(2 * n, m); // The cursor jumps to this position
color(face.color[m][n]); // The color is set to the color of the square
printf("■"); // Print box
}
else // The space moved down from the previous line , Print space
{
CursorJump(2 * n, m); // The cursor jumps to this position
printf(" "); // Print space ( Two spaces )
}
}
if (sum == 0) // All the spaces moved down from the previous line , There is no need to move the upper box down ( End of move )
return 1; // return 1, Indicates that the function needs to be called for judgment ( There may be a full line of moving down )
}
}
}
// Determine if the game is over
for ( j = 1; j < COL - 1; j++)
{
if (face.data[1][j] == 1) // There are squares on the top ( By the end of 1 Behavior top level , Not the first 0 That's ok )
{
Sleep(1000); // Leave players reaction time
system("cls"); // Clear the screen
color(7); // Color set to white
CursorJump(2 * (COL / 3), ROW / 2 - 3);
if (grade>max)
{
printf(" Congratulations on breaking the record , The highest record was updated to %d", grade);
WriteGrade();
}
else if (grade == max)
{
printf(" In line with the record , Come on, make another success ", grade);
}
else
{
printf(" Please continue refueling , There is a difference between the current record and the highest record %d", max - grade);
}
CursorJump(2 * (COL / 3), ROW / 2);
printf("GAME OVER");
while (1)
{
char ch;
CursorJump(2 * (COL / 3), ROW / 2 + 3);
printf(" Another round ?(y/n):");
scanf("%c", &ch);
if (ch == 'y' || ch == 'Y')
{
system("cls");
main();
}
else if (ch == 'n' || ch == 'N')
{
CursorJump(2 * (COL / 3), ROW / 2 + 5);
exit(0);
}
else
{
CursorJump(2 * (COL / 3), ROW / 2 + 4);
printf(" Wrong choice , Please select... Again ");
}
}
}
}
return 0; // The judgment is over , There is no need to call this function to judge
}
// Game body logic function
void StartGame()
{
int i,j;
int shape = rand() % 7, form = rand() % 4; // Randomly obtain the shape and shape of the box
while (1)
{
int t = 0;
int nextShape = rand() % 7, nextForm = rand() % 4; // Randomly obtain the shape and shape of the next box
int x = COL / 2 - 2, y = 0; // The abscissa and ordinate of the initial falling position of the block
color(nextShape); // The color is set to the color of the next box
DrawBlock(nextShape, nextForm, COL + 3, 3); // Display the next box in the upper right corner
while (1)
{
color(shape); // The color is set to the square currently falling
DrawBlock(shape, form, x, y); // Display the box at the initial drop position
if (t == 0)
{
t = 15000; // here t The smaller it is , The faster the box falls ( You can set the game difficulty according to this )
}
while (--t)
{
if (kbhit() != 0) // If the keyboard is struck , Then exit the loop
break;
}
if (t == 0) // The keyboard is not tapped
{
if (IsLegal(shape, form, x, y + 1) == 0) // It's illegal for the box to fall again ( Has reached the bottom )
{
// Enter the information of the current box face among
//face: Record whether there are squares at each position of the interface , If there is a box, the color of the box at that position shall also be recorded .
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
if (block[shape][form].space[i][j] == 1)
{
face.data[y + i][x + j] = 1; // Mark the position as square
face.color[y + i][x + j] = shape; // Record the color value of the box
}
}
}
while (JudeFunc()); // Judge whether the falling of the box scores and whether the game is over
break; // Jump out of the current loop , Get ready to drop the next box
}
else // Not to the bottom
{
DrawSpace(shape, form, x, y); // Overwrite the position of the current square with a space
y++; // The ordinate increases automatically ( The next time the box is displayed, it's equivalent to falling a grid )
}
}
else // The keyboard is struck
{
char ch = getch(); // Read keycode
switch (ch)
{
case DOWN: // Direction key : Next
if (IsLegal(shape, form, x, y + 1) == 1) // Judge whether the box is legal after moving down one bit
{
// After the box falls, the following operations can be performed legally
DrawSpace(shape, form, x, y); // Overwrite the position of the current square with a space
y++; // The ordinate increases automatically ( The next time the box is displayed, it's equivalent to falling a grid )
}
break;
case LEFT: // Direction key : Left
if (IsLegal(shape, form, x - 1, y) == 1) // Judge whether the box is legal after moving one bit to the left
{
// The following operations can only be performed after the box is moved to the left
DrawSpace(shape, form, x, y); // Overwrite the position of the current square with a space
x--; // Abscissa self subtraction ( The next time the box is displayed, it is equivalent to moving one grid to the left )
}
break;
case RIGHT: // Direction key : Right
if (IsLegal(shape, form, x + 1, y) == 1) // Judge whether the square is legal after moving one bit to the right
{
// The following operations can only be performed after the box is moved to the right
DrawSpace(shape, form, x, y); // Overwrite the position of the current square with a space
x++; // Abscissa self increasing ( The next time the box is displayed, it's equivalent to moving one grid to the right )
}
break;
case SPACE: // Space bar
if (IsLegal(shape, (form + 1) % 4, x, y + 1) == 1) // Judge whether the box is legal after rotation
{
// The following operations can only be performed after the square is rotated
DrawSpace(shape, form, x, y); // Overwrite the position of the current square with a space
y++; // The ordinate increases automatically ( You can't spin in place )
form = (form + 1) % 4; // The shape of the square increases ( The next time the box is displayed, it's equivalent to rotating )
}
break;
case ESC: //Esc key
system("cls"); // Clear the screen
color(7);
CursorJump(COL, ROW / 2);
printf(" Game over ");
CursorJump(COL, ROW / 2 + 2);
exit(0); // End procedure
case 's':
case 'S': // Pause
system("pause>nul"); // Pause ( Press any key to continue )
break;
case 'r':
case 'R': // restart
system("cls"); // Clear the screen
main(); // Re execute the main function
}
}
}
shape = nextShape, form = nextForm; // Get the information of the next box
DrawSpace(nextShape, nextForm, COL + 3, 3); // Overwrite the box information in the upper right corner with a space
}
}
// Read the highest score from the file
void ReadGrade()
{
FILE* pf = fopen(" The highest score in Tetris .txt", "r"); // Open the file read-only
if (pf == NULL) // fail to open file
{
pf = fopen(" The highest score in Tetris .txt", "w"); // Open the file in write only mode ( The file does not exist. You can create it automatically )
fwrite(&grade, sizeof(int), 1, pf); // take max write file ( here max by 0), Initialize the highest historical score to 0
}
fseek(pf, 0, SEEK_SET); // Make the file pointer pf Point to the beginning of the file
fread(&max, sizeof(int), 1, pf); // Read the highest historical score in the file to max among
fclose(pf); // Close file
pf = NULL; // The file pointer is set to null in time
}
// Update the highest score to the file
void WriteGrade()
{
FILE* pf = fopen(" The highest score in Tetris .txt", "w"); // Open the file in write only mode
if (pf == NULL) // fail to open file
{
printf(" Failed to save the highest score record \n");
exit(0);
}
fwrite(&grade, sizeof(int), 1, pf); // Write the game score of this game into the file ( Update the highest historical score )
fclose(pf); // Close file
pf = NULL; // The file pointer is set to null in time
}
边栏推荐
- IIS website configuration
- Solve proxyerror: CONDA cannot proceed due to an error in your proxy configuration
- Tableviewcell highly adaptive
- Mysql5.7.25 master-slave replication (one-way)
- 点赞,《新程序员》电子书限时免费领啦!
- Unstoppable, pure domestic PCs have been in place, and the monopoly of the U.S. software and hardware system has been officially broken
- Vs2019 configuring opencv
- Uniapp common error [wxml file compilation error]./pages/home/home Wxml and using MySQL front provided by phpstudy to establish an independent MySQL database and a detailed tutorial for independent da
- Sqoop【付诸实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)
- Sqoop [put it into practice 02] sqoop latest version full database import + data filtering + field type support description and example code (query parameter and field type forced conversion)
猜你喜欢
Uni app learning summary
Customize permission validation in blazor
Principle analysis and source code interpretation of service discovery
数通基础-网络基础知识
Error in render: "typeerror: cannot read properties of undefined (reading 'length')" --- error when calling interface
A new paradigm of distributed deep learning programming: Global tensor
PMM (percona monitoring and management) installation record
AR model in MATLAB for short-term traffic flow prediction
Logical architecture of MySQL
Map key not configured and uniapp routing configuration and jump are reported by the uniapp < map >< /map > component
随机推荐
Solve NPM -v sudden failure and no response
[information system project manager] summary of essence of high-level series for the first time
反射机制的原理是什么?
服务发现原理分析与源码解读
【Datawhale】【机器学习】糖尿病遗传风险检测挑战赛
Flask框架初学-04-flask蓝图及代码抽离
Formwork (III)
Use of tabbarcontroller
Customize permission validation in blazor
Sqoop【环境搭建 01】CentOS Linux release 7.5 安装配置 sqoop-1.4.7 解决警告并验证(附Sqoop1+Sqoop2最新版安装包+MySQL驱动包资源)
面试突击68:为什么 TCP 需要 3 次握手?
Study notes of the second week of sophomore year
The charm of SQL optimization! From 30248s to 0.001s
2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)
regular expression
Mqtt x cli officially released: powerful and easy-to-use mqtt 5.0 command line tool
[MySQL database] a collection of basic MySQL operations - the basis of seeing (adding, deleting, modifying, and querying)
protobuf的基本用法
Node memory overflow and V8 garbage collection mechanism
Study notes of the fifth week of sophomore year