using namespace std;
const int Width = 20; // 游戏区域宽度
const int Height = 20; // 游戏区域高度
int board[Height][Width] = { 0 }; // 游戏区域
// 方块数据结构
struct Block
{
int shape[4][4]; // 方块形状
int x, y; // 方块位置
} block;
void initBlock() // 初始化方块
{
int shapes[7][4][4] = {
{ { 1,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // 口口
{ { 0,2,0,0 },{ 2,2,2,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // 工
{ { 3,0,0,0 },{ 3,3,3,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // L
{ { 0,0,4,0 },{ 4,4,4,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // J
{ { 0,5,5,0 },{ 5,5,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // 田
{ { 0,0,6,0 },{ 6,6,6,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, // Z
{ { 7,7,0,0 },{ 0,7,7,0 },{ 0,0,0,0 },{ 0,0,0,0 } } // 反Z
};
int rand_shape = rand() % 7;
memcpy(&block.shape, &shapes[rand_shape], sizeof(block.shape));
block.x = Width / 2 - 1;
block.y = 0;
}
bool check(int x, int y) // 检查方块是否越界或与已有方块重合
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (block.shape[i][j] != 0 && (x + j < 0 || x + j >= Width || y + i >= Height || board[y + i][x + j] != 0))
{
return false;
}
}
}
return true;
}
void draw() // 绘制游戏区域和方块
{
system("cls"); // 清屏
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++)
{
if (board[i][j] == 0)
{
cout << " ";
}
else
{
cout << "口";
}
}
cout << endl;
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (block.shape[i][j] != 0)
{
COORD pos = { (SHORT)(2 * (block.x + j)), (SHORT)(block.y + i) };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
cout << "口";
}
}
}
}
void merge() // 将方块与已有方块合并
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (block.shape[i][j] != 0)
{
board[block.y + i][block.x + j] = block.shape[i][j];
}
}
}
}
void checkLine() // 检测是否有满行
{
for (int i = Height - 1; i >= 0; i--)
{
bool full = true;
for (int j = 0; j < Width; j++)
{
if (board[i][j] == 0)
{
full = false;
break;
}
}
if (full)
{
for (int k = i; k > 0; k--)
{
memcpy(board[k], board[k - 1], sizeof(board[k]));
}
memset(board[0], 0, sizeof(board[0]));
i++;
}
}
}
int main()
{
srand((unsigned)time(NULL)); // 初始化随机数生成器
while (true)
{
initBlock();
while (true)
{
draw();
Sleep(500); // 控制方块下落速度
if (check(block.x, block.y + 1)) // 方块下落
{
block.y++;
}
else // 方块到达底部
{
merge();
checkLine();
break;
}
if (_kbhit()) // 检测键盘输入
{
int key = _getch();
if (key == 'a' && check(block.x - 1, block.y)) // 左移
{
block.x--;
}
else if (key == 'd' && check(block.x + 1, block.y)) // 右移
{
block.x++;
}
else if (key == 'w') // 旋转
{
Block tmp = block;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
tmp.shape[j][3 - i] = block.shape[i][j];
}
}
if (check(block.x, block.y))
{
memcpy(&block.shape, &tmp.shape, sizeof(block.shape));
}
}
else if (key == 's') // 快速下落
{
while (check(block.x, block.y + 1))
{
block.y++;
}
}
}
}
}
return 0;
}