Open In App

2048 Game in C

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.

 

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

2. Tile Movement

3. Tile Combining

4. Scoring

6. Winning and Continuing

7. Game Over

2048 Game in C

Below program illustrate the implementation of 2048 game in 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

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;

Functions

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.
 


Article Tags :