6
6
// /=============================================================================
7
7
// / C++基础知识:
8
8
// / 1. 预处理(注释、头文件引入、定义宏)
9
- // / 2. 基本数据类型
9
+ // / 2. 数据类型
10
+ // / 1. 基本数据类型与数组
11
+ // / 2. 指针(特殊的基本数据类型)
12
+ // / 3. 引用(特殊的语法糖与语法含义)
10
13
// / 3. 定义类型
11
14
// / 1. 成员变量
12
15
// / 4. 定义变量
13
16
// / 1. 定义基本数据类型变量
14
17
// / 2. 定义结构体类型变量
15
18
// / 2. 定义数组变量
16
19
// / 5. 定义函数
17
- // / 6. 访问变量
18
- // / 7. 调用函数
19
- // / 8. (自定义)类型的内存结构
20
- // / 9. 函数的调用过程
20
+ // / 6. 表达式
21
+ // / 1. 访问变量
22
+ // / 2. 调用函数
23
+ // / 7. 逻辑语句
24
+ // / 1. 条件语句 if switch(case default break)
25
+ // / 2. 循环语句 for while do..while -- continue break
26
+ // / 3. 跳转语句 goto
27
+ // / 8. 入口函数
28
+ // / 9. (自定义)类型的内存结构
29
+ // / 10. 函数的调用过程
21
30
// /=============================================================================
22
31
// / 理解或思想:
23
32
// / 👉 预处理:💡简单的文本替换,提高代码复用
24
- // / 👉 数据类型的作用:💡赋予内存格子含义,或者说💡标注内存的处理方式
33
+ // / 👉 数据类型的作用:💡赋予格子(内存)含义,或者说💡标注内存的处理方式
34
+ // / 👉 指针:💡整数,💡代表格子的地址(编号)
35
+ // / 👉 引用:💡从底层角度看:引用是指针的语法糖,💡从语义角度看:引用是变量别名
25
36
// / 👉 定义(自定义)类型:
26
37
// / 💡确定该类型变量占用的格子数(通过成员变量自动计算大小)
27
38
// / 💡以及每个格子的含义(通过成员变量自动确定每个格子的含义)
30
41
// / 👉 定义函数:💡描述一个过程:输入->处理->输出,即参数->函数体->返回值
31
42
// / 👉 访问变量:💡找到对应格子,按类型含义访问和处理格子内的数据
32
43
// / 👉 调用函数:💡很好理解
44
+ // / 👉 逻辑语句:💡比较+跳转
33
45
// / 👉 (自定义)类型的内存结构:
34
46
// / 💡从避免CPU多次存取内存的角度出发,自动空出格子以提高内存访问效率
35
47
// / 👉 函数的调用过程:
36
48
// / 💡递归!
37
49
// / 💡栈!
38
- // / 💡输入(参数)输出(返回值)通过函数调用栈传递
50
+ // / 💡输入(参数)输出(返回值)通过在函数调用栈上创建变量传递
51
+ // / 💡参数和返回值必须通过复制值的方式传递,指针和引用的特殊之处在于复制(传递)的是地址
39
52
// /=============================================================================
40
53
// / 思想!:
41
54
// / 👉 程序的基本作用:💡内存读写与指令执行
42
55
// / 👉 面向对象-理解方式1:💡数据+算法(过程)
43
56
// / 👉 面向对象-理解方式2:💡变量+函数
44
57
// /=============================================================================
45
58
59
+ // 🏷 头文件引入
46
60
// 引入标准库.算法.函数std::clamp
47
61
#include < algorithm>
48
62
// 引入标准库.函数setlocale
59
73
// * ...
60
74
#include < ncurses.h>
61
75
76
+ // 🏷 定义(全局)变量
62
77
WINDOW *game_window;
63
78
WINDOW *info_window;
64
79
80
+ // 🏷 定义函数
65
81
void CreateWindow () {
66
82
game_window = newwin (20 , 10 , 0 , 0 );
67
83
info_window = newwin (20 , 70 , 0 , 10 );
68
84
}
69
85
86
+ // 🏷 定义函数
70
87
void DestroyWindow () { endwin (); }
71
88
89
+ // 🏷 定义(自定义)类型
72
90
// 定义格子类型
73
91
struct Cell {
74
92
bool has_tetro{};
75
93
};
76
94
95
+ // 🏷 定义(自定义)类型
77
96
// 定义棋盘类型
78
97
struct Board {
79
98
Cell cell[20 ][10 ]{};
80
99
};
81
100
82
- // I O T J L S Z
101
+ // 🏷 定义(自定义)类型
102
+ // 定义四连骨牌类型
103
+ // 四连骨牌有7种形式:I O T J L S Z
83
104
struct Mino {
84
105
// Mi mi[4];
85
106
Cell cell[4 ][4 ]{};
86
107
};
87
108
109
+ // 🏷 定义(全局)变量
88
110
// 定义棋盘变量
89
111
Board board;
90
112
113
+ // 🏷 定义(全局)变量
91
114
// 定义四连骨牌
92
115
Mino mino;
116
+ // 🏷 定义(全局)变量
117
+ // 定义四连骨牌的位置
93
118
int x;
94
119
int y;
95
120
121
+ // 🏷 定义函数
96
122
// 绘制棋盘
97
123
void RenderBoard () {
98
124
// 遍历每个格子
@@ -106,6 +132,9 @@ void RenderBoard() {
106
132
}
107
133
}
108
134
}
135
+
136
+ // 🏷 定义函数
137
+ // 清除磁盘
109
138
void ClearBoard () {
110
139
// 遍历每个格子
111
140
for (int row = 0 ; row < 20 ; ++row) {
@@ -114,6 +143,8 @@ void ClearBoard() {
114
143
}
115
144
}
116
145
}
146
+
147
+ // 🏷 定义函数
117
148
// 绘制四连骨牌
118
149
void RenderMino () {
119
150
// 遍历MINO的每个格子
@@ -126,6 +157,8 @@ void RenderMino() {
126
157
}
127
158
}
128
159
160
+ // 🏷 定义函数
161
+ // 碰撞检测
129
162
bool CollisionDetect (Mino &mino, int x, int y) {
130
163
// 每个mino的骨牌是否产生碰撞
131
164
for (int row = 0 ; row < 4 ; ++row) {
@@ -150,6 +183,8 @@ bool CollisionDetect(Mino &mino, int x, int y) {
150
183
return false ;
151
184
}
152
185
186
+ // 🏷 定义函数
187
+ // 创建四连骨牌
153
188
bool CreateMino () {
154
189
// 随机创建其中一种类型:I O T J L S Z
155
190
std::random_device rd;
@@ -233,6 +268,8 @@ bool CreateMino() {
233
268
return true ;
234
269
}
235
270
271
+ // 🏷 定义函数
272
+ // 下落四连骨牌
236
273
// 落地之后需要其它逻辑,返回值代表是否下落成功
237
274
bool Fall () {
238
275
// 判断能不能下落
@@ -244,6 +281,9 @@ bool Fall() {
244
281
y = y + 1 ;
245
282
return true ;
246
283
}
284
+
285
+ // 🏷 定义函数
286
+ // 使四连骨牌落地,即将四连骨牌分解为单个骨牌放置在棋盘上
247
287
void Land () {
248
288
// 把当前的四连骨牌放在棋盘上
249
289
// 绘制在棋盘上
@@ -256,6 +296,8 @@ void Land() {
256
296
}
257
297
}
258
298
299
+ // 🏷 定义函数
300
+ // 旋转四连骨牌
259
301
void Rotate () {
260
302
// ↻
261
303
// - - - -
@@ -287,12 +329,16 @@ void Rotate() {
287
329
}
288
330
}
289
331
332
+ // 🏷 定义函数
333
+ // 清除棋盘上的一行
290
334
void ClearLine (int y) {
291
335
for (int col = 0 ; col < 10 ; ++col) {
292
336
board.cell [y][col].has_tetro = false ;
293
337
}
294
338
}
295
339
340
+ // 🏷 定义函数
341
+ // 将棋盘上的某一行的上方所有行向下移动一行
296
342
void MoveDownAllAboveLine (int y) {
297
343
for (int row = y; 0 <= row; --row) {
298
344
if (row == 0 ) {
@@ -305,6 +351,8 @@ void MoveDownAllAboveLine(int y) {
305
351
}
306
352
}
307
353
354
+ // 🏷 定义函数
355
+ // 判断棋盘上的某一行是否放满骨牌
308
356
bool IsLineFull (int y) {
309
357
// return std::all_of(&board.cell[y][0], &board.cell[y][10], [](auto
310
358
// &cell){return cell.has_tetro;});
@@ -316,6 +364,8 @@ bool IsLineFull(int y) {
316
364
return true ;
317
365
}
318
366
367
+ // 🏷 定义函数
368
+ // 检查棋盘上的某一行是否放满骨牌、清理放满的行、将清理的行的上方所有骨牌向下移动
319
369
void CheckAndDeleteLine () {
320
370
for (int row = 0 ; row < 20 ; ++row) {
321
371
if (IsLineFull (row)) {
@@ -325,10 +375,13 @@ void CheckAndDeleteLine() {
325
375
}
326
376
}
327
377
378
+ // 🏷 定义宏
328
379
#define GAME_OVER 0
329
380
#define EXIT 1
330
381
#define RESTART 2
331
382
383
+ // 🏷 定义函数
384
+ // 显示欢迎信息
332
385
bool Welcome () {
333
386
wclear (info_window);
334
387
mvwprintw (info_window, 3 , 0 , " Welcome Tetris!" );
@@ -348,6 +401,8 @@ bool Welcome() {
348
401
}
349
402
}
350
403
404
+ // 🏷 定义函数
405
+ // 显示游戏结束信息
351
406
int GameOver () {
352
407
wclear (info_window);
353
408
mvwprintw (info_window, 5 , 0 , " Game Over!" );
@@ -367,6 +422,8 @@ int GameOver() {
367
422
}
368
423
}
369
424
425
+ // 🏷 定义函数
426
+ // 显示游戏帮助信息
370
427
void HelpInfo () {
371
428
wclear (info_window);
372
429
mvwprintw (info_window, 3 , 0 , " Keys:" );
@@ -377,6 +434,8 @@ void HelpInfo() {
377
434
mvwprintw (info_window, 9 , 0 , " e exit" );
378
435
}
379
436
437
+ // 🏷 定义函数
438
+ // 单次游戏循环
380
439
int GameLoop () {
381
440
HelpInfo ();
382
441
ClearBoard ();
@@ -439,6 +498,8 @@ int GameLoop() {
439
498
}
440
499
}
441
500
501
+ // 🏷 定义函数
502
+ // 入口函数
442
503
int main () {
443
504
setlocale (LC_ALL, " " );
444
505
// 初始化界面系统ncurses
0 commit comments