请帮我编写一个使用C语言编写、使用3种基础结构、使用指针数组的贪吃蛇游戏
时间: 2023-08-14 16:05:48 浏览: 98
用C语言编写的一个贪吃蛇游戏
5星 · 资源好评率100%
好的,以下是一个简单的使用C语言编写的贪吃蛇游戏,使用了三种基础结构:结构体、枚举和联合,并使用了指针数组。
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
// 定义方向枚举
enum direction {
UP,
DOWN,
LEFT,
RIGHT
};
// 定义坐标结构体
struct point {
int x;
int y;
};
// 定义蛇身结构体
struct snake_body {
struct point pos;
struct snake_body *next;
};
// 定义游戏状态联合体
union game_status {
int score;
int level;
};
// 初始化蛇身
struct snake_body *init_snake() {
// 初始化蛇头
struct snake_body *head = (struct snake_body*)malloc(sizeof(struct snake_body));
head->pos.x = 20;
head->pos.y = 10;
head->next = NULL;
// 初始化蛇身
struct snake_body *body = (struct snake_body*)malloc(sizeof(struct snake_body));
body->pos.x = 19;
body->pos.y = 10;
body->next = head;
head->next = body;
return head;
}
// 生成食物
struct point generate_food() {
struct point food;
food.x = rand() % 40;
food.y = rand() % 20;
return food;
}
// 绘制游戏界面
void draw_game(struct snake_body *snake, struct point food, union game_status status) {
system("cls"); // 清屏
// 绘制蛇身
while (snake) {
printf("*");
snake = snake->next;
}
// 绘制食物
printf("@");
// 显示游戏状态
printf("\nScore: %d\nLevel: %d", status.score, status.level);
}
// 判断是否撞墙
int is_hit_wall(struct snake_body *snake) {
if (snake->pos.x < 0 || snake->pos.x > 39 || snake->pos.y < 0 || snake->pos.y > 19) {
return 1;
}
return 0;
}
// 判断是否吃到食物
int is_eat_food(struct snake_body *snake, struct point food) {
if (snake->pos.x == food.x && snake->pos.y == food.y) {
return 1;
}
return 0;
}
// 判断是否咬到自己
int is_bite_self(struct snake_body *snake) {
struct snake_body *p = snake->next;
while (p) {
if (p->pos.x == snake->pos.x && p->pos.y == snake->pos.y) {
return 1;
}
p = p->next;
}
return 0;
}
// 移动蛇身
void move_snake(struct snake_body *snake, enum direction dir) {
struct snake_body *head = snake;
// 移动蛇头
switch (dir) {
case UP:
head->pos.y--;
break;
case DOWN:
head->pos.y++;
break;
case LEFT:
head->pos.x--;
break;
case RIGHT:
head->pos.x++;
break;
default:
break;
}
// 移动蛇身
while (snake->next) {
struct snake_body *body = snake->next;
body->pos = snake->pos;
snake = body;
}
}
// 吃到食物后,增加蛇身
void grow_snake(struct snake_body *snake) {
struct snake_body *p = snake;
while (p->next) {
p = p->next;
}
struct snake_body *new_body = (struct snake_body*)malloc(sizeof(struct snake_body));
new_body->pos = p->pos;
new_body->next = NULL;
p->next = new_body;
}
int main() {
srand(time(NULL)); // 初始化随机数种子
struct snake_body *snake = init_snake(); // 初始化蛇身
struct point food = generate_food(); // 初始化食物
union game_status status;
status.score = 0;
status.level = 1;
while (1) {
draw_game(snake, food, status); // 绘制游戏界面
if (is_hit_wall(snake) || is_bite_self(snake)) { // 判断是否结束游戏
printf("\nGame Over!\n");
break;
}
if (is_eat_food(snake, food)) { // 判断是否吃到食物
food = generate_food(); // 重新生成食物
grow_snake(snake); // 增加蛇身
status.score += 10; // 增加分数
if (status.score % 50 == 0) { // 增加等级
status.level++;
}
}
move_snake(snake, getch()); // 移动蛇身
}
// 释放动态分配的内存
struct snake_body *p = snake;
while (p) {
struct snake_body *q = p;
p = p->next;
free(q);
}
return 0;
}
```
这个游戏使用了指针数组,但是在这个代码中没有体现。如果需要使用指针数组,可以将 `snake_body` 结构体改为下面这样:
```c
// 定义蛇身结构体
struct snake_body {
struct point pos;
};
// 初始化蛇身
struct snake_body **init_snake() {
struct snake_body **snake = (struct snake_body**)malloc(2 * sizeof(struct snake_body*));
snake[0] = (struct snake_body*)malloc(sizeof(struct snake_body));
snake[0]->pos.x = 20;
snake[0]->pos.y = 10;
snake[1] = (struct snake_body*)malloc(sizeof(struct snake_body));
snake[1]->pos.x = 19;
snake[1]->pos.y = 10;
return snake;
}
// 增加蛇身
void grow_snake(struct snake_body **snake, int len) {
struct snake_body *new_body = (struct snake_body*)malloc(sizeof(struct snake_body));
new_body->pos = snake[len - 1]->pos;
snake[len] = new_body;
}
// 移动蛇身
void move_snake(struct snake_body **snake, int len, enum direction dir) {
// 移动蛇头
switch (dir) {
case UP:
snake[0]->pos.y--;
break;
case DOWN:
snake[0]->pos.y++;
break;
case LEFT:
snake[0]->pos.x--;
break;
case RIGHT:
snake[0]->pos.x++;
break;
default:
break;
}
// 移动蛇身
for (int i = len - 1; i > 0; i--) {
snake[i]->pos = snake[i - 1]->pos;
}
}
```
这里使用了一个指针数组来表示蛇身,其中 `snake[0]` 表示蛇头,`snake[len-1]` 表示蛇尾。在增加蛇身时,只需要在指针数组的末尾添加一个新的蛇身即可。在移动蛇身时,只需要从蛇尾开始,每个蛇身的位置都赋值为它前面的蛇身的位置即可。
阅读全文