#include <iostream>
#include <vector>
#include <conio.h> // 用于_getch()
#include <windows.h> // 用于Sleep()
#include <cstdlib> // 用于rand()和srand()
#include <ctime> // 用于time()
// 游戏区域大小
const int WIDTH = 10;
const int HEIGHT = 20;
// 方块形状定义
struct Tetromino {
std::vector<std::vector<int>> shape;
int width, height;
};
class TetrisGame {
private:
std::vector<std::vector<int>> gameGrid;
Tetromino currentPiece;
int currentX, currentY;
int score;
bool gameOver;
// 七种俄罗斯方块形状
std::vector<Tetromino> pieces;
// 初始化所有方块形状
void initPieces() {
// I形
pieces.push_back({{{1,1,1,1}}, 4, 1);
// O形
pieces.push_back({{{1,1},{1,1}}, 2, 2);
// T形
pieces.push_back({{{0,1,0},{1,1,1}}, 3, 2);
// L形
pieces.push_back({{{1,0},{1,0},{1,1}}, 2, 3);
// J形
pieces.push_back({{{0,1},{0,1},{1,1}}, 2, 3);
// S形
pieces.push_back({{{0,1,1},{1,1,0}}, 3, 2);
// Z形
pieces.push_back({{{1,1,0},{0,1,1}}, 3, 2);
}
// 获取随机方块
Tetromino getRandomPiece() {
return pieces[rand() % pieces.size()];
}
// 检查碰撞
bool checkCollision(int x, int y, const Tetromino& piece) {
for (int py = 0; py < piece.height; ++py) {
for (int px = 0; px < piece.width; ++px) {
if (piece.shape[py][px] == 0) continue;
int newX = x + px;
int newY = y + py;
if (newX < 0 || newX >= WIDTH || newY >= HEIGHT) {
return true;
}
if (newY >= 0 && gameGrid[newY][newX] != 0) {
return true;
}
}
}
return false;
}
// 合并方块到游戏区域
void mergePiece() {
for (int py = 0; py < currentPiece.height; ++py) {
for (int px = 0; px < currentPiece.width; ++px) {
if (currentPiece.shape[py][px] != 0) {
gameGrid[currentY + py][currentX + px] = 1;
}
}
}
}
// 旋转方块
void rotatePiece() {
Tetromino rotated;
rotated.width = currentPiece.height;
rotated.height = currentPiece.width;
rotated.shape.resize(rotated.height, std::vector<int>(rotated.width, 0));
for (int y = 0; y < currentPiece.height; ++y) {
for (int x = 0; x < currentPiece.width; ++x) {
rotated.shape[x][currentPiece.height - 1 - y] = currentPiece.shape[y][x];
}
}
if (!checkCollision(currentX, currentY, rotated)) {
currentPiece = rotated;
}
}
// 清除已满的行
void clearLines() {
for (int y = HEIGHT-1; y >= 0; --y) {
bool lineFull = true;
for (int x = 0; x < WIDTH; ++x) {
if (gameGrid[y][x] == 0) {
lineFull = false;
break;
}
}
if (lineFull) {
// 移除该行并增加分数
gameGrid.erase(gameGrid.begin() + y);
gameGrid.insert(gameGrid.begin(), std::vector<int>(WIDTH, 0));
score += 100;
y++; // 重新检查当前行,因为上面的行下移了
}
}
}
public:
TetrisGame() : score(0), gameOver(false) {
// 初始化游戏区域
gameGrid.resize(HEIGHT, std::vector<int>(WIDTH, 0));
// 初始化方块形状
initPieces();
// 生成第一个方块
spawnPiece();
}
// 生成新方块
void spawnPiece() {
currentPiece = getRandomPiece();
currentX = WIDTH / 2 - currentPiece.width / 2;
currentY = -currentPiece.height + 1;
// 检查游戏是否结束
if (checkCollision(currentX, currentY, currentPiece)) {
gameOver = true;
}
}
// 绘制游戏界面
void draw() {
system("cls");
// 绘制上边界
for (int i = 0; i < WIDTH+2; ++i)
std::cout << "#";
std::cout << std::endl;
// 绘制游戏区域
for (int y = 0; y < HEIGHT; ++y) {
std::cout << "#"; // 左边界
for (int x = 0; x < WIDTH; ++x) {
// 检查是否在活动方块内
bool inPiece = false;
if (y >= currentY && y < currentY + currentPiece.height &&
x >= currentX && x < currentX + currentPiece.width) {
int px = x - currentX;
int py = y - currentY;
if (py >= 0 && currentPiece.shape[py][px] != 0) {
inPiece = true;
}
}
if (inPiece) {
std::cout << "O";
} else if (gameGrid[y][x] != 0) {
std::cout << "X";
} else {
std::cout << " ";
}
}
std::cout << "#" << std::endl; // 右边界
}
// 绘制下边界
for (int i = 0; i < WIDTH+2; ++i)
std::cout << "#";
std::cout << std::endl;
std::cout << "Score: " << score << std::endl;
std::cout << "Controls: A-left, D-right, W-rotate, S-drop" << std::endl;
}
// 处理输入
void input() {
if (_kbhit()) {
switch (_getch()) {
case 'a': // 左移
if (!checkCollision(currentX-1, currentY, currentPiece))
currentX--;
break;
case 'd': // 右移
if (!checkCollision(currentX+1, currentY, currentPiece))
currentX++;
break;
case 's': // 快速下落
while (!checkCollision(currentX, currentY+1, currentPiece)) {
currentY++;
}
break;
case 'w': // 旋转
rotatePiece();
break;
case 'x': // 退出
gameOver = true;
break;
}
}
}
// 更新游戏逻辑
void update() {
// 方块下落
if (!checkCollision(currentX, currentY+1, currentPiece)) {
currentY++;
} else {
// 方块落地
mergePiece();
clearLines();
spawnPiece();
}
}
bool isGameOver() const { return gameOver; }
};
int main() {
srand(static_cast<unsigned>(time(0)));
TetrisGame game;
while (!game.isGameOver()) {
game.draw();
game.input();
game.update();
Sleep(300); // 控制下落速度
}
std::cout << "Game Over! Final Score: " << std::endl;
system("pause");
return 0;
}