Sunday, March 30, 2025

Part 2: Tetris Game in C programming | Data Structure, Collision detection and Score checking Techniques

Previous Page 



Data Structure

This is a 2D game where the primary object is a box. A combination of 4 boxes forms a Tetrimino (shape). Boxes are arranged on the Tetris board from the bottom upward.

Board Specifications
  • The Tetris board has a size of 11 columns (x-axis) by 21 rows (y-axis).
  • Tetriminos are arranged on the board such that if an entire row is filled with boxes, the player earns points.
Box Representation
  • Each box is defined by 2D (x, y) coordinates, which determine where it is drawn.
  • To represent boxes and Tetriminos (shapes), the game uses three structure variables:
    • Point2D
    • Tetriminos
    • TetrisBox


//Structure definition of x,y coordinate
struct Point2D {
    int x;
    int y;
};

//Structure definition to define each game board boxes
struct Tetriminos {
    struct Point2D body[4];
};

//Structure definition of individual Tetris Box
//Added on the Tetris board.
struct TetrisBox {
    struct Point2D box;
    int flag_T;
};

//Store four corner of the Tetris board
struct Point2D window[4];
//Store 7 shapes (Tetrimino)
struct Tetriminos tetrimino[7];

//Current Tetris shapes
struct Tetriminos current_T;

//Next Tetris shapes
struct Tetriminos next_T;

//Declare all box 11 * 21 = 231 within Tetris board
//double array matrix is created to represent board vertical boxes
//and horizontal boxes. The flag is to identify occupied box.
struct TetrisBox tetrisBoard[board_index_i_y][board_index_j_x];
The Point2D has two integer variables x, and y to represent x, and y coordinates. Tetriminos structure has only one body array of size 4 Struct Point2D variable to represent Tetrimino (Shapes). 
The structure definition TetrisBox represent only one box added on the board. The struct Point2D box variable store the coordinates and int flag_T variable represent it is filled by Tetrimino. The flag_T = 0 means box is not filled, flag_T = 1 means box is filled by Tetrimion. If any Terimino is added on the board then it will fill the box. So, after collision we will compare the coordinates of Tetrimino and boxes of the board, if both equal then we will set flag_T to 1. This technique is also used to check collision with boxes.

There are other variables such as struct Point2D currTranslateVec to represent translate vector, struct Point2D unitVec[4] to represent 4 units vectors toward positive and negative x and y axis, and struct Point2D currRotationVec[2] represent rotation vector clockwise and anticlockwise.

//Current Translate vector
struct Point2D currTranslateVec = {0,11};

//Unit vector toward  x-axis and y-axis both positive and negative
//0= + y-axis, 1 = - y-axis, 2 = + x-axis, and 3 = - x-axis
struct Point2D unitVec[4] = {{0,1},{0,-1},{1,0},{-1,0}};

//Clockwise rotation vector, 0 = clockwise, 1 = anti-clock wise
struct Point2D currRotationVec[2] = {{1,-1},{-1,1}};

//Index to indicate direction of unit vector
int unitVecDir = 1;

//Variable to calculate score
int score=0;

Collision detection

I have implemented collision detection based on following rules.
  • Tetrimino reach bottom of the board -> Add it in Tetris board.
  • Tetrimino collided with box while moving toward negative y-axis (downward) -> Add it in Tetris board.
  • Tetrimino collided with box while moving toward negative or positive x-axis -> Do not add it in board but stop moving further toward x-axis.
  • Tetrimino moving outside the board (out of window) -> Stop moving further toward x-axis.
  • Tetrimino collided with box but one or all boxes are outside of the window (positive y-axis) -> Game over

Scoring Techniques

Player will score if player able to arrange boxes in a row completely. We will scan the value of flag_T of the boxes along row to check scoring. We have defined Tetris board by two-dimension array struct TetrisBox tetrisBoard[board_index_i_y][board_index_j_x].  First index is number of rows toward y-axis and second index is number of columns.  So, for each row we will multiply the value of flag_T, if value equal to 1 then it means that row is filled by boxes and player will win 10 points. As you know, if box is not filled the value of flag_T is 0. Any of the box in a row is empty then total product of flag_T will be 0. 

When player win the points after filing all boxes in a row, we have to delete that row. To achieve this, I have implemented following logic.
  1. Add boxes from higher index i.e bottom of the board which is represented by board_index_i_y variable. Its value is up to 20 to represent all 21 rows of the board. The value 0 represents top row and 20 represent bottom row.
  2. Check the product of the value of flag_T from bottom row. If value is 1 increase the score and unset the value of flag_T to 0. Shift the value of flag_T from top rows to one step down starting from that index. Again, start checking product from same index, and repeat this step until you reach top row.
This is the end of the article. I hope you understood the coordinate system, data structure, collision detection techniques and scoring techniques used in this game. Please don't forget to download source code from the link provided in main page of this project, also do not forget to watch video. In video I have explain the source code in detail.


No comments:

Post a Comment