用c语言写出贪吃蛇代码,包括数组、指针、结构体、文件
时间: 2023-11-17 16:08:18 浏览: 47
以下是一个基于控制台的贪吃蛇C语言代码,包括数组、指针、结构体和文件操作:
```c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#define WIDTH 40 // 地图宽度
#define HEIGHT 20 // 地图高度
#define INIT_LEN 3 // 初始蛇身长度
#define FPS 10 // 帧率
typedef struct {
int x;
int y;
} Point;
typedef struct {
Point head;
Point tail;
int len;
Point *pBody;
} Snake;
typedef struct {
Point pos;
int value;
} Food;
typedef struct {
char name[20];
int score;
} Record;
int map[HEIGHT][WIDTH]; // 地图
Snake snake; // 蛇
Food food; // 食物
int score = 0; // 得分
void init(); // 初始化
void draw(); // 绘制
void update(); // 更新
void createFood(); // 生成食物
void moveSnake(); // 移动蛇
int getDirection(); // 获取方向
int isGameOver(); // 判断游戏是否结束
void saveRecord(); // 保存记录
void showRecord(); // 显示记录
int main() {
init(); // 初始化
while (1) {
draw(); // 绘制
update(); // 更新
Sleep(1000 / FPS); // 控制帧率
}
return 0;
}
void init() {
// 初始化地图
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (i == 0 || i == HEIGHT - 1 || j == 0 || j == WIDTH - 1) {
map[i][j] = -1; // 边界
} else {
map[i][j] = 0; // 空格
}
}
}
// 初始化蛇
snake.head.x = WIDTH / 2;
snake.head.y = HEIGHT / 2;
snake.tail.x = snake.head.x - INIT_LEN + 1;
snake.tail.y = snake.head.y;
snake.len = INIT_LEN;
snake.pBody = (Point*)malloc(INIT_LEN * sizeof(Point));
for (int i = 0; i < INIT_LEN; i++) {
snake.pBody[i].x = snake.tail.x + i;
snake.pBody[i].y = snake.tail.y;
map[snake.pBody[i].y][snake.pBody[i].x] = i + 1;
}
// 初始化食物
createFood();
// 初始化得分
score = 0;
// 设置随机数种子
srand(time(NULL));
}
void draw() {
system("cls"); // 清屏
// 绘制地图
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (map[i][j] == -1) {
printf("#"); // 边界
} else if (map[i][j] == 0) {
printf(" "); // 空格
} else {
printf("o"); // 蛇身
}
}
printf("\n");
}
// 绘制食物
printf("Food: [%d, %d]\n", food.pos.x, food.pos.y);
// 绘制得分
printf("Score: %d\n", score);
}
void update() {
// 获取方向
int dir = getDirection();
// 移动蛇
moveSnake(dir);
// 判断游戏是否结束
if (isGameOver()) {
printf("Game over!\n");
saveRecord();
showRecord();
exit(0);
}
}
void createFood() {
while (1) {
int x = rand() % (WIDTH - 2) + 1;
int y = rand() % (HEIGHT - 2) + 1;
if (map[y][x] == 0) {
food.pos.x = x;
food.pos.y = y;
food.value = 1;
map[y][x] = -2; // 食物
break;
}
}
}
void moveSnake(int dir) {
// 更新蛇头位置
switch (dir) {
case 0: // 上
snake.head.y--;
break;
case 1: // 右
snake.head.x++;
break;
case 2: // 下
snake.head.y++;
break;
case 3: // 左
snake.head.x--;
break;
}
// 判断是否吃到食物
if (snake.head.x == food.pos.x && snake.head.y == food.pos.y) {
snake.len++;
score += food.value;
createFood();
}
// 更新蛇身位置
map[snake.tail.y][snake.tail.x] = 0;
for (int i = snake.len - 1; i > 0; i--) {
snake.pBody[i] = snake.pBody[i - 1];
}
snake.pBody[0] = snake.head;
for (int i = 0; i < snake.len; i++) {
map[snake.pBody[i].y][snake.pBody[i].x] = i + 1;
}
// 更新蛇尾位置
snake.tail = snake.pBody[snake.len - 2];
}
int getDirection() {
if (_kbhit()) { // 如果有键盘输入
int ch = _getch();
if (ch == 27) { // ESC
printf("Game over!\n");
saveRecord();
showRecord();
exit(0);
} else if (ch == 'w' || ch == 'W') { // 上
if (snake.head.y > snake.pBody[0].y) return 2; // 不允许反向移动
return 0;
} else if (ch == 'd' || ch == 'D') { // 右
if (snake.head.x < snake.pBody[0].x) return 3;
return 1;
} else if (ch == 's' || ch == 'S') { // 下
if (snake.head.y < snake.pBody[0].y) return 0;
return 2;
} else if (ch == 'a' || ch == 'A') { // 左
if (snake.head.x > snake.pBody[0].x) return 1;
return 3;
}
}
return -1;
}
int isGameOver() {
// 撞墙
if (map[snake.head.y][snake.head.x] == -1) {
return 1;
}
// 撞到自己
for (int i = 1; i < snake.len; i++) {
if (snake.head.x == snake.pBody[i].x && snake.head.y == snake.pBody[i].y) {
return 1;
}
}
return 0;
}
void saveRecord() {
FILE *fp;
Record record;
printf("Enter your name: ");
scanf("%s", record.name);
record.score = score;
fp = fopen("record.bin", "ab");
fwrite(&record, sizeof(Record), 1, fp);
fclose(fp);
}
void showRecord() {
FILE *fp;
Record record;
printf("Ranking:\n");
fp = fopen("record.bin", "rb");
while (fread(&record, sizeof(Record), 1, fp) == 1) {
printf("%s: %d\n", record.name, record.score);
}
fclose(fp);
}
```
在这个代码中,我们定义了四个结构体类型:Point 表示一个二维坐标,Snake 表示蛇的结构体,包括蛇头、蛇尾、蛇身长度和蛇身数组的指针,Food 表示食物的结构体,包括食物位置和分值,Record 表示游戏记录的结构体,包括玩家名字和得分。我们使用指针来动态分配蛇身数组的内存,并在游戏结束后释放内存。我们还使用了文件操作来保存游戏记录,并在游戏结束后显示游戏记录。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)