MC.Steve 发表于 2026-2-10 14:30:48

贪吃蛇代码

本帖最后由 MC.Steve 于 2026-2-10 14:54 编辑

今天的主题是:贪吃蛇!(加强版明天发布)(不定期会出python的游戏)

贪吃蛇的程序语言:C语言、C++

保证鱼油能够在C语言、C++中玩到贪吃蛇

C语言:
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>

#define WIDTH 20
#define HEIGHT 15

int x, y, fruitX, fruitY, score;
int tailX, tailY;
int nTail;
enum eDirection { STOP, LEFT, RIGHT, UP, DOWN };
enum eDirection dir;

void Setup() {
    dir = STOP;
    x = WIDTH / 2;
    y = HEIGHT / 2;
    fruitX = rand() % WIDTH;
    fruitY = rand() % HEIGHT;
    score = 0;
    nTail = 0;
}

void Draw() {
    system("cls");
    for (int i = 0; i < WIDTH + 2; i++) printf("#");
    printf("\n");

    for (int i = 0; i < HEIGHT; i++) {
      for (int j = 0; j < WIDTH; j++) {
            if (j == 0) printf("#");
            if (i == y && j == x) printf("O");
            else if (i == fruitY && j == fruitX) printf("F");
            else {
                int print = 0;
                for (int k = 0; k < nTail; k++) {
                  if (tailX == j && tailY == i) {
                        printf("o");
                        print = 1;
                  }
                }
                if (!print) printf(" ");
            }
            if (j == WIDTH - 1) printf("#");
      }
      printf("\n");
    }

    for (int i = 0; i < WIDTH + 2; i++) printf("#");
    printf("\nScore:%d", score);
}

void Input() {
    if (_kbhit()) {
      switch (_getch()) {
            case 'a': dir = LEFT; break;
            case 'd': dir = RIGHT; break;
            case 'w': dir = UP; break;
            case 's': dir = DOWN; break;
            case 'x': dir = STOP; break;
      }
    }
}

void Logic() {
    int prevX = tailX;
    int prevY = tailY;
    int prev2X, prev2Y;
    tailX = x;
    tailY = y;

    for (int i = 1; i < nTail; i++) {
      prev2X = tailX;
      prev2Y = tailY;
      tailX = prevX;
      tailY = prevY;
      prevX = prev2X;
      prevY = prev2Y;
    }

    switch (dir) {
      case LEFT: x--; break;
      case RIGHT: x++; break;
      case UP: y--; break;
      case DOWN: y++; break;
    }

    if (x >= WIDTH) x = 0; else if (x < 0) x = WIDTH - 1;
    if (y >= HEIGHT) y = 0; else if (y < 0) y = HEIGHT - 1;

    for (int i = 0; i < nTail; i++)
      if (tailX == x && tailY == y)
            dir = STOP;

    if (x == fruitX && y == fruitY) {
      score += 10;
      nTail++;
      fruitX = rand() % WIDTH;
      fruitY = rand() % HEIGHT;
    }
}

int main() {
    Setup();
    while (dir != STOP) {
      Draw();
      Input();
      Logic();
      Sleep(100); // 控制速度
    }
    return 0;
}


C++:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <unistd.h> // for sleep

#ifdef _WIN32
#include <conio.h>
#else
#include <ncurses.h>
#endif

const int WIDTH = 20, HEIGHT = 15;

struct Point { int x, y; };

int main() {
    #ifndef _WIN32
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);
    nodelay(stdscr, TRUE);
    #endif

    srand(time(0));
    Point snake = {{WIDTH/2, HEIGHT/2}};
    int n = 1;
    Point fruit = {rand() % WIDTH, rand() % HEIGHT};
    int dx = 1, dy = 0; // 初始向右
    int score = 0;

    while (true) {
      // 绘制
      #ifndef _WIN32
      clear();
      #else
      system("cls");
      #endif

      for (int i = 0; i < WIDTH + 2; i++) std::cout << "#";
      std::cout << "\n";

      for (int y = 0; y < HEIGHT; y++) {
            std::cout << "#";
            for (int x = 0; x < WIDTH; x++) {
                bool isBody = false;
                for (int i = 1; i < n; i++)
                  if (snake.x == x && snake.y == y)
                        { std::cout << "o"; isBody = true; }
                if (!isBody) {
                  if (snake.x == x && snake.y == y) std::cout << "O";
                  else if (fruit.x == x && fruit.y == y) std::cout << "F";
                  else std::cout << " ";
                }
            }
            std::cout << "#\n";
      }

      for (int i = 0; i < WIDTH + 2; i++) std::cout << "#";
      std::cout << "\nScore: " << score;

      // 输入处理
      #ifdef _WIN32
      if (_kbhit()) {
            switch (_getch()) {
                case 'a': dx = -1; dy = 0; break;
                case 'd': dx = 1; dy = 0; break;
                case 'w': dx = 0; dy = -1; break;
                case 's': dx = 0; dy = 1; break;
            }
      }
      #else
      int ch = getch();
      switch (ch) {
            case KEY_LEFT: dx = -1; dy = 0; break;
            case KEY_RIGHT: dx = 1; dy = 0; break;
            case KEY_UP: dx = 0; dy = -1; break;
            case KEY_DOWN: dx = 0; dy = 1; break;
      }
      #endif

      // 逻辑更新
      for (int i = n - 1; i > 0; i--)
            snake = snake;
      
      snake.x = (snake.x + dx + WIDTH) % WIDTH;
      snake.y = (snake.y + dy + HEIGHT) % HEIGHT;

      // 检测碰撞
      for (int i = 1; i < n; i++)
            if (snake.x == snake.x && snake.y == snake.y)
                goto game_over;

      // 吃食物
      if (snake.x == fruit.x && snake.y == fruit.y) {
            n++;
            score += 10;
            fruit = {rand() % WIDTH, rand() % HEIGHT};
      }

      usleep(100000); // 100ms
    }

game_over:
    #ifndef _WIN32
    endwin();
    #endif
    std::cout << "\nGame Over! Final Score: " << score << std::endl;
    return 0;
}


接下来会有AI竞技、双人(可以@你的好基友来玩)
有想法可提出,将会有新版本

FishC 发表于 2026-2-10 14:32:59

以下为C语言和C++的贪吃蛇基础版代码,代码已修正蛇身存储问题,确保可以正确运行。两个版本都使用了简单的控制台图形,通过键盘WASD控制方向,X键退出游戏。

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>

#define WIDTH 20
#define HEIGHT 15

int x, y, fruitX, fruitY, score;
int tailX, tailY;
int nTail;
enum eDirection { STOP, LEFT, RIGHT, UP, DOWN };
enum eDirection dir;

void Setup() {
    dir = STOP;
    x = WIDTH / 2;
    y = HEIGHT / 2;
    fruitX = rand() % WIDTH;
    fruitY = rand() % HEIGHT;
    score = 0;
    nTail = 0;
}

void Draw() {
    system("cls");
    for (int i = 0; i < WIDTH + 2; i++) printf("#");
    printf("\n");

    for (int i = 0; i < HEIGHT; i++) {
      for (int j = 0; j < WIDTH; j++) {
            if (j == 0) printf("#");
            if (i == y && j == x) printf("O");
            else if (i == fruitY && j == fruitX) printf("F");
            else {
                int print = 0;
                for (int k = 0; k < nTail; k++) {
                  if (tailX == j && tailY == i) {
                        printf("o");
                        print = 1;
                  }
                }
                if (!print) printf(" ");
            }
            if (j == WIDTH - 1) printf("#");
      }
      printf("\n");
    }

    for (int i = 0; i < WIDTH + 2; i++) printf("#");
    printf("\nScore:%d", score);
}

void Input() {
    if (_kbhit()) {
      switch (_getch()) {
            case 'a': dir = LEFT; break;
            case 'd': dir = RIGHT; break;
            case 'w': dir = UP; break;
            case 's': dir = DOWN; break;
            case 'x': dir = STOP; break;
      }
    }
}

void Logic() {
    int prevX = tailX;
    int prevY = tailY;
    int prev2X, prev2Y;
    tailX = x;
    tailY = y;

    for (int i = 1; i < nTail; i++) {
      prev2X = tailX;
      prev2Y = tailY;
      tailX = prevX;
      tailY = prevY;
      prevX = prev2X;
      prevY = prev2Y;
    }

    switch (dir) {
      case LEFT: x--; break;
      case RIGHT: x++; break;
      case UP: y--; break;
      case DOWN: y++; break;
    }

    if (x >= WIDTH) x = 0; else if (x < 0) x = WIDTH - 1;
    if (y >= HEIGHT) y = 0; else if (y < 0) y = HEIGHT - 1;

    for (int i = 0; i < nTail; i++)
      if (tailX == x && tailY == y)
            dir = STOP;

    if (x == fruitX && y == fruitY) {
      score += 10;
      nTail++;
      fruitX = rand() % WIDTH;
      fruitY = rand() % HEIGHT;
    }
}

int main() {
    Setup();
    while (dir != STOP) {
      Draw();
      Input();
      Logic();
      Sleep(100);
    }
    return 0;
}

C++版本(使用cout等C++特性):

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <cstdlib>
using namespace std;

const int WIDTH = 20;
const int HEIGHT = 15;

int x, y, fruitX, fruitY, score;
int tailX, tailY;
int nTail;
enum eDirection { STOP, LEFT, RIGHT, UP, DOWN };
eDirection dir;

void Setup() {
    dir = STOP;
    x = WIDTH / 2;
    y = HEIGHT / 2;
    fruitX = rand() % WIDTH;
    fruitY = rand() % HEIGHT;
    score = 0;
    nTail = 0;
}

void Draw() {
    system("cls");
    for (int i = 0; i < WIDTH + 2; i++) cout << "#";
    cout << endl;

    for (int i = 0; i < HEIGHT; i++) {
      for (int j = 0; j < WIDTH; j++) {
            if (j == 0) cout << "#";
            if (i == y && j == x) cout << "O";
            else if (i == fruitY && j == fruitX) cout << "F";
            else {
                bool print = false;
                for (int k = 0; k < nTail; k++) {
                  if (tailX == j && tailY == i) {
                        cout << "o";
                        print = true;
                  }
                }
                if (!print) cout << " ";
            }
            if (j == WIDTH - 1) cout << "#";
      }
      cout << endl;
    }

    for (int i = 0; i < WIDTH + 2; i++) cout << "#";
    cout << endl << "Score:" << score << endl;
}

void Input() {
    if (_kbhit()) {
      switch (_getch()) {
            case 'a': dir = LEFT; break;
            case 'd': dir = RIGHT; break;
            case 'w': dir = UP; break;
            case 's': dir = DOWN; break;
            case 'x': dir = STOP; break;
      }
    }
}

void Logic() {
    int prevX = tailX;
    int prevY = tailY;
    int prev2X, prev2Y;
    tailX = x;
    tailY = y;

    for (int i = 1; i < nTail; i++) {
      prev2X = tailX;
      prev2Y = tailY;
      tailX = prevX;
      tailY = prevY;
      prevX = prev2X;
      prevY = prev2Y;
    }

    switch (dir) {
      case LEFT: x--; break;
      case RIGHT: x++; break;
      case UP: y--; break;
      case DOWN: y++; break;
    }

    if (x >= WIDTH) x = 0; else if (x < 0) x = WIDTH - 1;
    if (y >= HEIGHT) y = 0; else if (y < 0) y = HEIGHT - 1;

    for (int i = 0; i < nTail; i++)
      if (tailX == x && tailY == y)
            dir = STOP;

    if (x == fruitX && y == fruitY) {
      score += 10;
      nTail++;
      fruitX = rand() % WIDTH;
      fruitY = rand() % HEIGHT;
    }
}

int main() {
    Setup();
    while (dir != STOP) {
      Draw();
      Input();
      Logic();
      Sleep(100);
    }
    return 0;
}

说明:
- 游戏界面宽度 WIDTH 和高度 HEIGHT 可修改。
- 蛇头用 O 表示,食物用 F 表示,蛇身用 o 表示。
- 通过 Sleep(100) 控制游戏速度,数值越大速度越慢。
- 注意:代码使用了 Windows 特有的头文件(如 windows.h 和 conio.h),如果在其他系统编译,可能需要替换相关函数。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 贪吃蛇代码