c++贪吃蛇(可优化)
到dev-c++上运行,其中一半用豆包写的
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>
using namespace std;
// 定义方向枚举
enum Direction { UP, DOWN, LEFT, RIGHT };
// 定义坐标结构体
struct Point {
int x, y;
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
// 定义食物结构体,包含位置和对应的字母
struct Food {
Point pos;
char letter;
Food(int x, int y, char l) : pos(x, y), letter(l) {}
};
// 定义蛇类
class Snake {
private:
vector<Point> body;
vector<char> bodyLetters; // 新增:存储蛇身体各部分对应的字母
Direction dir;
bool alive;
int score;
public:
Snake(int x, int y) {
body.push_back(Point(x, y));
bodyLetters.push_back('O'); // 蛇头用大写 O 表示
dir = RIGHT;
alive = true;
score = 0;
}
void changeDirection(Direction newDir) {
if ((dir == UP && newDir != DOWN) ||
(dir == DOWN && newDir != UP) ||
(dir == LEFT && newDir != RIGHT) ||
(dir == RIGHT && newDir != LEFT)) {
dir = newDir;
}
}
void move() {
Point head = body.front();
switch (dir) {
case UP: head.y--; break;
case DOWN: head.y++; break;
case LEFT: head.x--; break;
case RIGHT: head.x++; break;
}
body.insert(body.begin(), head);
bodyLetters.insert(bodyLetters.begin(), 'O'); // 新的蛇头是大写 O
body.pop_back();
bodyLetters.pop_back();
}
void grow(char letter) {
Point tail = body.back();
body.push_back(tail);
bodyLetters.push_back(letter); // 增长的身体使用吃到的字母
score++;
}
Point getHead() const {
return body.front();
}
vector<Point> getBody() const {
return body;
}
vector<char> getBodyLetters() const {
return bodyLetters;
}
bool isAlive() const {
return alive;
}
int getScore() const {
return score;
}
void checkCollision(int width, int height, vector<Food>& foods) {
Point head = getHead();
// 检查边界碰撞
if (head.x <= 0 || head.x >= width - 1 || head.y <= 0 || head.y >= height - 1) {
alive = false;
return;
}
// 检查身体碰撞
for (size_t i = 1; i < body.size(); i++) {
if (head.x == body[i].x && head.y == body[i].y) {
// 去除重叠部分
body.erase(body.begin() + i, body.end());
bodyLetters.erase(bodyLetters.begin() + i, bodyLetters.end());
break;
}
}
// 检查食物碰撞
for (size_t i = 0; i < foods.size(); i++) {
if (head.x == foods[i].pos.x && head.y == foods[i].pos.y) {
grow(foods[i].letter);
foods.erase(foods.begin() + i);
break;
}
}
}
};
// 生成随机食物
Food generateFood(int width, int height, const vector<Point>& snakeBody, const vector<Food>& existingFoods) {
Point foodPos;
bool valid;
char randomLetter = 'a' + rand() % 26; // 生成随机小写字母
do {
valid = true;
foodPos.x = rand() % (width - 2) + 1;
foodPos.y = rand() % (height - 2) + 1;
// 检查是否与蛇身体或现有食物重叠
for (size_t i = 0; i < snakeBody.size(); i++) {
if (foodPos.x == snakeBody[i].x && foodPos.y == snakeBody[i].y) {
valid = false;
break;
}
}
if (valid) {
for (size_t i = 0; i < existingFoods.size(); i++) {
if (foodPos.x == existingFoods[i].pos.x && foodPos.y == existingFoods[i].pos.y) {
valid = false;
break;
}
}
}
} while (!valid);
return Food(foodPos.x, foodPos.y, randomLetter);
}
// 清屏函数
void clearScreen() {
HANDLE hOut;
COORD Position;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
Position.X = 0;
Position.Y = 0;
SetConsoleCursorPosition(hOut, Position);
}
// 绘制游戏界面
void draw(int width, int height, const Snake& snake, const vector<Food>& foods) {
clearScreen();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (x == 0 || x == width - 1 || y == 0 || y == height - 1) {
cout << '#';
} else {
bool isSnake = false;
const vector<Point> snakeBody = snake.getBody();
const vector<char> snakeLetters = snake.getBodyLetters();
for (size_t i = 0; i < snakeBody.size(); i++) {
if (snakeBody[i].x == x && snakeBody[i].y == y) {
cout << snakeLetters[i];
isSnake = true;
break;
}
}
if (!isSnake) {
bool isFood = false;
for (size_t i = 0; i < foods.size(); i++) {
if (foods[i].pos.x == x && foods[i].pos.y == y) {
cout << foods[i].letter;
isFood = true;
break;
}
}
if (!isFood) {
cout << '.';
}
}
}
}
cout << endl;
}
cout << "Score: " << snake.getScore() << endl;
}
int main() {
srand(time(NULL));
const int width = 20;
const int height = 20;
Snake snake(width / 2, height / 2);
vector<Food> foods;
// 初始化 5 个食物
for (int i = 0; i < 5; i++) {
foods.push_back(generateFood(width, height, snake.getBody(), foods));
}
while (snake.isAlive()) {
if (_kbhit()) {
char ch = _getch();
switch (ch) {
case 'w': snake.changeDirection(UP); break;
case 's': snake.changeDirection(DOWN); break;
case 'a': snake.changeDirection(LEFT); break;
case 'd': snake.changeDirection(RIGHT); break;
}
}
snake.move();
snake.checkCollision(width, height, foods);
// 确保始终有 5 个食物
while (foods.size() < 5) {
foods.push_back(generateFood(width, height, snake.getBody(), foods));
}
draw(width, height, snake, foods);
Sleep(100);
}
cout << "Game Over! Final Score: " << snake.getScore() << endl;
return 0;
}
如果你感兴趣的话也可以看看我的其他作品
扫雷
乒乓球游戏
口袋奇兵
逃离后室游戏
可以点个赞吗