俄罗斯方块c语言

参考了这个博客俄罗斯方块(C语言实现)_2021dragon的博客-CSDN博客_c语言俄罗斯方块游戏代码



//俄罗斯方块  C 语言
#include 
#include   
#include  
#include
#pragma comment(lib,"Winmm.lib")
#include   //getch函数
enum { ROW = 29, COL = 20 }; //row为行数,col是列数  游戏界面的大小
enum { DOWN = 80, LEFT = 75, RIGHT = 77, SPACE = 32, ESC = 27, ENTER = 13 };//定义方向键以及空格和退出键的 数值
int max = 0, grade = 0, flag = 0;
void userinterface();
void Hidecursor();
void  gotoxy(int x, int y);
void color(int c);
void initinterface();
void initblock();
void drawblock(int shape, int form, int x, int y);
void deleteblock(int shape, int form, int x, int y);
void Grade();
int judgestop(int shape, int form, int x, int y);
int judgeout();
void initoutface();
void startgame();
void ReadGrade();
void WriteGrade();
void show(int x, int y);
void mode();
void ReadGrade()
{
	FILE* pf = fopen("俄罗斯方块最高得分记录.txt", "r"); //以只读方式打开文件
	if (pf == NULL) //打开文件失败
	{
		pf = fopen("俄罗斯方块最高得分记录.txt", "w"); //以只写方式打开文件(文件不存在可以自动创建该文件)
		fwrite(&grade, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高历史得分初始化为0
	}
	fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头
	fread(&max, sizeof(int), 1, pf); //读取文件中的最高历史得分到max当中
	fclose(pf); //关闭文件
	pf = NULL; //文件指针及时置空
}
//更新最高分到文件
void WriteGrade()
{
	FILE* pf = fopen("俄罗斯方块最高得分记录.txt", "w"); //以只写方式打开文件
	if (pf == NULL) //打开文件失败
	{
		printf("保存最高得分记录失败\n");
		exit(0);
	}
	fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中(更新最高历史得分)
	fclose(pf); //关闭文件
	pf = NULL; //文件指针及时置空
}
struct Face {          //定义界面结构体,每一坐标的 有无方块,以及颜色
	int data[ROW][COL + 10];
	int color[ROW][COL + 10];
}face;

struct Block {
	int space[4][4];   //每种状态都可以用4×4的方格表示出来
}block[7][4];          //存储七种类型的方块,以及每个方块的四种状态
char player[20];
int main() {
	time_t start, end;
	start = time(NULL);
	PlaySound(TEXT("上海アリス幻樂団 - 神々が恋した幻想郷.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
	userinterface();
	system("mode con lines=29 cols=60");        //窗口大小
	srand((unsigned int)time(NULL));           //时间种子
	Hidecursor();                             //隐藏光标
	initinterface();                          //初始化页面
	initblock();                              //初始化方块
	startgame();                              //开始游戏
	system("pause>nul");
	system("cls");
	end = time(NULL);
	gotoxy(COL / 2 + 5, ROW / 2 - 5);
	printf("最终得分:%d", grade);
	gotoxy(COL / 2 + 5, ROW / 2 - 3);
	printf("最终耗时:time=%.0fs\n", difftime(end, start));
	return 1;
}

void  gotoxy(int x, int y) {   //移动光标
	COORD point;
	point.X = x;
	point.Y = y;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);          //获取控制台句柄
	SetConsoleCursorPosition(handle, point);                //设置光标位置
}
void Hidecursor() {                     //隐藏光标
	CONSOLE_CURSOR_INFO cursor = { 1,0 };                       //0:设置光标不可见
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cursor);                 //设置光标信息

}
void mode()
{
	color(8);
	gotoxy(35, 9);
	printf("模式1 >> 标准模式\n"); gotoxy(35, 10);
	printf("模式2 >> 地狱模式\n"); gotoxy(35, 11);
	printf("模式3 >> 作弊模式\n"); gotoxy(35, 12);
	printf("模式4 >> 隐身模式\n"); gotoxy(35, 13);//隐身模式 是指经过一次消块后 把存在的方块变成黑色
	printf("您的选择是");

	scanf(" %d", &flag);
	while (flag > 4 || flag <= 0) {
		scanf("%d", &flag);
	}
}
void userinterface() {

	printf("\n\n\n"); printf("    ");
	show(0, 0);
	gotoxy(25, 7);
	char str[100] = { "welcome to your favorite game --- tetris" };
	color(7);
	for (int i = 0; i < strlen(str); i++)
	{
		printf("%c", str[i]);
		Sleep(50);
	}
	printf("\n");
	color(1);
	gotoxy(25, 8);
	printf("          >>  请输入玩家名字:");
	scanf("%s", &player);

	mode();
	gotoxy(25, 6);
	printf("          OK   %s   Let's go!\n", player);
	printf("          "); gotoxy(25, 7);
	char str1[60] = { " >>  Please enjoy adventure! " };
	color(2);
	for (int i = 0; i < strlen(str1); i++)
	{
		printf("%c", str1[i]);
		Sleep(60);
	}

	color(7);
	Sleep(500);
	system("cls");
}
void show(int x, int y)
{
	int flagl = 0;
	while (1) {
		system("cls");
		color(rand() % 6);
		gotoxy(x, y);
		printf("■■■■■  ■■■■■  ■■■■■  ■■■■  ■■■  ■■■■");
		gotoxy(x, y + 1);
		printf("    ■      ■              ■      ■    ■    ■    ■");
		gotoxy(x, y + 2);
		printf("    ■      ■■■■        ■      ■■■      ■      ■■■");
		gotoxy(x, y + 3);
		printf("    ■      ■              ■      ■  ■      ■          ■");
		gotoxy(x, y + 4);
		printf("    ■      ■■■■■      ■      ■    ■  ■■■  ■■■■");
		Sleep(100); x = x + 1; flagl++;
		if (flagl == 20)
		{
			break;
		}

	}
}
void initinterface() {   //初始化界面
	for (int j = 28; j >= 0; j--) {

		for (int i = 0; i < 30; i++) {
			color(8);
			gotoxy(i * 2, j);
			printf("■");

		}Sleep(50);
	}Sleep(200);
	system("cls");
	color(7);
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL + 10; j++) {
			if (j == 0) face.data[i][j] = 1;
			else if (i == ROW - 1) face.data[i][j] = 1;
			else if (j == COL - 1 || j == COL + 9) face.data[i][j] = 1;
			else  face.data[i][j] = 0;

		}
	}
	for (int i = COL; i < COL + 10; i++) {
		face.data[8][i] = 1;
	}
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL + 10; j++) {
			if (face.data[i][j] == 1) {
				gotoxy(j * 2, i);
				printf("■");
			}
		}
	}
	gotoxy(COL * 2 + 1, ROW / 2 + 1);
	printf(" '↓' :下移一格");
	gotoxy(COL * 2 + 1, ROW / 2 + 3);
	printf(" '→' :右移一格 ");
	gotoxy(COL * 2 + 1, ROW / 2 + 5);
	printf(" '←' :左移一格 ");
	gotoxy(COL * 2 + 1, ROW / 2 + 7);
	printf("'空格键':翻转方块");
	gotoxy(COL * 2 + 1, ROW / 2 - 3);
	printf("Player: %s", player);
	gotoxy(COL * 2 + 1, ROW / 2 - 1);
	printf("当前得分:%d", grade);


	gotoxy(COL * 2 + 1, ROW / 2 + 11);
	printf("R:重新开始");
	gotoxy(COL * 2 + 1, ROW / 2 + 13);
	printf("S:停止游戏");
	gotoxy(COL * 2 + 1, ROW / 2 - 5);
	printf("MAX:%d", max);
	if (flag == 3)
	{
		gotoxy(COL * 2 + 1, ROW / 2 + 9);
		printf("ENTER:变换方块");
	}

}

void color(int c) {
	switch (c) {
	case 0:c = 10; break;   //七种图形各个的颜色
	case 1:c = 11; break;
	case 2:c = 12; break;
	case 3:c = 14; break;
	case 4:c = 8; break;
	case 5:
	case 6:c = 13; break;
	case 99:c = 0; break;
	default:c = 7; break; //其他设置为白色

	}
	HANDLE consolehend;
	consolehend = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(consolehend, c);
}
void initblock() {
	//   T形
	for (int i = 1; i < 4; i++) {
		block[0][0].space[1][i] = 1;
	}
	block[0][0].space[0][2] = 1;
	//   L形
	for (int i = 0; i < 3; i++) {
		block[1][0].space[i][1] = 1;

	}
	block[1][0].space[2][2] = 1;
	// 镜像L形
	for (int i = 0; i < 3; i++) {
		block[2][0].space[i][2] = 1;
	}
	block[2][0].space[2][1] = 1;
	//  I 形
	for (int i = 0; i < 4; i++) {
		block[3][0].space[i][2] = 1;

	}
	//  Z形
	for (int i = 1; i < 3; i++) {
		block[4][0].space[0][i] = 1;
	}
	for (int i = 2; i < 4; i++) {
		block[4][0].space[1][i] = 1;
	}
	//  镜像Z形
	for (int i = 1; i < 3; i++) {
		block[5][0].space[1][i] = 1;
	}
	for (int i = 2; i < 4; i++) {
		block[5][0].space[0][i] = 1;
	}
	// 田形
	for (int i = 0; i < 2; i++) {
		for (int j = 1; j < 3; j++) {
			block[6][0].space[i][j] = 1;
		}
	}
	//  顺时针进行翻转
	for (int t = 0; t < 7; t++) {   //七种图形
		for (int i = 1; i < 4; i++) {   //四种翻转
			for (int j = 0; j < 4; j++) {   //行
				for (int k = 0; k < 4; k++) {   //列
					block[t][i].space[k][3 - j] = block[t][i - 1].space[j][k];
				}
			}
		}
	}
}
void drawblock(int shape, int form, int x, int y) {
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {

			if (block[shape][form].space[i][j] == 1) {
				gotoxy((j + x) * 2, y + i);
				//一个小方格占据两个横坐标,一个纵坐标
				printf("■");
			}

		}
	}
}
void deleteblock(int shape, int form, int x, int y) {
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (block[shape][form].space[i][j] == 1) {
				gotoxy((j + x) * 2, y + i);
				printf("  ");  //需要打两个空格覆盖
			}
		}


	}
}

int judgestop(int shape, int form, int x, int y) {  //判断方块是否落到方块上  或者底部
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {

			if (block[shape][form].space[i][j] == 1)
			{
				if (face.data[y + i][x + j] == 1)
				{
					return 0;
				}
			}
		}
	}
	return 1;
}


void Grade() {
	for (int i = ROW - 2; i > 0; i--) {   //从ROW-2开始,最底层是边界  最顶部检测到初始方块下落的位置
		int num = 0;                    //记录每一行方块的个数 
		for (int j = 1; j <= COL - 2; j++)  //从1开始,最左边是边界
		{
			num += face.data[i][j];
		}
		if (num == 0)  break;  //没有方块结束循环
		if (num == COL - 2) {   //判断是否消除
			grade += 10;
			color(7);
			gotoxy(COL * 2 + 1, ROW / 2 - 1);
			printf("当前得分:%d", grade);
			for (int j = 1; j < COL - 1; j++) {
				face.data[i][j] = 0;
				gotoxy(j * 2, i);
				printf("  ");//打印两个空格覆盖
			}
			for (int t = i; t > 1; t--) {   //下移
				int sum = 0;
				for (int k = 1; k < COL - 1; k++) {
					face.data[t][k] = face.data[t - 1][k];
					face.color[t][k] = face.color[t - 1][k];
					sum += face.data[t - 1][k];

					if (face.data[t][k] == 1) {
						gotoxy(k * 2, t);
						color(face.color[t][k]);
						printf("■");
					}
					else {
						gotoxy(k * 2, t);
						printf("  ");
					}


				}
				if (sum == 0) {
					i++;
					break;
				}
			}
		}
	}

}


int  judgeout() { //判断游戏结束
	for (int i = 1; i < COL - 1; i++) {  //i=1为顶层
		if (face.data[1][i] == 1) {

			initoutface();
			return 0;
		}
	}return 1;

}
void initoutface() {
	for (int j = 28; j >= 0; j--) {

		for (int i = 0; i < 30; i++) {
			color(2);
			gotoxy(i * 2, j);
			printf("■");

		}Sleep(50);
	}
	for (int j = 28; j >= 0; j--)
	{
		for (int i = 0; i < 60; i++) {
			color(2);
			gotoxy(i * 2, j);
			printf("■");
		}Sleep(50);
	}
	for (int i = 0; i < 5; i++) {
		gotoxy(3 * 2, i + 10);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 4; i++) {
		gotoxy((3 + i) * 2, 10);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 3; i++) {
		gotoxy((3 + i) * 2, 12);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 4; i++) {
		gotoxy((3 + i) * 2, 14);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 5; i++) {
		gotoxy(9 * 2, i + 10);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 4; i++) {
		gotoxy((9 + i) * 2, i + 10);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 5; i++) {
		gotoxy(13 * 2, 14 - i);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 5; i++) {
		gotoxy(15 * 2, 10 + i);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 2; i++) {
		gotoxy((16 + i) * 2, 10);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 3; i++) {
		gotoxy(18 * 2, 11 + i);
		printf("  "); Sleep(50);
	}
	for (int i = 0; i < 2; i++) {
		gotoxy((17 - i) * 2, 14);
		printf("  "); Sleep(50);
	}
	Sleep(500);

}
void startgame()
{
	int shape = rand() % 7;   //随机取方块形状 状态
	int form = rand() % 4;
	while (1)
	{
		int i = 0;
		int x = COL / 2;     //每次循环(x,y)初始化为顶部中间位置  初始下落位置  
		int y = 0;
		int nextshape = rand() % 7;   //获取下一个方块
		int nextform = rand() % 4;
		int t;               //下落间隙时间设置在while循环外 ,保证每次t都是减少到0 才重新计时,保证正常的下落速度
		if (flag == 2) t = 5000;
		else t = 15000;
		color(nextshape);
		drawblock(nextshape, nextform, COL + 3, 2);
		while (1) {

			color(shape);

			drawblock(shape, form, x, y); //每次循环后刷新方块位置
			if (judgestop(shape, form, x, y) == 0) {
				initoutface();
				return;
			}

			if (t == 0)
			{
				if (flag == 2) t = 5000;
				else t = 15000;
			}
			while (--t) {
				if (_kbhit() != 0)break;    //如果按键 ,则直接跳出循环执行 方向 操作,t剩余值
			}
			if (t == 0) {   //t=0 方块需要往下移动一行
				if (judgestop(shape, form, x, y + 1) == 0) {  //如果下一行位置
					for (int t = 0; t < 4; t++) {
						for (int k = 0; k < 4; k++) {
							if (block[shape][form].space[t][k] == 1) {
								face.data[t + y][k + x] = 1;
								if (flag != 4)
									face.color[t + y][k + x] = shape;
								else if (flag == 4)//隐身模式
								{
									face.color[t + y][k + x] = 99; color(99);
								}
							}
						}
					}
					Grade();             //判断得分 					
					if (judgeout() == 0) //判断结束游戏
						return;
					break;              //跳出while循环,刷新下一个方块
				}
				else {                 //如果合法删除原来位置方块
					deleteblock(shape, form, x, y);
					y++;
				}

			}

			else if (t > 0) {     //由于程序执行很快,在敲击条件下,如果不合法可以不给赋值data=1,它会直接进下一循环不敲击中判断出来。
				char c = _getch();   //获取 敲击键操作
				switch (c) {
				case DOWN:if (judgestop(shape, form, x, y + 1) == 1) {   //如果不合法

					deleteblock(shape, form, x, y);
					y++;
				}

						 break;
				case LEFT:
					if (judgestop(shape, form, x - 1, y) == 1) {
						deleteblock(shape, form, x, y);

						x--;
					}
					break;
				case RIGHT:if (judgestop(shape, form, x + 1, y) == 1)
				{
					deleteblock(shape, form, x, y);

					x++;
				}
						  break;
				case SPACE:if (judgestop(shape, (form + 1) % 4, x, y + 1) == 1) {


					deleteblock(shape, form, x, y);
					y++;
					form = (form + 1) % 4;  //翻转

				}break;

				case ENTER:if (flag == 3 && judgestop(shape, (form + 1) % 4, x, y + 1) == 1) {

					deleteblock(shape, form, x, y);
					y++;
					shape = (shape + 1) % 7;  //翻转
				}break;
				case 's':
				case 'S':
					system("pause>nul"); break;
				case 'r':
				case 'R': system("cls"); main();       //重新游戏
				}

			}
		}
		deleteblock(nextshape, nextform, COL + 3, 2); shape = nextshape; form = nextform;
	}
	return;
}

你可能感兴趣的:(c语言,c++,开发语言)