C语言学习—-贪吃蛇

C语言——贪吃蛇

头文件,定义成绩变量

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>

#define map_row 50 //行数列数
#define map_col 50

int score=0;

定义蛇和食物的结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct Snakes
{
int x;
int y;
struct Snakes *next;
}snake;

snake *head,*tail;

struct Foods
{
int x;
int y;
}food;

设置对鼠标的控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
char key=0;

void push_key(){
if(kbhit()){
key=getch();
}
}


void gotoxy(int x,int y){
// 更新光标位置
COORD pos; //结构体对象存放光标坐标
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); //获取窗口句柄
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hOutput, pos); //将光标移动到指定位置

//隐藏光标
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible = 0;//0表示隐藏,1表示显示
cursor.dwSize = 1;
SetConsoleCursorInfo(hOutput, &cursor);
}

画地图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void drawmap(){
for(int i=0;i<map_col;i+=2)
{
gotoxy(i,0);
printf("*");
gotoxy(i,map_row/2-3);
printf("*");
}

for(int i=1;i<map_row/2-3;i++)
{
gotoxy(0,i);
printf("*");
gotoxy(map_col-2,i);
printf("*");
}

}

用链表创造蛇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void creatsnake(){
snake *body;
head = (snake *)malloc(sizeof(snake));
body=(snake *)malloc(sizeof(snake));
tail=(snake *)malloc(sizeof(snake));

head->x=14;
head->y=15;
body->x=14;
body->y=16;
tail->x=14;
tail->y=17;

head->next=body;
body->next=tail;
tail->next=NULL;
}

打印蛇

1
2
3
4
5
6
7
8
9
10
void printsanke(){
snake *p=head;
while(p->next!=NULL){
gotoxy(p->x,p->y);
printf("o");
p=p->next;
}
gotoxy(p->x,p->y);
printf("o");
}

创建随机出现的食物

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void creatfood(){
srand((unsigned)time(NULL));
int x;
int flag=0;
while(!flag){
flag=1;
x=rand()%(map_col-4)+1;
food.x = x%2==0?x:x+1;
food.y = rand() % (map_row/2-4) +1;

snake* judge = head;
while (1) //遍历排除蛇身重复
{
if (judge->next == NULL) break;
if (food.x == judge->x && food.y == judge->y)
{
flag = 0;
}
judge = judge->next;
}
}

gotoxy(food.x,food.y);
printf("@");
}

让蛇动起来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void movesnake(){
int speed;
int x=head->x;
int y=head->y;
snake *p,*q;

switch (key)
{
case 'w':
y--;
break;
case 's':
y++;
break;
case 'a':
x-=2;
break;
case 'd':
x+=2;
break;
default:
break;
}
if(x!=head->x||y!=head->y){
p=q=head;
snake *newhead=(snake *)malloc(sizeof(snake)); //创建新蛇头节点
newhead->x=x;
newhead->y=y;
newhead->next = head; //将新蛇头接到老蛇头上
head=newhead;
gotoxy(head->x,head->y); //打印新蛇头
printf("o");
while(p->next!=NULL){
q=p;
p=p->next;
} //移动到蛇尾。删除蛇尾,并插除蛇尾。
gotoxy(p->x,p->y);
printf(" ");
q->next=NULL;
free(p);
speed=250-score*10; //加速
speed<100?100:speed;
Sleep(speed); //延时
}
}

设置蛇吃食物会变长

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void eatfood(){
if (head->x == food.x && head->y == food.y)
{

creatfood();
snake* _new = (snake*)malloc(sizeof(snake));
snake* p;
p = head;
while (1)
{
if (p->next == NULL) break;
p = p->next;
}
p->next = _new;
_new->next = NULL;
score++;
gotoxy(0,map_row/2+1);
printf("score:%d",score); //吃食物得分
}
}

判定死亡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//判断撞墙 
int judge_wall(){
if(head->x==0||head->y==0||head->x==map_col-2||head->y==map_row/2-3) return 1;
else return 0;
}

//判断撞自己
int judge_self(){
snake* judge = head->next;
while (judge->next!=NULL) //遍历排除蛇身重复
{

if (head->x == judge->x && head->y == judge->y)
{
return 1;
}
judge = judge->next;
}
if (head->x == judge->x && head->y == judge->y)
{
return 1;
}
return 0;
}

主程序,调用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void main () {

drawmap();
creatsnake();
printsanke();
creatfood();
while(1){
push_key();
movesnake();
eatfood();
if (judge_wall()||judge_self()){
gotoxy(0,map_row/2+2);
printf("Game Over");
break;
}
}
getch();
}