2025年3月

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

#define SIZE 4

int board[SIZE][SIZE];

// 初始化棋盘
void initializeBoard() {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            board[i][j] = 0;
        }
    }
    // 在棋盘上随机生成两个数字2或4
    addRandomTile();
    addRandomTile();
}

// 在棋盘上随机生成一个数字2或4
void addRandomTile() {
    int value = (rand() % 2 + 1) * 2; // 生成2或4
    int x, y;
    do {
        x = rand() % SIZE;
        y = rand() % SIZE;
    } while (board[x][y] != 0); // 找到一个空的位置
    board[x][y] = value;
}

// 打印棋盘
void printBoard() {
    printf("-----------------------------\n");
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf("| %4d ", board[i][j]);
        }
        printf("|\n");
        printf("-----------------------------\n");
    }
}

// 判断棋盘是否已满
bool isBoardFull() {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == 0) {
                return false;
            }
        }
    }
    return true;
}

// 判断游戏是否结束
bool isGameOver() {
    if (!isBoardFull()) {
        return false;
    }
    // 检查是否有相邻的相同数字
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (i < SIZE - 1 && board[i][j] == board[i + 1][j]) {
                return false;
            }
            if (j < SIZE - 1 && board[i][j] == board[i][j + 1]) {
                return false;
            }
        }
    }
    return true;
}

// 向左移动
void moveLeft() {
    for (int i = 0; i < SIZE; i++) {
        int lastMerged = -1;
        for (int j = 1; j < SIZE; j++) {
            if (board[i][j] != 0) {
                int k = j;
                while (k > 0 && board[i][k - 1] == 0) {
                    board[i][k - 1] = board[i][k];
                    board[i][k] = 0;
                    k--;
                }
                if (k > 0 && board[i][k - 1] == board[i][k] && lastMerged != k - 1) {
                    board[i][k - 1] *= 2;
                    board[i][k] = 0;
                    lastMerged = k - 1;
                }
            }
        }
    }
}

// 向右移动
void moveRight() {
    for (int i = 0; i < SIZE; i++) {
        int lastMerged = SIZE;
        for (int j = SIZE - 2; j >= 0; j--) {
            if (board[i][j] != 0) {
                int k = j;
                while (k < SIZE - 1 && board[i][k + 1] == 0) {
                    board[i][k + 1] = board[i][k];
                    board[i][k] = 0;
                    k++;
                }
                if (k < SIZE - 1 && board[i][k + 1] == board[i][k] && lastMerged != k + 1) {
                    board[i][k + 1] *= 2;
                    board[i][k] = 0;
                    lastMerged = k + 1;
                }
            }
        }
    }
}

// 向上移动
void moveUp() {
    for (int j = 0; j < SIZE; j++) {
        int lastMerged = -1;
        for (int i = 1; i < SIZE; i++) {
            if (board[i][j] != 0) {
                int k = i;
                while (k > 0 && board[k - 1][j] == 0) {
                    board[k - 1][j] = board[k][j];
                    board[k][j] = 0;
                    k--;
                }
                if (k > 0 && board[k - 1][j] == board[k][j] && lastMerged != k - 1) {
                    board[k - 1][j] *= 2;
                    board[k][j] = 0;
                    lastMerged = k - 1;
                }
            }
        }
    }
}

// 向下移动
void moveDown() {
    for (int j = 0; j < SIZE; j++) {
        int lastMerged = SIZE;
        for (int i = SIZE - 2; i >= 0; i--) {
            if (board[i][j] != 0) {
                int k = i;
                while (k < SIZE - 1 && board[k + 1][j] == 0) {
                    board[k + 1][j] = board[k][j];
                    board[k][j] = 0;
                    k++;
                }
                if (k < SIZE - 1 && board[k + 1][j] == board[k][j] && lastMerged != k + 1) {
                    board[k + 1][j] *= 2;
                    board[k][j] = 0;
                    lastMerged = k + 1;
                }
            }
        }
    }
}

// 主函数
int main() {
    srand(time(NULL));
    initializeBoard();
    printBoard();

    char move;
    while (true) {
        printf("Enter move (w/a/s/d): ");
        scanf(" %c", &move);

        switch (move) {
            case 'a': // 向左移动
                moveLeft();
                break;
            case 'd': // 向右移动
                moveRight();
                break;
            case 'w': // 向上移动
                moveUp();
                break;
            case 's': // 向下移动
                moveDown();
                break;
            default:
                printf("Invalid move!\n");
                continue;
        }

        if (!isBoardFull()) {
            addRandomTile();
        }
        printBoard();

        if (isGameOver()) {
            printf("Game Over!\n");
            break;
        }
    }

    return 0;
}

通过库函数 printf 输出

  1. 勾选微库(MicroLIB)
  2. 添加fputc函数
/* 覆盖了内置的fputc函数,printf函数会调用fputc输出 */
int fputc(int ch, FILE* f) {
    while ((USART1->ISR & 0x40) == 0);
    USART1->TDR = (uint8_t) ch;

    return ch;
}

自定义 uart2_printf 函数输出

#include <stdarg.h>
#include <stdio.h>

uint8_t uart2_tx_buf[200];
void uart2_printf(const char *format, ...) {
    uint16_t len;
    va_list args;

    va_start(args, format);
    len = vsnprintf((char*)uart2_tx_buf, sizeof(uart2_tx_buf)+1, (char*)format, args); // 为什么要 +1 ?
    va_end(args);
    HAL_UART_Transmit(&huart2, UartTxBuf, len, HAL_MAX_DELAY);
}