俄罗斯方块游戏的逆向分析与改进
俄罗斯方块游戏的逆向分析与改进
目录
- 来源
- 运行环境与结果
- 主要问题与改进思路
- 新代码
- 重构的软件测试
- 总结
一、来源
https://blog.csdn.net/Peter1X/article/details/139753375
二、运行环境与结果
1.运行环境
- 操作系统:Windows 10/11
- 编译器:Dev-C++ 5.11 / Visual Studio 2022、MinGW/GCC
2.运行结果
开始界面

游戏界面


游戏结束界面

点击查看代码
#include<iostream>
#include<string>
#include<cstdlib>
#include<windows.h>
#include<ctime>
#include<conio.h>
#include<cstdio>
using namespace std;
class Tetris
{
private:
int rank; //游戏难度等级
int score; // 得分
int id; //图形ID
int point[2]; //两基点
int top; //最高点高度
public:
Tetris();
void Welocme(); //首界面
void DrawMap(); //游戏界面
void SetColor(int); //控制颜色
void Draw(int, int, int); //画图形
void Run(); //运行游戏
void ReDraw(int, int, int); //清除图形
bool Judge(int, int, int);
void Turn(int); //旋转
void Updata(); // 更新界面
void Pause(); //游戏暂停
void Input_score();
};
const int sharp[15][8] = //组成图形的各个点的各个坐标,先纵后横
{
{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
{0,0,1,0,0,1,1,1},
{0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0},
{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1},
{0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},
{0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1}
};
const int high[15] = { 4,1,2,2,3,2,3,2,3,2,3,2,3,2,3 };
int map[28][16];
#define a1 0 //条形
#define a2 1
#define b 2 // 方块
#define c1 3 //L形
#define c2 4
#define c3 5
#define c4 6
#define d1 7 //T形
#define d2 8
#define d3 9
#define d4 10
#define e1 11 //闪电1形
#define e2 12
#define f1 13 //闪电2形
#define f2 14
Tetris::Tetris() //构造函数, 初始化各个值
{
point[0] = 0;
point[1] = 5;
score = 0;
top = 25;
}
void Tetris::Turn(int num) //旋转函数
{
switch (num)
{
case a1: id = a2; break; //条形互换
case a2: id = a1; break;
case b: id = b; break; //方块无法旋转
case c1: id = c2; break; //各种L形互换
case c2: id = c3; break;
case c3: id = c4; break;
case c4: id = c1; break;
case d1: id = d2; break; //各种T形互换
case d2: id = d3; break;
case d3: id = d4; break;
case d4: id = d1; break;
case e1: id = e2; break; //两种闪电形互换
case e2: id = e1; break;
case f1: id = f2; break;
case f2: id = f1; break;
}
}
void SetPos(int i, int j) //控制光标位置, 列, 行
{
COORD pos = { i,j };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void Tetris::Pause() // 暂停函数
{
SetPos(32, 10);
cout << "游戏暂停!" << endl;
SetPos(30, 11);
cout << "你的分数为 " << score;
char temp;
while (1)
{
while (1)
{
if (_kbhit())
{
temp = _getch();
break;
}
}
if (temp == 32)
break;
}
SetPos(32, 10); // 清除暂停时显示的信息
cout << " ";
SetPos(30, 11);
cout << " ";
}
void Tetris::Updata() //更新函数
{
int i, flag;
int nx, ny;
for (i = 0; i < 4; i++)
{
nx = point[0] + sharp[id][i * 2];
ny = point[1] + sharp[id][i * 2 + 1];
SetPos((ny + 1) * 2, nx + 1);
SetColor(0);
cout << "■";
map[nx][ny] = 1; //界面各个点是否为空的更新
}
if (point[0] < top)
top = point[0]; //最高点的更新
for (i = point[0]; i < point[0] + high[id]; i++) //消除行
{
flag = 1;
for (int j = 0; j < 13; j++) //判定某一行是否满, 用flag来标记
if (map[i][j] == 0)
flag = 0;
if (flag == 1)
{
for (int k = i; k >= top; k--)
{
for (int p = 0; p < 13; p++)
{
map[k][p] = map[k - 1][p];
SetPos((p + 1) * 2, k + 1);
if (map[k][p] == 1)
cout << "■";
else cout << " ";
}
}
score += 10;
Input_score();
}
}
}
void Tetris::Input_score()
{
SetColor(3);
SetPos(30, 19);
cout << "得分: " << score;
}
void Tetris::Welocme() //欢迎界面
{
SetColor(1);
char x;
while (1)
{
system("cls");
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << " 俄罗斯方块 " << endl;
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << " 操作方式:" << endl;
cout << " ↑ - 旋转" << endl;
cout << " ↓ - 加速下移" << endl;
cout << " ← - 左移" << endl;
cout << " → - 右移" << endl;
cout << " 空格 - 暂停" << endl;
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << "■ 按1—3选择难度■" << endl;
SetPos(20, 10);
x = getchar();
if (x <= '9' && x >= '0')
{
rank = x - '0';
break;
}
}
}
void Tetris::SetColor(int color_num) //设置颜色
{
int n;
switch (color_num)
{
case 0: n = 0x08; break;
case 1: n = 0x0C; break;
case 2: n = 0x0D; break;
case 3: n = 0x0E; break;
case 4: n = 0x0A; break;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}
void Tetris::DrawMap() //画游戏时界面
{
int i;
SetColor(0);
for (i = 0; i < 24; i++) //宽24格
{
SetPos(i * 2, 0);
cout << "■";
SetPos(i * 2, 26);
cout << "■";
}
for (i = 0; i < 26; i++) //高26格
{
SetPos(0, i);
cout << "■";
SetPos(28, i);
cout << "■";
SetPos(46, i);
cout << "■";
}
for (i = 14; i < 24; i++)
{
SetPos(i * 2, 16);
cout << "■";
}
SetColor(3);
Input_score();
SetPos(30, 21);
cout << "难度等级: " << rank;
SetPos(32, 2);
cout << "下一图形";
}
void Tetris::Draw(int x, int y, int num) //画图形
{
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
SetPos((ny + 1) * 2, nx + 1);
SetColor(i + 1);
cout << "■";
}
}
void Tetris::ReDraw(int x, int y, int num) //为更新图形的位置清除图形
{
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
SetPos((ny + 1) * 2, nx + 1);
cout << " ";
}
}
bool Tetris::Judge(int x, int y, int num) //判定在x, y 所指位置是否可画编号为
{ //num 的图形, 若不可画则反回true
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
if (!(nx < 25 && nx >= 0 && ny < 13 && ny >= 0 && !map[nx][ny]))
return true;
}
return false;
}
void Tetris::Run() //运行游戏
{
int next_id;
srand((int)time(0));
id = rand() % 15;
next_id = rand() % 15;
Draw(point[0], point[1], id);
Draw(5, 16, next_id);
int count;
if (rank == 1)
count = 150;
else if (rank == 2)
count = 100;
else if (rank==3)
count = 50;
else
count = 5;
int i = 0; //不同等级对应不同count
while (1)
{
if (!(i < count)) //i 与 count 用于控制时间
{
i = 0;
if (Judge(point[0] + 1, point[1], id)) //在某一位置不能下落的话
{
Updata();
id = next_id;
ReDraw(5, 16, next_id);
next_id = rand() % 15;
point[0] = 0; point[1] = 5;
Draw(point[0], point[1], id);
Draw(5, 16, next_id);
if (Judge(point[0], point[1], id))
{
system("cls");
SetPos(20, 10);
cout << "游戏结束!" << endl;
SetPos(20, 11);
cout << "你的分数为 " << score << endl;
system("pause");
exit(1);
}
}
else //继续下落
{
ReDraw(point[0], point[1], id);
point[0]++;
Draw(point[0], point[1], id);
}
}
if (_kbhit()) //键盘输入值时
{
int key, key2;
key = _getch();
if (key == 224)
{
key2 = _getch();
if (key2 == 72) //按向上方向键时
{
int temp = id;
Turn(id);
if (Judge(point[0], point[1], id))
id = temp;
ReDraw(point[0], point[1], temp);
Draw(point[0], point[1], id);
}
if (key2 == 80) //按向下方向键时
{
if (!Judge(point[0] + 2, point[1], id))
{
ReDraw(point[0], point[1], id);
point[0] += 2;
Draw(point[0], point[1], id);
}
}
else if (key2 == 75) //按向左方向键时
{
if (!Judge(point[0], point[1] - 1, id))
{
ReDraw(point[0], point[1], id);
point[1]--;
Draw(point[0], point[1], id);
}
}
else if (key2 == 77) //按向右方向键时
{
if (!Judge(point[0], point[1] + 1, id))
{
ReDraw(point[0], point[1], id);
point[1]++;
Draw(point[0], point[1], id);
}
}
}
else if (key == 32) // 按下空格暂停
Pause();
}
Sleep(1); //等待1毫秒
i++; //控制下落间隔
}
}
int main()
{
Tetris game;
game.Welocme();
system("cls"); //清除欢迎界面
game.DrawMap();
game.Run();
}
三、主要问题及改善思路
| 序号 | 问题描述 | 改进思路 |
|---|---|---|
| 1 | 缺乏游戏难度实际效果:难度只影响下落速度,与得分无关 | 增加难度系数对得分的影响:消除一行基础得 10 分,根据当前难度额外加分 |
| 2 | 游戏暂停时无法退出:暂停后只能按空格继续,缺乏中途退出的选项 | 添加暂停时的退出选项 |
| 3 | 图形旋转系统不完整:原代码 Turn() 函数仅简单切换 ID,未基于当前坐标计算旋转后的位置 | 重构旋转算法,基于数学矩阵旋转,计算旋转后的坐标 |
| 4 | 难度选择逻辑存在缺陷:输入非 1-3 的数字时,难度直接设为 50ms 间隔(过难),无提示信息 | 增加难度输入校验,仅允许 1-3,非有效值提示重新输入 |
| 5 | 游戏结束后直接退出:无重新开始选项,体验感差 | 游戏结束后增加 “按 R 重新开始 / 按 ESC 退出” 选项 |
四、新代码
点击查看代码
#include<iostream>
#include<string>
#include<cstdlib>
#include<windows.h>
#include<ctime>
#include<conio.h>
#include<cstdio>
using namespace std;
// 全局函数声明
void SetPos(int i, int j);
class Tetris
{
private:
int rank; //游戏难度等级
int score; // 得分
int id; //图形ID
int point[2]; //两基点
int top; //最高点高度
public:
Tetris();
void Welcome(); //首界面
void DrawMap(); //游戏界面
void SetColor(int); //控制颜色
void Draw(int, int, int); //画图形
void Run(); //运行游戏
void ReDraw(int, int, int); //清除图形
bool Judge(int, int, int);
int GetRotatedId(int); //获取旋转后的ID
void Update(); // 更新界面
void Pause(); //游戏暂停
void InputScore();
bool RestartPrompt(); //游戏结束提示并返回是否重新开始
void ResetGame(); //重置游戏状态
};
const int sharp[15][8] = //组成图形的各个点的各个坐标,先纵后横
{
{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
{0,0,1,0,0,1,1,1},
{0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0},
{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1},
{0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},
{0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1}
};
const int high[15] = { 4,1,2,2,3,2,3,2,3,2,3,2,3,2,3 };
int map[28][16];
// 定义每种图形的旋转序列
const int rotateSequence[15][4] = {
{0,1,0,1}, // 条形:0<->1
{1,0,1,0}, // 条形:1<->0
{2,2,2,2}, // 方块:不变
{3,4,5,6}, // L形:3->4->5->6->3
{4,5,6,3}, // L形
{5,6,3,4}, // L形
{6,3,4,5}, // L形
{7,8,9,10}, // T形:7->8->9->10->7
{8,9,10,7}, // T形
{9,10,7,8}, // T形
{10,7,8,9}, // T形
{11,12,11,12}, // 闪电1:11<->12
{12,11,12,11}, // 闪电1
{13,14,13,14}, // 闪电2:13<->14
{14,13,14,13} // 闪电2
};
#define a1 0 //条形
#define a2 1
#define b 2 // 方块
#define c1 3 //L形
#define c2 4
#define c3 5
#define c4 6
#define d1 7 //T形
#define d2 8
#define d3 9
#define d4 10
#define e1 11 //闪电1形
#define e2 12
#define f1 13 //闪电2形
#define f2 14
// 全局函数定义
void SetPos(int i, int j) //控制光标位置, 列, 行
{
COORD pos = { (SHORT)i, (SHORT)j };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
Tetris::Tetris() //构造函数, 初始化各个值
{
point[0] = 0;
point[1] = 5;
score = 0;
top = 25;
rank = 1; //默认难度
}
int Tetris::GetRotatedId(int currentId) {
// 获取当前图形旋转90度后的ID
// 对于每种图形,我们按照预定义的旋转序列返回下一个ID
return rotateSequence[currentId][1]; // 返回旋转90度后的ID
}
void Tetris::Pause() // 暂停函数(显示在右侧空白处)
{
// 在右侧空白区域显示暂停信息(从第30列开始)
SetColor(2);
SetPos(32, 10);
cout << "══════════════" << endl;
SetPos(32, 11);
cout << " 游戏暂停!" << endl;
SetPos(32, 12);
cout << "══════════════" << endl;
SetPos(32, 13);
cout << " 你的分数: " << score << endl;
SetPos(32, 14);
cout << "══════════════" << endl;
SetPos(32, 15);
cout << " 空格键: 继续" << endl;
SetPos(32, 16);
cout << " ESC键: 退出" << endl;
SetPos(32, 17);
cout << "══════════════" << endl;
char temp;
while (1)
{
while (1)
{
if (_kbhit())
{
temp = _getch();
break;
}
}
if (temp == 32) { // 空格键
break;
}
else if (temp == 27) { // ESC键
system("cls");
SetPos(30, 10);
cout << "游戏已退出!" << endl;
SetPos(30, 11);
cout << "最终得分: " << score << endl;
SetPos(30, 12);
system("pause");
exit(0);
}
}
// 清除暂停时显示的信息
for (int i = 10; i <= 17; i++) {
SetPos(32, i);
cout << " ";
}
}
void Tetris::Update() //更新函数
{
int i, flag;
int nx, ny;
for (i = 0; i < 4; i++)
{
nx = point[0] + sharp[id][i * 2];
ny = point[1] + sharp[id][i * 2 + 1];
SetPos((ny + 1) * 2, nx + 1);
SetColor(0);
cout << "■";
map[nx][ny] = 1; //界面各个点是否为空的更新
}
if (point[0] < top)
top = point[0]; //最高点的更新
for (i = point[0]; i < point[0] + high[id]; i++) //消除行
{
flag = 1;
for (int j = 0; j < 13; j++) //判定某一行是否满, 用flag来标记
if (map[i][j] == 0)
flag = 0;
if (flag == 1)
{
for (int k = i; k >= top; k--)
{
for (int p = 0; p < 13; p++)
{
map[k][p] = map[k - 1][p];
SetPos((p + 1) * 2, k + 1);
if (map[k][p] == 1)
cout << "■";
else cout << " ";
}
}
// 基础得分10分,根据难度等级乘以系数
int baseScore = 10;
float difficultyMultiplier;
switch(rank) {
case 1: difficultyMultiplier = 1.0; break;
case 2: difficultyMultiplier = 1.5; break;
case 3: difficultyMultiplier = 2.0; break;
default: difficultyMultiplier = 1.0;
}
score += (int)(baseScore * difficultyMultiplier);
InputScore();
}
}
}
void Tetris::InputScore()
{
SetColor(3);
SetPos(30, 19);
cout << "得分: " << score;
}
void Tetris::Welcome() //欢迎界面(调整难度选择和错误提示位置)
{
SetColor(1);
char x;
while (1)
{
system("cls");
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << " 俄罗斯方块 " << endl;
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << " 操作方式:" << endl;
cout << " ↑ - 旋转" << endl;
cout << " ↓ - 加速下移" << endl;
cout << " ← - 左移" << endl;
cout << " → - 右移" << endl;
cout << " 空格 - 暂停" << endl;
cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
cout << "请选择难度 (1-3): ";
x = _getch(); // 直接在同一行获取输入
if (x >= '1' && x <= '3')
{
rank = x - '0';
cout << rank << endl; // 显示选择的难度并换行
cout << "您选择了难度 " << rank << endl;
break;
}
else
{
// 在同一行显示错误提示
cout << " 错误!请输入1-3之间的数字" << endl;
Sleep(1000); // 显示提示1秒
// 使用SetPos清空上一行
SetPos(0, 11); // 移动到输入行(第11行)
cout << " "; // 清空该行
SetPos(23, 11); // 移回输入位置
}
}
cout << "\n按任意键开始游戏...";
_getch();
}
void Tetris::SetColor(int color_num) //设置颜色
{
int n;
switch (color_num)
{
case 0: n = 0x08; break;
case 1: n = 0x0C; break;
case 2: n = 0x0D; break;
case 3: n = 0x0E; break;
case 4: n = 0x0A; break;
default: n = 0x07; break;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}
void Tetris::DrawMap() //画游戏时界面
{
int i;
SetColor(0);
for (i = 0; i < 24; i++) //宽24格
{
SetPos(i * 2, 0);
cout << "■";
SetPos(i * 2, 26);
cout << "■";
}
for (i = 0; i < 26; i++) //高26格
{
SetPos(0, i);
cout << "■";
SetPos(28, i);
cout << "■";
SetPos(46, i);
cout << "■";
}
for (i = 14; i < 24; i++)
{
SetPos(i * 2, 16);
cout << "■";
}
SetColor(3);
InputScore();
SetPos(30, 21);
cout << "难度等级: " << rank;
// 显示难度系数
float multiplier;
switch(rank) {
case 1: multiplier = 1.0; break;
case 2: multiplier = 1.5; break;
case 3: multiplier = 2.0; break;
default: multiplier = 1.0;
}
SetPos(30, 22);
cout << "得分系数: " << multiplier << "倍";
SetPos(32, 2);
cout << "下一图形";
}
void Tetris::Draw(int x, int y, int num) //画图形
{
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
SetPos((ny + 1) * 2, nx + 1);
SetColor(i + 1);
cout << "■";
}
}
void Tetris::ReDraw(int x, int y, int num) //为更新图形的位置清除图形
{
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
SetPos((ny + 1) * 2, nx + 1);
cout << " ";
}
}
bool Tetris::Judge(int x, int y, int num) //判定在x, y 所指位置是否可画编号为
{ //num 的图形, 若不可画则返回true
int nx, ny;
for (int i = 0; i < 4; i++)
{
nx = x + sharp[num][2 * i];
ny = y + sharp[num][2 * i + 1];
if (nx < 0 || nx >= 25 || ny < 0 || ny >= 13 || map[nx][ny] == 1)
return true;
}
return false;
}
void Tetris::ResetGame() {
// 重置地图
for (int i = 0; i < 28; i++) {
for (int j = 0; j < 16; j++) {
map[i][j] = 0;
}
}
// 重置游戏状态
point[0] = 0;
point[1] = 5;
score = 0;
top = 25;
}
bool Tetris::RestartPrompt() {
system("cls");
SetColor(1);
SetPos(30, 10);
cout << "游戏结束!" << endl;
SetPos(28, 11);
cout << "你的最终得分: " << score << endl;
SetPos(25, 12);
cout << "按 R 重新开始 / 按 ESC 退出" << endl;
char temp;
while (1) {
while (1) {
if (_kbhit()) {
temp = _getch();
break;
}
}
if (temp == 'r' || temp == 'R') {
ResetGame();
return true; // 重新开始
}
else if (temp == 27) { // ESC
return false; // 退出
}
}
}
void Tetris::Run() //运行游戏
{
bool restart;
do {
restart = false;
int next_id;
srand((int)time(0));
id = rand() % 15;
next_id = rand() % 15;
Draw(point[0], point[1], id);
Draw(5, 16, next_id);
int count;
if (rank == 1)
count = 150;
else if (rank == 2)
count = 100;
else if (rank == 3)
count = 50;
else
count = 5;
int i = 0; //不同等级对应不同count
while (1)
{
if (!(i < count)) //i 与 count 用于控制时间
{
i = 0;
if (Judge(point[0] + 1, point[1], id)) //在某一位置不能下落的话
{
Update();
id = next_id;
ReDraw(5, 16, next_id);
next_id = rand() % 15;
point[0] = 0; point[1] = 5;
Draw(point[0], point[1], id);
Draw(5, 16, next_id);
if (Judge(point[0], point[1], id))
{
// 游戏结束,显示重新开始选项
if (RestartPrompt()) {
// 重新开始游戏
system("cls");
DrawMap();
restart = true;
break;
} else {
// 退出游戏
system("cls");
SetPos(30, 10);
cout << "感谢游玩!" << endl;
SetPos(30, 11);
system("pause");
exit(0);
}
}
}
else //继续下落
{
ReDraw(point[0], point[1], id);
point[0]++;
Draw(point[0], point[1], id);
}
}
if (_kbhit()) //键盘输入值时
{
int key, key2;
key = _getch();
if (key == 224)
{
key2 = _getch();
if (key2 == 72) //按向上方向键时 - 旋转
{
int newId = GetRotatedId(id); // 获取旋转后的ID
// 检查旋转后是否合法
if (!Judge(point[0], point[1], newId))
{
// 清除原图形
ReDraw(point[0], point[1], id);
// 更新ID
id = newId;
// 绘制新图形
Draw(point[0], point[1], id);
}
}
else if (key2 == 80) //按向下方向键时
{
if (!Judge(point[0] + 2, point[1], id))
{
ReDraw(point[0], point[1], id);
point[0] += 2;
Draw(point[0], point[1], id);
}
}
else if (key2 == 75) //按向左方向键时
{
if (!Judge(point[0], point[1] - 1, id))
{
ReDraw(point[0], point[1], id);
point[1]--;
Draw(point[0], point[1], id);
}
}
else if (key2 == 77) //按向右方向键时
{
if (!Judge(point[0], point[1] + 1, id))
{
ReDraw(point[0], point[1], id);
point[1]++;
Draw(point[0], point[1], id);
}
}
}
else if (key == 32) // 按下空格暂停
Pause();
}
Sleep(1); //等待1毫秒
i++; //控制下落间隔
}
} while (restart);
}
int main()
{
Tetris game;
game.Welcome();
system("cls"); //清除欢迎界面
game.DrawMap();
game.Run();
return 0;
}
五、重构的软件测试
开始界面

若难度输入错误

游戏界面


游戏暂停界面

游戏结束界面

六、总结
难点:
- 图形旋转算法的重构:
原代码仅通过切换图形 ID 实现 “伪旋转”,未基于坐标矩阵计算真实旋转位置,需要通过数学公式推导旋转后位置,并配合 Judge 碰撞检测,防止穿墙或重叠,这是耗时最久、调试难度最大的环节。 - 流程与状态管理:
新增难度校验、暂停退出、重新开始等逻辑,需要重构原有循环结构,确保状态切换不乱、变量不残留。 - 视觉与体验优化:
消除行、旋转失败的反馈效果,需要精确控制颜色与延时,既要醒目又不卡顿。
对于逆向软件工程的思考
在对俄罗斯方块原始程序进行逆向分析与二次开发的过程中,我深刻体会到逆向软件工程的核心在于 “先理解,再优化”。逆向工程不是简单修复 bug,而是从整体流程、设计思路、编码规范和用户体验等角度,重新审视一份未完成或不成熟的代码。原始代码虽然实现了基本功能,但存在全局变量滥用、命名不规范、旋转逻辑不完整、缺乏输入校验和体验反馈等问题,这些都是初学者代码中常见的工程缺陷。这一过程让我认识到,逆向工程的真正价值在于还原设计思想、修补工程短板,并在原有基础上做增量式提升,使项目更接近工业级产品的标准。
浙公网安备 33010602011771号