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占用低。

相关推荐
胡少侠71 小时前
RAG 向量持久化:用 ChromaDB 替换内存存储,支持 Metadata 溯源
ai·agent·rag·chromadb
大数据AI人工智能培训专家培训讲师叶梓1 小时前
120B 数学语料 + GRPO 算法,DeepSeekMath 刷新开源大模型推理天花板
人工智能·算法·大模型·推理·deepseek·openclaw·openclaw 讲师
智算菩萨1 小时前
多目标超启发式算法系统文献综述:人机协同大语言模型方法论深度精读
论文阅读·人工智能·深度学习·ai·多目标·综述
多加点辣也没关系1 小时前
Claude Code 安装与配置(详细教程)
ide·ai
码码哈哈0.01 小时前
开源项目Heygem本地运行 AI 数字人模型
人工智能·ai
JuckenBoy2 小时前
Linux环境安装SGLang框架运行自选大模型(以Rocky9.7为例)
linux·运维·大模型·qwen·rocky·deepseek·sglang
智算菩萨2 小时前
【How Far Are We From AGI】5 AGI的“道德罗盘“——价值对齐的技术路径与伦理边界
论文阅读·人工智能·深度学习·ai·接口·agi·对齐技术
柯儿的天空2 小时前
【OpenClaw 全面解析:从零到精通】第 006 篇:OpenClaw 在 Windows/WSL2 上的安装与部署实战
人工智能·windows·语言模型·chatgpt·ai作画
拙野2 小时前
OpenClaw 安装使用指南 (Windows)-对接钉钉、飞书、QQ
ai·钉钉·飞书·openclaw