【C语言俄罗斯方块】

"block block"

Posted by 2024级软件工程04班周俊杰 on December 14, 2024

程序特色

判断得分与结束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
int JudeFunc()//判断得分与结束
{
	int i, j, m, n;
	//判断是否得分
	for ( i = ROW - 2; i > 1; i--)
	{
		int sum = 0; //记录第i行的方块个数
		for (j = 1; j < COL - 1; j++)
		{
			sum += face.data[i][j]; //统计第i行的方块个数
		}
		if (sum == 0) //该行没有方块,无需再判断其上的层次(无需再继续判断是否得分)
			break; //跳出循环
		if (sum == COL - 2) //该行全是方块,可得分
		{
			grade += 10; //满一行加10分
			color(7); //颜色设置为白色
			CursorJump(2 * COL + 4, ROW - 3); //光标跳转到显示当前分数的位置
			printf("当前分数:%d", grade); //更新当前分数
			for (int j = 1; j < COL - 1; j++) //清除得分行的方块信息
			{
				face.data[i][j] = 0; //该位置得分后被清除,标记为无方块
				CursorJump(2 * j, i); //光标跳转到该位置
				printf("  "); //打印空格覆盖(两个空格)
			}
			//把被清除行上面的行整体向下挪一格
			for ( m = i; m > 1; m--)
			{
				sum = 0; //记录上一行的方块个数
				for ( n = 1; n < COL - 1; n++)
				{
					sum += face.data[m - 1][n]; //统计上一行的方块个数
					face.data[m][n] = face.data[m - 1][n]; //将上一行方块的标识移到下一行
					face.color[m][n] = face.color[m - 1][n]; //将上一行方块的颜色编号移到下一行
					if (face.data[m][n] == 1) //上一行移下来的是方块,打印方块
					{
						CursorJump(2 * n, m); //光标跳转到该位置
						color(face.color[m][n]); //颜色设置为还方块的颜色
						printf("■"); //打印方块
					}
					else //上一行移下来的是空格,打印空格
					{
						CursorJump(2 * n, m); //光标跳转到该位置
						printf("  "); //打印空格(两个空格)

					}
				}
				if (sum == 0)
					//上一行移下来的全是空格,无需再将上层的方块向下移动(移动结束)
					return 1; //返回1,表示还需调用该函数进行判断(移动下来的可能还有满行)
			}
		}
	}
	//判断游戏是否结束
	for (int j = 1; j < COL - 1; j++)
	{
		if (face.data[1][j] == 1) //顶层有方块存在(以第1行为顶层,不是第0行)
		{
			Sleep(1000); //制造时间差
			system("cls"); //清空屏幕
			color(7); //颜色设置为白色
			CursorJump(2 * (COL / 3), ROW / 2 - 3);
			if (grade > max)
			{
				printf("恭喜你打破最高记录,最高记录更新为%d", grade);
				WriteGrade();
			}
			else if (grade == max)
			{
				printf("与最高记录持平,加油再创佳绩", grade);
			}
			else
			{
				printf("请继续加油,当前与最高记录相差%d", max - grade);
			}
			CursorJump(2 * (COL / 3), ROW / 2);
			printf("GAME OVER");
			while (1)
			{
				char ch;
				CursorJump(2 * (COL / 3), ROW / 2 + 3);
				printf("再来一局?(Y/N):");
				ch = getch();
				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("选择错误,请再次选择");
				}
			}
		}
	}
	return 0; //判断结束,无需再调用该函数进行判断
}

合法性判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//合法性判断
int IsLegal(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) && (face.data[y + i][x + j] == 1))
				return 0; //不合法
		}
	}
	return 1; //合法
}

演示视频