CODE:
#include <SFML/[Link]>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace sf;
using namespace std;
const int WIDTH = 10; // Grid width
const int HEIGHT = 20; // Grid height
const int BLOCK_SIZE = 30; // Block size in pixels
// Define Tetromino shapes using 4 blocks
int tetrominoShapes[7][4] = {
{1, 3, 5, 7}, // I shape
{2, 4, 5, 7}, // Z shape
{3, 5, 4, 6}, // S shape
{3, 5, 4, 7}, // T shape
{2, 3, 5, 7}, // L shape
{3, 5, 7, 6}, // J shape
{2, 3, 4, 5} // O shape
};
class Tetris {
private:
bool gameOver;
RenderWindow window;
vector<vector<int>> grid;
RectangleShape block;
int currentShape;
int rotation;
int x, y; // Position of the current piece
int score; // Player's score
// Colors for different Tetrominoes
Color colors[7] = {
Color::Cyan, // I
Color::Red, // Z
Color::Green, // S
Color::Yellow, // T
Color::Blue, // L
Color::Magenta, // J
Color::White // O
};
Clock fallClock; // Timer for controlling block fall speed
float fallTime; // Time between automatic falls
const float fallSpeed = 0.5f; // Control the speed of block fall
Font font;
Text scoreText;
public:
Tetris() {
[Link](VideoMode(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE), "Tetris");
[Link](60);
// Initialize the grid with zeros (empty spaces)
[Link](HEIGHT, vector<int>(WIDTH, 0));
[Link](Vector2f(BLOCK_SIZE - 1, BLOCK_SIZE - 1)); // Block size with margin
[Link](Color::White);
srand(time(0)); // Seed for random generation
spawnNewPiece();
fallTime = 0.0f;
score = 0; // Initialize score
gameOver = false;
if () {
cerr << "Error loading font" << endl;
exit(1);
[Link](font);
[Link](24);
[Link](Color::White);
[Link](10, 10);
updateScoreText();
void updateScoreText() {
[Link]("Score: " + to_string(score));
}
void spawnNewPiece() {
currentShape = rand() % 7; // Randomly select a shape
rotation = 0; // Starting rotation
x = WIDTH / 2 - 2; // Start at the middle of the grid
y = 0; // Start at the top of the grid
bool checkCollision() {
// Check if the current piece collides with the walls or other blocks
for (int i = 0; i < 4; ++i) {
int px = x + (tetrominoShapes[currentShape][i] % 2);
int py = y + (tetrominoShapes[currentShape][i] / 2);
if (px < 0 || px >= WIDTH || py >= HEIGHT || grid[py][px]) {
return true;
return false;
void rotatePiece() {
rotation = (rotation + 1) % 4;
void movePiece(int dx, int dy) {
x += dx;
y += dy;
if (checkCollision()) {
x -= dx;
y -= dy;
if (dy > 0) { // Piece reached the bottom, so place it on the grid
placePiece();
spawnNewPiece();
void placePiece() {
for (int i = 0; i < 4; ++i) {
int px = x + (tetrominoShapes[currentShape][i] % 2);
int py = y + (tetrominoShapes[currentShape][i] / 2);
// Debugging output
cout << "Placing block at: (" << px << ", " << py << ")" << endl;
grid[py][px] = currentShape + 1; // Store the piece number
clearFullLines();
// Check for game over (any block in the top row)
for (int j = 0; j < WIDTH; ++j) {
if (grid[0][j] != 0) { // If any cell in the top row is occupied
cout << "Game over: Block at top row" << endl; // Debugging output
gameOver = true;
return;
}
}
void clearFullLines() {
for (int i = HEIGHT - 1; i >= 0; --i) {
bool fullLine = true;
for (int j = 0; j < WIDTH; ++j) {
if (grid[i][j] == 0) {
fullLine = false;
break;
if (fullLine) {
for (int k = i; k > 0; --k) {
grid[k] = grid[k - 1];
grid[0] = vector<int>(WIDTH, 0); // Clear the top row
score += 100; // Increment score for clearing a line
updateScoreText();
i++; // Recheck this row
void draw() {
[Link]();
// Draw the grid
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j) {
if (grid[i][j] != 0) {
[Link](colors[grid[i][j] - 1]);
[Link](j * BLOCK_SIZE, i * BLOCK_SIZE);
[Link](block);
if (!gameOver)
for (int i = 0; i < 4; ++i)
int px = x + (tetrominoShapes[currentShape][i] % 2);
int py = y + (tetrominoShapes[currentShape][i] / 2);
[Link](colors[currentShape]);
[Link](px * BLOCK_SIZE, py * BLOCK_SIZE);
[Link](block);
else
// Draw game over message
Text gameOverText;
[Link](font);
[Link](36);
[Link](Color::Red);
[Link]("Game Over");
[Link](WIDTH * BLOCK_SIZE / 2 - 100, HEIGHT * BLOCK_SIZE / 2 - 50);
[Link](gameOverText);
[Link](scoreText);
[Link]();
void run() {
while ([Link]()) {
Event event;
while ([Link](event)) {
if ([Link] == Event::Closed)
[Link]();
if (!gameOver && [Link] == Event::KeyPressed) {
if ([Link] == Keyboard::Left)
movePiece(-1, 0); // Move left
if ([Link] == Keyboard::Right)
movePiece(1, 0); // Move right
if ([Link] == Keyboard::Down)
movePiece(0, 1); // Move down
if ([Link] == Keyboard::Up)
rotatePiece(); // Rotate piece
if (!gameOver)
// Handle automatic falling with fallClock
if ([Link]().asSeconds() >= fallSpeed)
{
movePiece(0, 1); // Move the piece down
[Link](); // Reset the clock for next fall
else
cout << "Game Over: No further actions allowed." << endl; // Debugging output
draw();
};
int main() {
Tetris game;
[Link]();
return 0;