Gemini初体验

Gemini的学生优惠实在是太诱人了,我在这个过程中遇到两个问题,第一个就是学生认证,第二个就是美国邮编的卡号。国内的大学通过不了认证。后来研究了几个小时,通过了。登上了之后,我第一个弄得就是圆球手势跟随,随着手掌的握紧和张开,圆球会慢慢缩聚和释放。

使用之后感觉在代码上Gemini比chatgpt优秀很多,整体很流畅,几乎无Debug。复制粘贴到VScode里面也是直接就可以使用,把prompt提示词再学习一下,可以把编程性能拉满。

然后就是对比一下主流AI工具,deepseek,chatgpt,gemini,grok,目前前端代码写的最好就是gemini,然后chatgpt论文以及语言词藻更加优秀,deepseek的深度思考过程(小字部分)对于我们分析问题的角度有启发作用,grok会追踪X上的热门话题,探索非正式的或创造性的视角。

下面是我自己的一些看法,我是从八字角度 来看的,首先我提供了一个男人的四柱八字,这个男人的八字的日主是乙木,坐丑土,日柱是乙丑。然后年月时天干丙火透干,地支坐燥土,天干癸水(用神)透出,但又坐火地,致使癸水烤干,对于乙木润局的效果大打折扣。典型的火炎土燥,身弱不胜财官,伤官配印(破格)的格局。这个是我提问的基础。我提出的问题是大运对于这个乙木日主的影响。问了chatgpt deepseek gemini,这三个AI工具。

我主要问他们,大运对于这个男生的影响。这个男人接下来的大运是丙申大运,三个AI给的解释各有千秋。

chatgpt :丙申大运,与乙木日主原局结合,三丙火,外在躁动,不稳,压力大,急火攻身,口直嘴快,易得罪人。申金为长生之地,暗藏壬水,能滋润乙木,为乙木生根。只看格局和大运,不看家庭背景,这个乙木日主会很累,事业和财富来之不易,事业不会太顶尖,更有可能成为普通工薪人员。

gemini :原局已有两丙,大运再来一个丙。三丙透干,火势滔天。乙木被泄气泄到了极致。这代表他这十年心气极高,欲望极大,极其焦虑,想法一天三变,根本静不下来。申金是正官。表面看是官星,但地支里有个大雷:巳申刑合。月令巳火(伤官)与大运申金(正官)打架。这就是经典的"伤官见官,为祸百端"。这个八字大运走返了,20-50走金火运,50岁之后才走水运。药来的太迟了。

deepseek :丙申大运,熔炉铸型期,巳(月柱地支)申合,从传统来看,伤官见官,祸事百端。格局看:"技术合规化"------将天马行空的创意(巳火伤官)纳入行业标准与专利体系(申金正官)。此运必有因原创成果引发的法律纠纷(如专利官司),但结果是确立技术所有权。如果大运直接来水运,在火炎土燥,火土成势的原局情况下,水运里的水并不能直接滋润乙木的根部,只能在表面覆盖一层水,再与原局激烈的火,水火交战,反倒激起更加猛烈的火。

综上来看,chatgpt和gemini是从传统五行来看的八字,deepseek是从格局论和盲派角度来看的。deepseek更乐观一些,也有怕用户情绪太过激动的情况。相比来说,chatgpt和gemini在论述的时候一直在强调保持理性和客观。这几个AI的分析方式,deepseek更偏向于感性,chatgpt和gemini更偏向于理性。

接下来,开始分析代码能力。我要求他们用C语言制作俄罗斯方块小程序。

deepseek:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>

// 游戏区域大小
#define WIDTH 10
#define HEIGHT 20

// 方块形状定义
int shapes[7][4][4][4] = {
    // I型方块
    {
        {{0,0,0,0}, {1,1,1,1}, {0,0,0,0}, {0,0,0,0}},
        {{0,0,1,0}, {0,0,1,0}, {0,0,1,0}, {0,0,1,0}},
        {{0,0,0,0}, {1,1,1,1}, {0,0,0,0}, {0,0,0,0}},
        {{0,0,1,0}, {0,0,1,0}, {0,0,1,0}, {0,0,1,0}}
    },
    // J型方块
    {
        {{0,0,0,0}, {1,1,1,0}, {0,0,1,0}, {0,0,0,0}},
        {{0,1,0,0}, {0,1,0,0}, {1,1,0,0}, {0,0,0,0}},
        {{1,0,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}},
        {{0,1,1,0}, {0,1,0,0}, {0,1,0,0}, {0,0,0,0}}
    },
    // L型方块
    {
        {{0,0,0,0}, {1,1,1,0}, {1,0,0,0}, {0,0,0,0}},
        {{1,1,0,0}, {0,1,0,0}, {0,1,0,0}, {0,0,0,0}},
        {{0,0,1,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}},
        {{0,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,0,0}}
    },
    // O型方块
    {
        {{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}},
        {{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}},
        {{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}},
        {{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}}
    },
    // S型方块
    {
        {{0,0,0,0}, {0,1,1,0}, {1,1,0,0}, {0,0,0,0}},
        {{1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0}},
        {{0,0,0,0}, {0,1,1,0}, {1,1,0,0}, {0,0,0,0}},
        {{1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0}}
    },
    // T型方块
    {
        {{0,0,0,0}, {1,1,1,0}, {0,1,0,0}, {0,0,0,0}},
        {{0,1,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0}},
        {{0,1,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}},
        {{0,1,0,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0}}
    },
    // Z型方块
    {
        {{0,0,0,0}, {1,1,0,0}, {0,1,1,0}, {0,0,0,0}},
        {{0,0,1,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0}},
        {{0,0,0,0}, {1,1,0,0}, {0,1,1,0}, {0,0,0,0}},
        {{0,0,1,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0}}
    }
};

// 方块颜色
int colors[7] = {14, 9, 12, 10, 2, 13, 6}; // 亮黄、蓝、红、绿、绿、紫、黄

// 游戏区域
int board[HEIGHT][WIDTH] = {0};
int currentX, currentY; // 当前方块位置
int currentShape;       // 当前方块类型
int currentRotation;    // 当前方块旋转状态
int score = 0;          // 分数
int level = 1;          // 等级
int linesCleared = 0;   // 消除的行数
int gameOver = 0;       // 游戏结束标志

// 函数声明
void initGame();
void drawGame();
void generateNewBlock();
int checkCollision(int x, int y, int shape, int rotation);
void mergeBlock();
void clearLines();
void rotateBlock();
void moveBlock(int dx, int dy);
void dropBlock();
void setColor(int color);
void gotoxy(int x, int y);
void drawBlock(int x, int y, int shape, int rotation, int show);
void updateScore(int lines);

int main() {
    initGame();
    generateNewBlock();
    
    // 游戏主循环
    while (!gameOver) {
        drawGame();
        
        // 控制下落速度
        int speed = 500 - (level - 1) * 50;
        if (speed < 100) speed = 100;
        
        // 等待用户输入或时间到
        clock_t start = clock();
        while ((clock() - start) * 1000 / CLOCKS_PER_SEC < speed) {
            if (_kbhit()) {
                char key = _getch();
                
                // 处理按键
                switch (key) {
                    case 'a':
                    case 'A':
                    case 75: // 左箭头
                        moveBlock(-1, 0);
                        break;
                    case 'd':
                    case 'D':
                    case 77: // 右箭头
                        moveBlock(1, 0);
                        break;
                    case 's':
                    case 'S':
                    case 80: // 下箭头
                        moveBlock(0, 1);
                        break;
                    case 'w':
                    case 'W':
                    case 72: // 上箭头
                        rotateBlock();
                        break;
                    case ' ': // 空格键
                        dropBlock();
                        break;
                    case 'q':
                    case 'Q':
                        gameOver = 1;
                        break;
                    case 'r':
                    case 'R':
                        initGame();
                        generateNewBlock();
                        break;
                }
                
                drawGame();
            }
        }
        
        // 方块下落
        moveBlock(0, 1);
    }
    
    // 游戏结束
    system("cls");
    printf("\n\n\n");
    printf("   游戏结束!\n");
    printf("   最终得分: %d\n", score);
    printf("   消除行数: %d\n", linesCleared);
    printf("   等级: %d\n", level);
    printf("\n   按任意键退出...\n");
    _getch();
    
    return 0;
}

// 初始化游戏
void initGame() {
    // 清空游戏区域
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            board[y][x] = 0;
        }
    }
    
    score = 0;
    level = 1;
    linesCleared = 0;
    gameOver = 0;
    
    // 设置随机种子
    srand(time(NULL));
}

// 绘制游戏界面
void drawGame() {
    system("cls");
    
    // 绘制游戏边框和标题
    printf("俄罗斯方块\n");
    printf("得分: %d   等级: %d   行数: %d\n\n", score, level, linesCleared);
    
    // 绘制游戏区域
    for (int y = 0; y < HEIGHT; y++) {
        printf("|");
        for (int x = 0; x < WIDTH; x++) {
            if (board[y][x]) {
                setColor(board[y][x]);
                printf("■");
                setColor(7); // 恢复白色
            } else {
                printf("  ");
            }
        }
        printf("|\n");
    }
    
    // 绘制底部边框
    printf("+");
    for (int x = 0; x < WIDTH; x++) {
        printf("--");
    }
    printf("+\n");
    
    // 绘制下一个方块预览
    printf("\n下一个方块:\n");
    for (int y = 0; y < 4; y++) {
        printf("  ");
        for (int x = 0; x < 4; x++) {
            if (shapes[(currentShape + 1) % 7][0][y][x]) {
                setColor(colors[(currentShape + 1) % 7]);
                printf("■");
                setColor(7);
            } else {
                printf("  ");
            }
        }
        printf("\n");
    }
    
    // 绘制控制说明
    printf("\n控制:\n");
    printf("  ↑/W: 旋转方块\n");
    printf("  ←/A: 左移\n");
    printf("  →/D: 右移\n");
    printf("  ↓/S: 加速下落\n");
    printf("  空格: 直接落下\n");
    printf("  R: 重新开始\n");
    printf("  Q: 退出游戏\n");
    
    // 绘制当前方块
    drawBlock(currentX, currentY, currentShape, currentRotation, 1);
}

// 生成新的方块
void generateNewBlock() {
    currentShape = rand() % 7;
    currentRotation = 0;
    currentX = WIDTH / 2 - 2;
    currentY = 0;
    
    // 检查游戏是否结束
    if (checkCollision(currentX, currentY, currentShape, currentRotation)) {
        gameOver = 1;
    }
}

// 检查碰撞
int checkCollision(int x, int y, int shape, int rotation) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (shapes[shape][rotation][i][j]) {
                int boardX = x + j;
                int boardY = y + i;
                
                // 检查边界
                if (boardX < 0 || boardX >= WIDTH || boardY >= HEIGHT) {
                    return 1;
                }
                
                // 检查与已有方块的碰撞
                if (boardY >= 0 && board[boardY][boardX]) {
                    return 1;
                }
            }
        }
    }
    return 0;
}

// 合并方块到游戏区域
void mergeBlock() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (shapes[currentShape][currentRotation][i][j]) {
                int boardX = currentX + j;
                int boardY = currentY + i;
                
                if (boardY >= 0) {
                    board[boardY][boardX] = colors[currentShape];
                }
            }
        }
    }
    
    // 清除完整的行
    clearLines();
    
    // 生成新的方块
    generateNewBlock();
}

// 清除完整的行
void clearLines() {
    int linesToClear = 0;
    
    for (int y = HEIGHT - 1; y >= 0; y--) {
        int full = 1;
        for (int x = 0; x < WIDTH; x++) {
            if (!board[y][x]) {
                full = 0;
                break;
            }
        }
        
        if (full) {
            linesToClear++;
            
            // 将上面的行下移
            for (int ny = y; ny > 0; ny--) {
                for (int x = 0; x < WIDTH; x++) {
                    board[ny][x] = board[ny - 1][x];
                }
            }
            
            // 清空顶部行
            for (int x = 0; x < WIDTH; x++) {
                board[0][x] = 0;
            }
            
            y++; // 重新检查当前行
        }
    }
    
    if (linesToClear > 0) {
        updateScore(linesToClear);
        linesCleared += linesToClear;
        level = linesCleared / 10 + 1;
    }
}

// 旋转方块
void rotateBlock() {
    int newRotation = (currentRotation + 1) % 4;
    
    if (!checkCollision(currentX, currentY, currentShape, newRotation)) {
        currentRotation = newRotation;
    } else {
        // 尝试墙踢:左右移动一格再旋转
        if (!checkCollision(currentX - 1, currentY, currentShape, newRotation)) {
            currentX--;
            currentRotation = newRotation;
        } else if (!checkCollision(currentX + 1, currentY, currentShape, newRotation)) {
            currentX++;
            currentRotation = newRotation;
        }
    }
}

// 移动方块
void moveBlock(int dx, int dy) {
    if (!checkCollision(currentX + dx, currentY + dy, currentShape, currentRotation)) {
        currentX += dx;
        currentY += dy;
    } else if (dy > 0) {
        // 无法向下移动,合并方块
        mergeBlock();
    }
}

// 方块直接落下
void dropBlock() {
    while (!checkCollision(currentX, currentY + 1, currentShape, currentRotation)) {
        currentY++;
    }
    mergeBlock();
}

// 更新分数
void updateScore(int lines) {
    switch (lines) {
        case 1:
            score += 100 * level;
            break;
        case 2:
            score += 300 * level;
            break;
        case 3:
            score += 500 * level;
            break;
        case 4:
            score += 800 * level;
            break;
    }
}

// 设置控制台颜色 (Windows)
void setColor(int color) {
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, color);
}

// 移动控制台光标
void gotoxy(int x, int y) {
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

// 绘制方块
void drawBlock(int x, int y, int shape, int rotation, int show) {
    setColor(colors[shape]);
    
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (shapes[shape][rotation][i][j]) {
                int screenX = x + j;
                int screenY = y + i;
                
                if (screenY >= 0 && screenY < HEIGHT && screenX >= 0 && screenX < WIDTH) {
                    gotoxy(screenX * 2 + 1, screenY + 3);
                    printf(show ? "■" : "  ");
                }
            }
        }
    }
    
    setColor(7);
}

chatgpt

cpp 复制代码
// tetris.c
// Simple terminal Tetris (cross-platform: Unix and Windows)
// Compile (Linux/macOS): gcc tetris.c -o tetris -std=c99
// Compile (Windows MinGW): gcc tetris.c -o tetris.exe -std=c99
// Controls:
//   a / left arrow  - move left
//   d / right arrow - move right
//   s / down arrow  - soft drop
//   w / up arrow    - rotate clockwise
//   space           - hard drop
//   p               - pause
//   q               - quit

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

#ifdef _WIN32
#include <conio.h>
#include <windows.h>
#else
#include <termios.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#endif

#define FIELD_W 10
#define FIELD_H 20
#define VISIBLE_H FIELD_H
#define HOLD_AREA_W 6

// Tetromino definitions (4x4 blocks for each rotation)
const char *tetromino[7] = {
    // I
    "...."
    "1111"
    "...."
    "....",

    // J
    "1.."
    "111"
    "..."
    ,

    // L
    "..1"
    "111"
    "..."
    ,

    // O
    "11"
    "11"
    ,

    // S
    ".11"
    "11."
    "..."
    ,

    // Z
    "11."
    ".11"
    "..."
    ,

    // T
    ".1."
    "111"
    "..."
};

// But above compact forms vary in width; to simplify rotation and indexing,
// we'll store tetrominoes as 4x4 strings ('.' and '1') - fill smaller ones into 4x4.
const char seeds[7][17] = {
    // I
    "...."
    "1111"
    "...."
    "....",

    // J
    "1..."
    "111."
    "...."
    "....",

    // L
    "...1"
    "111."
    "...."
    "....",

    // O
    "11.."
    "11.."
    "...."
    "....",

    // S
    ".11."
    "11.."
    "...."
    "....",

    // Z
    "11.."
    ".11."
    "...."
    "....",

    // T
    ".1.."
    "111."
    "...."
    "...."
};

int field[FIELD_H][FIELD_W]; // 0 empty, >0 filled
int score = 0;
int level = 1;
int lines_cleared = 0;

// Random generator
int rnd() {
    return rand();
}

#ifdef _WIN32
void sleep_ms(int ms) { Sleep(ms); }
#else
void sleep_ms(int ms) { usleep(ms * 1000); }
#endif

// Non-blocking keyboard input
#ifdef _WIN32
int kbhit_nonblock() {
    return _kbhit();
}
int getch_nonblock() {
    return _getch();
}
#else
static struct termios orig_termios;
void reset_terminal_mode() {
    tcsetattr(0, TCSANOW, &orig_termios);
}
void set_conio_terminal_mode() {
    struct termios new_termios;
    tcgetattr(0, &orig_termios);
    new_termios = orig_termios;
    // disable canonical mode, echo
    new_termios.c_lflag &= ~(ICANON | ECHO);
    // minimal input
    new_termios.c_cc[VMIN] = 0;
    new_termios.c_cc[VTIME] = 0;
    tcsetattr(0, TCSANOW, &new_termios);
    atexit(reset_terminal_mode);
}
int kbhit_nonblock() {
    struct timeval tv = {0L, 0L};
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(0, &fds);
    return select(1, &fds, NULL, NULL, &tv);
}
int getch_nonblock() {
    unsigned char c;
    if (read(0, &c, 1) < 1) return -1;
    return c;
}
#endif

// Clear screen
void clear_screen() {
#ifdef _WIN32
    system("cls");
#else
    // ANSI clear
    printf("\x1b[2J\x1b[H");
#endif
}

// Print field and status
void draw(int nextTet, int px, int py, int current, int rot, int ghostY) {
    clear_screen();
    printf("Score: %d   Level: %d   Lines: %d\n", score, level, lines_cleared);
    printf("+------------+   Next:\n"); // field width 10 -> 12 with borders
    for (int y = 0; y < FIELD_H; ++y) {
        printf("|");
        for (int x = 0; x < FIELD_W; ++x) {
            int v = field[y][x];
            char ch = v ? '#' : ' ';
            // If piece occupies this
            // (we'll not check collision here, simply overlay)
            putchar(ch);
        }
        printf("|");
        // draw next piece preview (4x4)
        int pyOff = y < 4 ? y : -1;
        if (pyOff >= 0) {
            printf("   ");
            const char *s = seeds[nextTet];
            for (int x = 0; x < 4; ++x) {
                char c = s[pyOff * 4 + x];
                if (c == '1') putchar('#'); else putchar(' ');
            }
        }
        printf("\n");
    }
    printf("+------------+\n");
    printf("Controls: a/d left-right   w rotate   s soft drop   space hard drop   p pause   q quit\n");
}

// access tetromino cell after rotation (0..3)
int tcell(int tet, int rot, int x, int y) {
    // rot: 0..3 clockwise rotations
    // seeds[tet] is 4x4 row-major
    // rotation formulas:
    // rot=0: (x,y) -> index = y*4 + x
    // rot=1: (x,y) -> index = (3-x)*4 + y
    // rot=2: (x,y) -> index = (3-y)*4 + (3-x)
    // rot=3: (x,y) -> index = x*4 + (3-y)
    const char *s = seeds[tet];
    int idx = 0;
    if (rot == 0) idx = y*4 + x;
    else if (rot == 1) idx = (3 - x)*4 + y;
    else if (rot == 2) idx = (3 - y)*4 + (3 - x);
    else idx = x*4 + (3 - y);
    return s[idx] == '1';
}

// collision check
int collides(int tet, int rot, int ox, int oy) {
    for (int y = 0; y < 4; ++y)
        for (int x = 0; x < 4; ++x) {
            if (tcell(tet, rot, x, y)) {
                int fx = ox + x;
                int fy = oy + y;
                if (fx < 0 || fx >= FIELD_W || fy >= FIELD_H) return 1;
                if (fy >= 0 && field[fy][fx]) return 1;
            }
        }
    return 0;
}

// place piece onto field
void place(int tet, int rot, int ox, int oy) {
    for (int y = 0; y < 4; ++y)
        for (int x = 0; x < 4; ++x)
            if (tcell(tet, rot, x, y)) {
                int fx = ox + x;
                int fy = oy + y;
                if (fy >= 0 && fx >= 0 && fx < FIELD_W && fy < FIELD_H)
                    field[fy][fx] = tet + 1; // non-zero
            }
}

// remove full lines, return number removed
int clear_lines() {
    int removed = 0;
    for (int y = FIELD_H - 1; y >= 0; --y) {
        int full = 1;
        for (int x = 0; x < FIELD_W; ++x) if (!field[y][x]) { full = 0; break; }
        if (full) {
            ++removed;
            // drop everything above
            for (int yy = y; yy > 0; --yy)
                for (int x = 0; x < FIELD_W; ++x)
                    field[yy][x] = field[yy-1][x];
            // clear top
            for (int x = 0; x < FIELD_W; ++x) field[0][x] = 0;
            ++y; // recheck same y
        }
    }
    return removed;
}

// draw field with current falling piece and ghost to console (simple)
void draw_with_piece(int nextTet, int px, int py, int current, int rot) {
    clear_screen();
    printf("Score: %d   Level: %d   Lines: %d\n", score, level, lines_cleared);
    printf("+------------+   Next:\n");
    // compute ghost Y (hard drop preview)
    int gy = py;
    while (!collides(current, rot, px, gy+1)) gy++;
    for (int y = 0; y < FIELD_H; ++y) {
        printf("|");
        for (int x = 0; x < FIELD_W; ++x) {
            int ch = ' ';
            if (field[y][x]) ch = '#';
            // overlay ghost
            int gx = x - px;
            int gyCell = y - gy;
            if (gyCell >= 0 && gyCell < 4 && gx >= 0 && gx < 4 && tcell(current, rot, gx, gyCell) && !field[y][x]) {
                // ghost dim (.)
                ch = '.';
            }
            // overlay current piece
            int cx = x - px;
            int cy = y - py;
            if (cy >= 0 && cy < 4 && cx >= 0 && cx < 4 && tcell(current, rot, cx, cy)) {
                ch = '#';
            }
            putchar(ch);
        }
        printf("|");
        // next box
        int pyOff = y < 4 ? y : -1;
        if (pyOff >= 0) {
            printf("   ");
            const char *s = seeds[nextTet];
            for (int x = 0; x < 4; ++x) {
                char c = s[pyOff*4 + x];
                if (c == '1') putchar('#'); else putchar(' ');
            }
        }
        printf("\n");
    }
    printf("+------------+\n");
    printf("Controls: a/d left-right   w rotate   s soft drop   space hard drop   p pause   q quit\n");
}

int main() {
    srand((unsigned int)time(NULL));
#ifndef _WIN32
    set_conio_terminal_mode();
#endif

    // init field
    memset(field, 0, sizeof(field));

    int current = rnd() % 7;
    int nextTet = rnd() % 7;
    int rot = 0;
    int px = FIELD_W/2 - 2;
    int py = -2; // start above visible
    int tick_time_ms = 700; // base drop interval
    int running = 1;

    int drop_counter = 0;
    int soft_drop = 0;
    int paused = 0;

    // game loop
    while (running) {
        // compute drop speed by level
        tick_time_ms = 700 - (level - 1) * 50;
        if (tick_time_ms < 100) tick_time_ms = 100;

        int elapsed = 0;
        int interval = 50; // check every 50ms for input
        while (elapsed < tick_time_ms) {
            // input
            if (kbhit_nonblock()) {
                int c = getch_nonblock();
                if (c == -1) { /* none */ }
                else {
                    // handle arrow sequences for some terminals: ESC [ A etc
                    if (c == 27) { // ESC
                        // try to read [ and code
                        int s1 = getch_nonblock();
                        if (s1 == '[') {
                            int s2 = getch_nonblock();
                            if (s2 == 'A') c = 'w'; // up
                            else if (s2 == 'B') c = 's'; // down
                            else if (s2 == 'C') c = 'd'; // right
                            else if (s2 == 'D') c = 'a'; // left
                        }
                    }
                    if (c == 'a' || c == 'A') {
                        if (!paused && !collides(current, rot, px-1, py)) px--;
                        draw_with_piece(nextTet, px, py, current, rot);
                    } else if (c == 'd' || c == 'D') {
                        if (!paused && !collides(current, rot, px+1, py)) px++;
                        draw_with_piece(nextTet, px, py, current, rot);
                    } else if (c == 's' || c == 'S') {
                        if (!paused) {
                            if (!collides(current, rot, px, py+1)) py++;
                            score += 1; // soft drop small score
                            draw_with_piece(nextTet, px, py, current, rot);
                        }
                    } else if (c == 'w' || c == 'W') {
                        if (!paused) {
                            int newrot = (rot + 1) & 3;
                            if (!collides(current, newrot, px, py)) rot = newrot;
                            else {
                                // simple wall kick attempts
                                if (!collides(current, newrot, px-1, py)) px--;
                                else if (!collides(current, newrot, px+1, py)) px++;
                            }
                            draw_with_piece(nextTet, px, py, current, rot);
                        }
                    } else if (c == ' ') { // hard drop
                        if (!paused) {
                            while (!collides(current, rot, px, py+1)) { py++; score += 2; }
                            // place immediately
                            place(current, rot, px, py);
                            int cleared = clear_lines();
                            if (cleared > 0) {
                                lines_cleared += cleared;
                                score += (cleared * cleared) * 100;
                                level = 1 + lines_cleared / 10;
                            }
                            // spawn next
                            current = nextTet;
                            nextTet = rnd() % 7;
                            rot = 0;
                            px = FIELD_W/2 - 2;
                            py = -2;
                            if (collides(current, rot, px, py)) {
                                // game over
                                clear_screen();
                                printf("GAME OVER\nScore: %d   Lines: %d\n", score, lines_cleared);
                                printf("Press r to restart or q to quit.\n");
                                int choice = 0;
                                while (!choice) {
                                    if (kbhit_nonblock()) {
                                        int ch = getch_nonblock();
                                        if (ch == 'q' || ch == 'Q') { running = 0; choice = 1; }
                                        else if (ch == 'r' || ch == 'R') {
                                            // reset
                                            memset(field, 0, sizeof(field));
                                            score = 0; level = 1; lines_cleared = 0;
                                            current = rnd() % 7;
                                            nextTet = rnd() % 7;
                                            rot = 0; px = FIELD_W/2 - 2; py = -2;
                                            choice = 1;
                                        }
                                    }
                                    sleep_ms(100);
                                }
                            }
                            draw_with_piece(nextTet, px, py, current, rot);
                        }
                    } else if (c == 'p' || c == 'P') {
                        paused = !paused;
                        if (paused) {
                            clear_screen();
                            printf("PAUSED. Press p to resume.\n");
                        } else draw_with_piece(nextTet, px, py, current, rot);
                    } else if (c == 'q' || c == 'Q') {
                        running = 0;
                    }
                }
            }
            if (!paused) elapsed += interval;
            sleep_ms(interval);
        }

        if (paused) continue;

        // automatic drop
        if (!collides(current, rot, px, py+1)) {
            py++;
        } else {
            // place piece
            place(current, rot, px, py);
            int cleared = clear_lines();
            if (cleared > 0) {
                lines_cleared += cleared;
                score += (cleared * cleared) * 100;
                level = 1 + lines_cleared / 10;
            }
            // spawn next
            current = nextTet;
            nextTet = rnd() % 7;
            rot = 0;
            px = FIELD_W/2 - 2;
            py = -2;
            if (collides(current, rot, px, py)) {
                // game over
                clear_screen();
                printf("GAME OVER\nScore: %d   Lines: %d\n", score, lines_cleared);
                printf("Press r to restart or q to quit.\n");
                int choice = 0;
                while (!choice) {
                    if (kbhit_nonblock()) {
                        int ch = getch_nonblock();
                        if (ch == 'q' || ch == 'Q') { running = 0; choice = 1; }
                        else if (ch == 'r' || ch == 'R') {
                            // reset
                            memset(field, 0, sizeof(field));
                            score = 0; level = 1; lines_cleared = 0;
                            current = rnd() % 7;
                            nextTet = rnd() % 7;
                            rot = 0; px = FIELD_W/2 - 2; py = -2;
                            choice = 1;
                        }
                    }
                    sleep_ms(100);
                }
            }
        }

        draw_with_piece(nextTet, px, py, current, rot);
    }

#ifndef _WIN32
    reset_terminal_mode();
#endif
    printf("Bye!\n");
    return 0;
}

gemini:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>

// --- 游戏配置 ---
#define WIDTH 12       // 游戏区域宽度 (包括墙壁)
#define HEIGHT 22      // 游戏区域高度 (包括地板)
#define SPEED_MS 300   // 下落速度 (毫秒)

// --- 全局变量 ---
int field[HEIGHT][WIDTH]; // 游戏地图: 0=空, 1=墙/地, 2=方块
int score = 0;
int gameOver = 0;

// 定义7种方块 (4x4 矩阵)
// 为了简化,这里直接硬编码方块的形状
int shapes[7][4][4] = {
    {{0,0,0,0}, {1,1,1,1}, {0,0,0,0}, {0,0,0,0}}, // I
    {{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}}, // O
    {{0,0,0,0}, {0,1,0,0}, {1,1,1,0}, {0,0,0,0}}, // T
    {{0,0,0,0}, {0,0,1,0}, {0,1,1,0}, {0,1,0,0}}, // S
    {{0,0,0,0}, {1,0,0,0}, {1,1,0,0}, {0,1,0,0}}, // Z
    {{0,0,0,0}, {1,0,0,0}, {1,1,1,0}, {0,0,0,0}}, // J
    {{0,0,0,0}, {0,0,1,0}, {1,1,1,0}, {0,0,0,0}}  // L
};

// 当前方块的属性
int currentPiece[4][4];
int tempPiece[4][4]; // 用于旋转测试
int px, py; // 方块的位置

// --- 辅助函数:隐藏光标 ---
void hideCursor() {
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO info;
    info.dwSize = 100;
    info.bVisible = FALSE;
    SetConsoleCursorInfo(consoleHandle, &info);
}

// --- 辅助函数:移动光标到 (0,0) ---
// 比 system("cls") 更好,不会闪烁
void resetCursor() {
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord;
    coord.X = 0;
    coord.Y = 0;
    SetConsoleCursorPosition(consoleHandle, coord);
}

// --- 初始化游戏地图 ---
void initField() {
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (j == 0 || j == WIDTH - 1 || i == HEIGHT - 1) {
                field[i][j] = 1; // 墙壁或地板
            } else {
                field[i][j] = 0; // 空地
            }
        }
    }
}

// --- 生成新方块 ---
void spawnPiece() {
    int id = rand() % 7;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            currentPiece[i][j] = shapes[id][i][j];
        }
    }
    px = WIDTH / 2 - 2;
    py = 0;

    // 检查生成时是否已经碰撞(游戏结束)
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (currentPiece[i][j] && field[py + i][px + j] != 0) {
                gameOver = 1;
            }
        }
    }
}

// --- 碰撞检测 ---
// 返回 1 表示发生碰撞,0 表示安全
int checkCollision(int p[4][4], int posX, int posY) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (p[i][j]) { // 如果方块这格有东西
                // 检查是否越界或撞墙/撞其他方块
                if (posX + j < 0 || posX + j >= WIDTH || posY + i >= HEIGHT || 
                    field[posY + i][posX + j] != 0) {
                    return 1;
                }
            }
        }
    }
    return 0;
}

// --- 旋转方块 ---
void rotatePiece() {
    // 顺时针旋转公式:temp[j][3-i] = current[i][j]
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            tempPiece[j][3 - i] = currentPiece[i][j];
        }
    }

    // 只有旋转后不碰撞才应用旋转
    if (!checkCollision(tempPiece, px, py)) {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                currentPiece[i][j] = tempPiece[i][j];
            }
        }
    }
}

// --- 锁定方块到地图 ---
void lockPiece() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (currentPiece[i][j]) {
                field[py + i][px + j] = 2;
            }
        }
    }
}

// --- 消除满行 ---
void checkLines() {
    for (int i = HEIGHT - 2; i > 0; i--) {
        int full = 1;
        for (int j = 1; j < WIDTH - 1; j++) {
            if (field[i][j] == 0) {
                full = 0;
                break;
            }
        }

        if (full) {
            score += 100;
            // 简单的下沉动画逻辑:把上面的行都挪下来
            for (int k = i; k > 0; k--) {
                for (int j = 1; j < WIDTH - 1; j++) {
                    field[k][j] = field[k - 1][j];
                }
            }
            i++; // 重新检查当前行(因为上面的行掉下来了)
        }
    }
}

// --- 绘制画面 ---
void draw() {
    resetCursor();
    // 创建一个显示缓冲区,避免逐字打印造成的闪烁
    // 注意:这里使用简单的直接打印,对于现代PC速度够快
    
    printf("=== TETRIS (C Language) ===\n");
    printf("Score: %d\n\n", score);

    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            int isActivePiece = 0;
            
            // 检查是否是正在下落的方块
            if (i >= py && i < py + 4 && j >= px && j < px + 4) {
                if (currentPiece[i - py][j - px]) {
                    printf("[]");
                    isActivePiece = 1;
                }
            }

            if (!isActivePiece) {
                if (field[i][j] == 1) printf("##");      // 墙壁
                else if (field[i][j] == 2) printf("[]"); // 已固定的方块
                else printf(" .");                       // 空地
            }
        }
        printf("\n");
    }
    printf("\nControls: W(Rotate) A(Left) S(Down) D(Right) Q(Quit)");
}

// --- 主程序 ---
int main() {
    srand((unsigned)time(NULL));
    initField();
    spawnPiece();
    hideCursor();

    clock_t lastTime = clock();

    while (!gameOver) {
        // 1. 处理输入
        if (_kbhit()) {
            char ch = _getch();
            if (ch == 'a' || ch == 'A') {
                if (!checkCollision(currentPiece, px - 1, py)) px--;
            }
            if (ch == 'd' || ch == 'D') {
                if (!checkCollision(currentPiece, px + 1, py)) px++;
            }
            if (ch == 's' || ch == 'S') {
                if (!checkCollision(currentPiece, px, py + 1)) py++;
            }
            if (ch == 'w' || ch == 'W') {
                rotatePiece();
            }
            if (ch == 'q' || ch == 'Q') {
                break;
            }
            draw(); // 响应按键后立即重绘,增加流畅感
        }

        // 2. 自动下落逻辑 (基于时间)
        if (clock() - lastTime > SPEED_MS) {
            if (!checkCollision(currentPiece, px, py + 1)) {
                py++;
            } else {
                // 到底了
                lockPiece();
                checkLines();
                spawnPiece();
            }
            lastTime = clock();
            draw();
        }
        
        // 简单的CPU休眠,防止占用过高
        Sleep(10);
    }

    printf("\n\nGAME OVER! Final Score: %d\n", score);
    system("pause");
    return 0;
}

整体上,gemini代码简洁,算法优化更强,deepseek所包含功能较为丰富,CPU占用较高,运行时间较长,chatgpt跨平台性、性能效率、代码架构均为最优、渲染无闪烁,CPU占用低。

相关推荐
阿杰学AI3 小时前
AI核心知识45——大语言模型之PPO(简洁且通俗易懂版)
人工智能·ai·语言模型·自然语言处理·aigc·ppo·近端策略优化
爱笑的眼睛114 小时前
神经网络的骨架:深入解析前向传播的数学本质与工程实现
java·人工智能·python·ai
大熊猫侯佩4 小时前
拯救发际线行动:用 Swift 和 Image Playground 驾驭 AI 绘图
人工智能·ai·文生图·swift·图生图·imageplayground·apple 智能
爱吃烤鸡翅的酸菜鱼4 小时前
AscendNPU IR 语法指南:核心概念速查
人工智能·ai·cann
shandianchengzi4 小时前
【记录】Github|Github账号意外被封以及不需要手机号解封的全过程(被封原因:一台设备上登录过多个账号)
github·gemini
忆~遂愿4 小时前
vLLM Ascend 项目架构解析与部署配置指南
人工智能·后端·python·ai
模型启动机4 小时前
GELab-Zero:阶跃开源的4B端侧多模态GUI Agent模型,助力本地可控的移动设备智能化
人工智能·ai·大模型·智能化
ONLYOFFICE5 小时前
如何在ONLYOFFICE协作空间中使用AI智能体?配置应用全攻略
人工智能·ai·编辑器·onlyoffice
quantanexus深算工场5 小时前
Quantanexus(QN)深算工场AI智能调度平台安装
人工智能·ai·gpu算力·深算工场·gpu管理软件·ai实训教学平台