Open In App

2048 Game in C

Last Updated : 02 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

2048 is a popular single-player puzzle game that gained widespread popularity after its release in 2014. It was created by the Italian developer Gabriele Cirulli. The game’s objective is to slide numbered tiles on a grid to combine them, with the ultimate goal of creating a tile with the number 2048. The game continues beyond this point, allowing players to achieve higher scores by merging larger numbers.

2048 game in c

 

In this article, we will create a simple console-based C application for the 2048 game.

Rules of 2048 Game in C

The game contains certain elements and rules as mentioned below:

1. Grid Layout

  • The game is played on a 4×4 grid.
  • Numbered tiles appear on the grid, initially with only two tiles valued at 2 or 4.

2. Tile Movement

  • Players can move tiles in four directions: up, down, left, and right.
  • When a move is made, all tiles on the grid slide in the chosen direction, and a new tile appears.

3. Tile Combining

  • Tiles with the same number combine when they collide.
  • For example, if two tiles with the number 2 collide, they merge to form a tile with the number 4.

4. Scoring

  • Players earn points each time tiles combine.
  • The score is the sum of all tile values on the grid.

6. Winning and Continuing

  • The game is won when a tile with the number 2048 is created.
  • However, players can continue playing to achieve higher scores even after winning.

7. Game Over

  • The game ends when there are no more valid moves, i.e., the grid is filled, and no tiles can be merged or moved.

2048 Game in C

Below program illustrate the implementation of 2048 game in C.

C




// C program to implement 2048 game
  
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
  
#define MAXRANDOMVALUE 3
#define MAXPREV 500
int arr[4][4] = { 0 }, c[4], temp = 0, len = 0, score = 0,
    highscore = 0, count = 0,
    ch = 0; // COUNT WILL COUNT THE NO OF STEPS
  
int findlen(int n);
  
// Function to print the game board
void print()
{
    int i, j, k, len1;
  
    printf(
        "\n\t\t\t\t\t===============2048==============\n");
    printf("\t\t\t\t\tYOUR SCORE=%d\n\t\t\t\t\t", score);
    if (score < highscore) {
        printf("HIGH SCORE=%d\t\t\t\t\t\n", highscore);
    }
    else {
        highscore = score;
        printf("HIGH SCORE=%d\t\t\t\t\t\n", highscore);
    }
    printf("\t\t\t\t\t---------------------------------\n");
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            if (j == 0) {
                printf("\t\t\t\t\t|");
            }
            if (arr[i][j] != 0) {
                len1 = findlen(arr[i][j]);
                // printf("%d:",len);
  
                for (k = 0; k < 4 - len; k++) {
                    printf(" ");
                }
                printf("%d", arr[i][j]);
  
                for (k = 0; k < 4 - len; k++) {
                    printf(" ");
                }
                for (k = 0; k < len - 1; k++) {
                    printf(" ");
                }
                printf("|");
            }
            else {
                for (k = 0; k < 8 - 2 * len - 1; k++) {
                    printf(" ");
                }
                printf("|");
            }
            len = 0;
        }
        if (i != 3) {
            printf("\n");
            printf("\t\t\t\t\t-----------------------------"
                   "----\n");
        }
    }
    printf(
        "\n\t\t\t\t\t---------------------------------\n");
    printf("\t\t\t\t\tPREV-> P\t\t\t\t\t\n");
    printf("\t\t\t\t\tRESTART-> R\t\t\t\t\t\n");
    printf("\t\t\t\t\tEXIT-> U\t\t\t\t\t\n");
    printf("\t\t\t\t\tENTER YOUR CHOISE -> "
           "W,S,A,D\n\t\t\t\t\t");
}
  
// Function to move values in the array
void movevalue(int k)
{
    int i;
    if (k == 3) {
        return;
    }
    for (i = k; i < 4; i++) {
        if (c[i] != 0) {
            movevalue(i + 1);
            for (; i < 4; i++) {
                if (c[i + 1] != 0) {
                    break;
                }
                c[i + 1] = c[i];
                c[i] = 0;
            }
        }
    }
}
  
// Function to find the length of a number (count of digits)
int findlen(int n)
{
  
    if (n == 0) {
  
        return len;
    }
    else {
        len++;
        findlen(n / 10);
    }
}
  
// Function to add a random number to the game board
void addrandomno()
{
    int no;
    srand(time(NULL));
    int i, j; // RANDOM INDEX
    do {
        i = (rand()) % (MAXRANDOMVALUE + 1);
        j = (rand()) % (MAXRANDOMVALUE + 1);
    } while (arr[i][j] != 0);
    // printf("%d %d",i,j);
    no = 2 * ((rand() % 10) + 1);
    if (no == 3 || no == 2) {
        arr[i][j] = 4;
    }
    else {
        arr[i][j] = 2;
    }
}
  
// Function to update the array after moving values
void rupdate()
{
    int i, j;
    for (i = 3; i > 0; i--) {
        if (c[i] == c[i - 1]) {
            c[i] += c[i - 1];
            score = score + c[i];
            if (score > highscore) {
            }
            temp = 1;
            c[i - 1] = 0;
        }
        else if (c[i - 1] == 0 && c[i] != 0) {
            c[i - 1] = c[i];
            c[i] = 0;
            temp = 1;
        }
        else if (c[i] == 0) {
            temp = 1;
        }
    }
    movevalue(0);
}
  
// Function to create a previous state in the history
void createprev(int*** p)
{
    int i, j, k;
    FILE* ptr;
    ptr = fopen("hstr.txt", "a");
    fprintf(ptr, "%d ", score);
    fclose(ptr);
  
    if (count == MAXPREV + 1) {
        for (i = MAXPREV; i > 0; i--) {
            for (j = 0; j < 4; j++) {
                for (k = 0; k < 4; k++) {
                    p[i][j][k] = p[i - 1][j][k];
                }
            }
        }
        count = MAXPREV;
    }
  
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            p[MAXPREV - count][i][j] = arr[i][j];
        }
    }
}
  
// Function to update the array to a previous state
void updatearrtoprev(int*** p)
{
    int data, i, j;
    if (count == 0) {
        printf("\n******FURTHER MORE PREV NOT "
               "POSSIBLE********");
        return;
    }
    FILE* ptr = fopen("hstr.txt", "r+");
    for (i = 0; i < count; i++) {
        fscanf(ptr, "%d ", &data);
    }
    score = data;
  
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            arr[i][j] = p[MAXPREV - count][i][j];
        }
    }
    count--;
}
  
// Function to reset the game
void resetgame()
{
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            arr[i][j] = 0;
        }
    }
    system("clear || cls");
    score = 0;
    addrandomno();
}
int main()
{
    int i, j, k, m, n, same = 0;
    char choise, s = -33, reschk;
    printf("===============2048==============\n");
    printf("WELCOME TO PUZZLE 2048\n");
    printf("> CONTROLS\n");
    printf("  FOR MOVES:- 'W','S','A','D'\n");
    printf("  GO BACKWARD:- 'P'\n");
    printf("  RESTAT THE GAME:- 'R'\n");
    printf("  EXIT:-'U'\n");
  
    printf("\nPRESS ANY KEY TO START THE GAME....");
  
    getchar();
    system("clear || cls");
    printf("\n===============2048==============\n");
    printf("\nLOADING...\n");
    for (int i = 0, j; i < 35; i++) {
        printf("%c", s);
        j = i;
        if (i % 2 != 0 && i < 20) {
            usleep(1000);
        }
    }
    usleep(1000);
    system("clear || cls");
    int*** p;
    p = (int***)malloc(sizeof(int*) * (MAXPREV + 1));
    for (int i = 0; i < MAXPREV + 1; i++) {
        *(p + i) = (int**)malloc(sizeof(int*) * 4);
    }
    for (int i = 0; i < MAXPREV + 1; i++) {
        for (int j = 0; j < 4; j++) {
            p[i][j] = (int*)malloc(sizeof(int) * 4);
        }
    }
    createprev(p);
  
    FILE* ptr;
    ptr = fopen("highscore.txt", "r");
    fscanf(ptr, "%d", &highscore);
    fclose(ptr);
    ptr = fopen("hstr.txt", "w");
    fclose(ptr);
    addrandomno();
    print();
    while (1) {
        if (score > highscore) {
  
            ptr = fopen("highscore.txt", "w");
            fprintf(ptr, "%d", score);
            fclose(ptr);
        }
        choise = getchar();
        // Clear the input buffer
        while (getchar() != '\n')
            ;
        if (choise == 'D' || choise == 'd') {
            count++;
            ch++;
            createprev(p);
            for (i = 0; i < 4; i++) {
                for (j = 0; j < 4; j++) {
                    c[j] = arr[i][j];
                }
                rupdate();
                for (k = 0; k < 4; k++) {
                    arr[i][k] = c[k];
                }
            }
        }
        else if (choise == 'a' || choise == 'A') {
            count++;
            ch++;
            createprev(p);
            for (i = 0; i < 4; i++) {
                for (j = 3; j >= 0; j--) {
                    c[3 - j] = arr[i][j];
                }
                rupdate();
                for (k = 0; k < 4; k++) {
                    arr[i][3 - k] = c[k];
                }
            }
        }
        else if (choise == 's' || choise == 'S') {
            count++;
            ch++;
  
            createprev(p);
            for (i = 0; i < 4; i++) {
                for (j = 0; j < 4; j++) {
                    c[j] = arr[j][i];
                }
                rupdate();
                for (k = 0; k < 4; k++) {
                    arr[k][i] = c[k];
                }
            }
        }
        else if (choise == 'w' || choise == 'W') {
            count++;
            ch++;
  
            createprev(p);
            for (i = 0; i < 4; i++) {
                for (j = 3; j >= 0; j--) {
                    c[3 - j] = arr[j][i];
                }
                rupdate();
                for (k = 0; k < 4; k++) {
                    arr[3 - k][i] = c[k];
                }
            }
        }
        else if (choise == 'p' || choise == 'p') {
  
            updatearrtoprev(p);
  
            temp = 8;
        }
        else if (choise == 'R' || choise == 'r') {
            count = 0;
            resetgame();
            print();
            continue;
        }
        else if (choise == 'u' || choise == 'U') {
            exit(0);
        }
  
        if (temp == 1) {
            temp = 0;
            system("clear || cls");
            printf("\n%c\n", choise);
            addrandomno();
            print();
        }
        else if (temp == 8) {
            temp = 0;
            print();
        }
        else {
            for (m = 0; m < 4; m++) {
                for (n = 3; n > 0; n--) {
                    if (arr[m][n] == arr[m][n - 1]
                        || arr[m][n] == 0
                        || arr[m][n - 1] == 0) {
                        same = 1;
                        break;
                    }
                    if (arr[n][m] == arr[n - 1][m]
                        || arr[m][n] == 0
                        || arr[m][n - 1] == 0) {
                        same = 1;
                        break;
                    }
                }
                if (same == 1)
                    break;
            }
            if (same == 1) {
                printf("\n============INVALID "
                       "KEY==========\n");
                same = 0;
            }
            else {
                printf(
                    "\n=============GAME OVER============");
                printf("\nWANT TO PLAY MORE?? Y/N??\n");
                reschk = getchar();
                while (getchar() != '\n')
                    ; // Clear the input buffer
                switch (reschk) {
                case 'Y':
                case 'y':
                    resetgame();
                    print();
                    break;
                case 'n':
                case 'N':
                    exit(0);
                }
                continue;
            }
        }
    }
    return 0;
}


Output

2048GameinC

2048 Game in C

Explanation

Constants: These are preprocessor directives defining constants for the maximum random value and maximum previous game states.

#define MAXRANDOMVALUE 3
#define MAXPREV 500

Global Variables:

int arr[4][4] = {0}, c[4], temp = 0, len = 0, score = 0, highscore = 0, count = 0, ch = 0;
  • arr[4][4]: Represents the game grid.
  • c[4]: Temporary array used for moving values in a row or column.
  • temp: A flag used for checking if a move is valid.
  • len: Length variable used for formatting output.
  • score: Player’s current score.
  • highscore: Highest score achieved.
  • count: Number of steps taken in the game.
  • ch: A counter for the number of moves.

Functions

  • findlen(int n): Calculates the number of digits in an integer.
  • print(): Displays the current state of the game grid, score, and high score.
  • movevalue(int k): Moves non-zero values to the rightmost side in an array.
  • addrandomno(): Adds a random number (2 or 4) to a random empty cell in the grid.
  • rupdate(): Combines adjacent equal values in a row.
  • createprev(int ***p): Creates a record of the current game state to maintain a history of previous states.
  • updatearrtoprev(int ***p): Updates the game grid to a previous state.
  • resetgame(): Resets the game by clearing the grid, resetting the score, and adding a new random number.
  • main() Function: Initializes the game, handles user input, updates the game state based on the input, and checks for game over conditions. Additionally, file handling functions are used to read and write high scores and maintain a history of game states.

Conclusion

Developing a project like the 2048 game in C provides a hands-on and enjoyable way to enhance programming skills. The article has shown the usage of the fundamental components of the language for implementing the game, including its grid layout, tile movement, scoring, and game-ending conditions.
 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads