用C++制作一个完整贪吃蛇代码
时间: 2023-06-11 13:09:02 浏览: 76
以下是一个贪吃蛇游戏的C语言代码,包含了基本的游戏逻辑和图形界面显示。建议在CodeBlocks等IDE中运行。
```c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#define ROW 20 // 地图行数
#define COL 30 // 地图列数
#define FOOD_MAX 5 // 食物数量上限
typedef struct position {
int x;
int y;
} Position;
typedef struct snake {
Position body[ROW * COL]; // 蛇身体部位
int len; // 蛇长度
char direction; // 蛇所朝方向(w a s d)
} Snake;
typedef struct food {
Position pos[FOOD_MAX];
int num; // 当前食物数
} Food;
void initMap(char map[ROW][COL]) { // 初始化地图
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (i == 0 || i == ROW - 1 || j == 0 || j == COL - 1) {
map[i][j] = '#'; // 墙壁
} else {
map[i][j] = ' '; // 空地
}
}
}
}
void printMap(char map[ROW][COL]) { // 打印地图
system("cls"); // 清屏
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
printf("%c", map[i][j]);
}
printf("\n");
}
}
void initSnake(Snake* snake) { // 初始化蛇
snake->len = 3;
snake->direction = 'd';
snake->body[0].x = ROW / 2;
snake->body[0].y = COL / 2;
for (int i = 1; i < snake->len; i++) {
snake->body[i].x = snake->body[i - 1].x - 1;
snake->body[i].y = snake->body[i - 1].y;
}
}
void printSnake(char map[ROW][COL], Snake* snake) { // 打印蛇
for (int i = 0; i < snake->len; i++) {
map[snake->body[i].x][snake->body[i].y] = '*';
}
}
void updateSnake(Snake* snake) { // 更新蛇
for (int i = snake->len - 1; i > 0; i--) {
snake->body[i].x = snake->body[i - 1].x;
snake->body[i].y = snake->body[i - 1].y;
}
switch (snake->direction) {
case 'w':
snake->body[0].x--;
break;
case 'a':
snake->body[0].y--;
break;
case 's':
snake->body[0].x++;
break;
case 'd':
snake->body[0].y++;
break;
}
}
void initFood(Food* food) { // 初始化食物
food->num = 0;
}
void addFood(Food* food) { // 添加食物
if (food->num < FOOD_MAX) {
int x, y;
do {
x = rand() % (ROW - 2) + 1;
y = rand() % (COL - 2) + 1;
} while (food->num > 0 && food->pos[food->num - 1].x == x && food->pos[food->num - 1].y == y); // 避免新食物出现在蛇身上
food->pos[food->num].x = x;
food->pos[food->num].y = y;
food->num++;
}
}
void printFood(char map[ROW][COL], Food* food) { // 打印食物
for (int i = 0; i < food->num; i++) {
map[food->pos[i].x][food->pos[i].y] = '$';
}
}
int checkGameOver(Snake* snake) { // 检测游戏是否结束
if (snake->body[0].x == 0 || snake->body[0].x == ROW - 1 || snake->body[0].y == 0 || snake->body[0].y == COL - 1) { // 撞墙
return 1;
}
for (int i = 1; i < snake->len; i++) {
if (snake->body[0].x == snake->body[i].x && snake->body[0].y == snake->body[i].y) { // 撞自己
return 1;
}
}
return 0;
}
int checkEatFood(Snake* snake, Food* food) { // 检测是否吃到食物
for (int i = 0; i < food->num; i++) {
if (snake->body[0].x == food->pos[i].x && snake->body[0].y == food->pos[i].y) {
return i; // 返回被吃食物的下标
}
}
return -1;
}
void updateFood(Food* food, int index) { // 更新食物
if (index >= 0 && index < food->num) {
for (int i = index; i < food->num - 1; i++) {
food->pos[i] = food->pos[i + 1];
}
food->num--;
}
}
void updateSpeed(int score) { // 根据得分更新游戏速度
int speed = 400 - score * 10;
if (speed < 50) {
speed = 50;
}
Sleep(speed);
}
int main() {
char map[ROW][COL]; // 地图
Snake snake; // 蛇
Food food; // 食物
int score = 0; // 得分
srand((unsigned) time(NULL)); // 初始化随机数种子
initMap(map); // 初始化地图
initSnake(&snake); // 初始化蛇
initFood(&food); // 初始化食物
addFood(&food); // 添加第一个食物
while (1) { // 游戏循环
printMap(map); // 打印地图
printSnake(map, &snake); // 打印蛇
printFood(map, &food); // 打印食物
printf("Score: %d\n", score); // 打印得分
updateSpeed(score); // 根据得分更新游戏速度
if (kbhit()) { // 监听键盘输入
char ch = getch();
if ((ch == 'w' && snake.direction != 's') || (ch == 'a' && snake.direction != 'd') || (ch == 's' && snake.direction != 'w') || (ch == 'd' && snake.direction != 'a')) { // 避免掉头
snake.direction = ch;
}
}
updateSnake(&snake); // 更新蛇
int eatIndex = checkEatFood(&snake, &food); // 检测是否吃到食物
if (eatIndex >= 0) { // 吃到食物
snake.body[snake.len].x = food.pos[eatIndex].x;
snake.body[snake.len].y = food.pos[eatIndex].y;
snake.len++;
updateFood(&food, eatIndex);
addFood(&food);
score++;
}
if (checkGameOver(&snake)) { // 游戏结束
printf("Game Over! Score: %d\n", score);
break;
}
}
return 0;
}
```