#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#define UP 1 //蛇的状态
#define DOWN 2
#define LEFT 3
#define RIGHT 4
typedef struct Snake {
int x;
int y;
struct Snake* next;
}Snake;
//全局变量
int length = 58, width = 26; //地图长宽
int score = 0, add = 10; //总得分与每次吃食物得分。
int sleeptime = 200; //每次运行的时间间隔
int status; //控制方向
Snake* head, * food; //蛇头指针,食物指针
Snake* q; //遍历蛇的时候用到的指针
int endgamestatus = 0; //游戏结束 1:撞到墙 2:咬到自己 3:主动退出
//声明
void Endgame(); //结束游戏
void Pos(); //控制光标位置
void CreateMap(); //创建地图
void InitSnake(); //初始化蛇身
int BitSelf(); //判断是否咬到自己
void BitWall(); //判断是否撞墙
void CreateFood(); //随机出现食物
void pause(); //暂停函数
void SnakeMove(); //移动,绑定键盘上下左右键
void GameCircle(); //控制游戏
void Welcome(); //开始界面
void GameStart(); //游戏初始化
void Pos(int x, int y) {
COORD pos; //位置
HANDLE HOutput; //句柄
pos.X = x;
pos.Y = y;
HOutput = GetStdHandle(STD_OUTPUT_HANDLE); //控制台输出句柄
SetConsoleCursorPosition(HOutput, pos); //控制光标位置函数
}
void CreateMap() {
for (int i = 0; i < length; i += 2) { //打印上下边框
Pos(i, 0);
printf("■");
Pos(i, width);
printf("■");
}
for (int i = 1; i < width; i++) { //打印左右边框
Pos(0, i);
printf("■");
Pos(length - 2, i);
printf("■");
}
}
void pause() { //暂停
while (1) { //按空格后进入该函数循环
Sleep(300); //再次按空格跳出循环继续游戏
if (GetAsyncKeyState(VK_SPACE)) { //检查键盘(空格)
break;
}
}
}
void InitSnake() {
Snake* tail = (Snake*)malloc(sizeof(Snake));
tail->x = 24; //初始位置(24,5),3格长
tail->y = 5;
tail->next = nullptr;
for (int i = 0; i < 4; i++) {
head = (Snake*)malloc(sizeof(Snake)); //头插法
head->next = tail;
head->x = 24 + 2 * i;
head->y = 5;
tail = head;
}
while (tail != nullptr) { //打印蛇身
Pos(tail->x, tail->y);
printf("■");
tail = tail->next;
}
}
int BitSelf() {
Snake* self = head->next;
while (self != nullptr) {
if (self->x == head->x && self->y == head->y) {
return 1;
}
self = self->next;
}
return 0;
}
void BitWall() {
if (head->x == 0 || head->x == length - 2 || head->y == 0 || head->y == width) {
endgamestatus = 1;
Endgame();
}
}
void CreateFood() {
Snake* food_1 = (Snake*)malloc(sizeof(Snake));
srand((unsigned)time(nullptr));
while (food_1->x % 2 != 0) //保证x为偶数
food_1->x = rand() % (length - 6) + 2;
food_1->y = rand() % (width - 2) + 1;
q = head;
while (q->next != nullptr) {
if (q->x == food_1->x && q->y == food_1->y) { //判断蛇身是否与食物重叠
free(food_1);
CreateFood(); //有重叠则重新放置
}
q = q->next;
}
Pos(food_1->x, food_1->y);
food = food_1;
printf("■");
}
void SnakeMove() {
Snake* nexthead = (Snake*)malloc(sizeof(Snake));
BitWall();
if (status == UP) {
nexthead->x = head->x;
nexthead->y = head->y - 1;
nexthead->next = head;
head = nexthead;
q = head;
//碰到食物
if (nexthead->x == food->x && nexthead->y == food->y) {
while (q != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score += add;
CreateFood();
}
else {
while (q->next->next != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = nullptr;
}
if (BitSelf() == 1) { //判断是否会咬到自己
endgamestatus = 2;
Endgame();
}
}
if (status == DOWN) {
nexthead->x = head->x;
nexthead->y = head->y + 1;
nexthead->next = head;
head = nexthead;
q = head;
//碰到食物
if (nexthead->x == food->x && nexthead->y == food->y) {
while (q != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score += add;
CreateFood();
}
else {
while (q->next->next != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = nullptr;
}
if (BitSelf() == 1) {
endgamestatus = 2;
Endgame();
}
}
if (status == LEFT) {
nexthead->x = head->x - 2;
nexthead->y = head->y;
nexthead->next = head;
head = nexthead;
q = head;
//碰到食物
if (nexthead->x == food->x && nexthead->y == food->y) {
while (q != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score += add;
CreateFood();
}
else {
while (q->next->next != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = nullptr;
}
if (BitSelf() == 1) {
endgamestatus = 2;
Endgame();
}
}
if (status == RIGHT) {
nexthead->x = head->x + 2;
nexthead->y = head->y;
nexthead->next = head;
head = nexthead;
q = head;
//碰到食物
if (nexthead->x == food->x && nexthead->y == food->y) {
while (q != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score += add;
CreateFood();
}
else {
while (q->next->next != nullptr) {
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = nullptr;
}
if (BitSelf() == 1) {
endgamestatus = 2;
Endgame();
}
}
}
void GameCircle() {
Pos(64, 15);
printf("不能穿墙,不能咬到自己\n");
Pos(64, 16);
printf("用↑.↓.←.→分别控制蛇的移动.");
Pos(64, 17);
printf("ESC :退出游戏.space:暂停游戏.");
Pos(64, 20);
status = RIGHT;
while (1) {
Pos(64, 10);
printf("得分:%d ", score);
Pos(64, 11);
printf("每个食物得分:%d分", add);
if (GetAsyncKeyState(VK_UP) && status != DOWN)
status = UP;
else if (GetAsyncKeyState(VK_LEFT) && status != RIGHT)
status = LEFT;
else if (GetAsyncKeyState(VK_RIGHT) && status != LEFT)
status = RIGHT;
else if (GetAsyncKeyState(VK_DOWN) && status != UP)
status = DOWN;
else if (GetAsyncKeyState(VK_SPACE))
pause();
else if (GetAsyncKeyState(VK_ESCAPE)) {
endgamestatus = 3;
break;
}
Sleep(sleeptime);
SnakeMove();
}
}
void Welcome() {
Pos(40, 12);
printf("欢迎来到贪食蛇游戏!");
Pos(40, 25);
system("pause"); //暂停函数
system("cls");
Pos(25, 12);
printf("用↑.↓.←.→分别控制蛇的移动\n");
system("pause");
system("cls");
}
void Endgame() {
system("cls");
Pos(24, 12);
if (endgamestatus == 1) {
printf("您撞到墙了,游戏结束.");
}
else if (endgamestatus == 2) {
printf("您咬到自己了,游戏结束.");
}
else if (endgamestatus == 3) {
printf("您结束了游戏。");
}
Pos(24, 13);
printf("您的得分是%d\n", score);
exit(0);
}
void GameStart() {
system("mode con cols=100 lines=30");
Welcome();
CreateMap();
InitSnake();
CreateFood();
}
int main() {
GameStart();
GameCircle();
Endgame();
return 0;
}
贪吃蛇(c++)
于 2024-05-05 21:08:27 首次发布