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