C语言实战:2048数字合并游戏

发布于:2025-07-02 ⋅ 阅读:(24) ⋅ 点赞:(0)

游戏简介

这是一个经典的2048游戏,使用C语言编写,运行在命令行终端。玩家需要通过滑动数字方块(上、下、左、右),让相同数字的方块合并,最终尝试合成2048(或更高)的方块!

游戏特点

✅ 简洁的终端界面
✅ 实时计分系统
✅ 随机生成数字(2或4)
✅ 游戏结束判定
✅ 支持键盘控制(WASD或方向键)

如何运行?

  1. 复制代码到C编译器(如GCC、Clang)

  2. 编译运行(例如:gcc 2048.c -o 2048,然后 ./2048

  3. 开始挑战你的数字合并技巧!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h> // For getch() on Windows
#include <stdbool.h>

#define SIZE 4

int board[SIZE][SIZE] = {0};
int score = 0;

// Function prototypes
void initBoard();
void printBoard();
void addRandomTile();
bool moveTiles(int direction);
bool isGameOver();
void rotateBoard();
bool mergeTiles();
void clearScreen();

int main() {
    srand(time(0)); // Seed the random number generator
    
    initBoard();
    addRandomTile();
    addRandomTile();
    
    while (true) {
        clearScreen();
        printf("2048 Game - Score: %d\n\n", score);
        printBoard();
        
        if (isGameOver()) {
            printf("\nGame Over! Final Score: %d\n", score);
            break;
        }
        
        printf("\nUse arrow keys to move (w=up, s=down, a=left, d=right, q=quit): ");
        
        char input = getch();
        int direction = -1;
        
        switch (input) {
            case 'w': direction = 0; break; // Up
            case 's': direction = 1; break; // Down
            case 'a': direction = 2; break; // Left
            case 'd': direction = 3; break; // Right
            case 'q': 
                printf("\nQuitting game...\n");
                return 0;
            default: continue;
        }
        
        if (moveTiles(direction)) {
            addRandomTile();
        }
    }
    
    return 0;
}

void initBoard() {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            board[i][j] = 0;
        }
    }
    score = 0;
}

void printBoard() {
    for (int i = 0; i < SIZE; i++) {
        printf("+------+------+------+------+\n");
        for (int j = 0; j < SIZE; j++) {
            printf("|");
            if (board[i][j] != 0) {
                printf("%5d ", board[i][j]);
            } else {
                printf("      ");
            }
        }
        printf("|\n");
    }
    printf("+------+------+------+------+\n");
}

void addRandomTile() {
    int emptyCells[SIZE * SIZE][2];
    int count = 0;
    
    // Find all empty cells
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == 0) {
                emptyCells[count][0] = i;
                emptyCells[count][1] = j;
                count++;
            }
        }
    }
    
    if (count > 0) {
        // Choose a random empty cell
        int index = rand() % count;
        int x = emptyCells[index][0];
        int y = emptyCells[index][1];
        
        // 90% chance for 2, 10% chance for 4
        board[x][y] = (rand() % 10 == 0) ? 4 : 2;
    }
}

bool moveTiles(int direction) {
    bool moved = false;
    
    // Rotate board to simplify movement logic
    for (int i = 0; i < direction; i++) {
        rotateBoard();
    }
    
    // Move and merge tiles
    moved = mergeTiles();
    
    // Rotate back
    for (int i = 0; i < (4 - direction) % 4; i++) {
        rotateBoard();
    }
    
    return moved;
}

void rotateBoard() {
    int temp[SIZE][SIZE];
    
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            temp[i][j] = board[SIZE - j - 1][i];
        }
    }
    
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            board[i][j] = temp[i][j];
        }
    }
}

bool mergeTiles() {
    bool moved = false;
    
    for (int i = 0; i < SIZE; i++) {
        // First, move all tiles to the left (after rotation)
        int pos = 0;
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] != 0) {
                if (j != pos) {
                    board[i][pos] = board[i][j];
                    board[i][j] = 0;
                    moved = true;
                }
                pos++;
            }
        }
        
        // Then merge adjacent tiles with the same value
        for (int j = 0; j < SIZE - 1; j++) {
            if (board[i][j] != 0 && board[i][j] == board[i][j + 1]) {
                board[i][j] *= 2;
                score += board[i][j];
                board[i][j + 1] = 0;
                moved = true;
                
                // Shift remaining tiles
                for (int k = j + 1; k < SIZE - 1; k++) {
                    board[i][k] = board[i][k + 1];
                }
                board[i][SIZE - 1] = 0;
            }
        }
    }
    
    return moved;
}

bool isGameOver() {
    // Check for empty cells
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == 0) {
                return false;
            }
        }
    }
    
    // Check for possible merges
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE - 1; j++) {
            if (board[i][j] == board[i][j + 1]) {
                return false;
            }
        }
    }
    
    for (int j = 0; j < SIZE; j++) {
        for (int i = 0; i < SIZE - 1; i++) {
            if (board[i][j] == board[i + 1][j]) {
                return false;
            }
        }
    }
    
    return true;
}

void clearScreen() {
    #ifdef _WIN32
        system("cls");
    #else
        system("clear");
    #endif
}


网站公告

今日签到

点亮在社区的每一天
去签到