#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
#define UP 72
#define DOWN 80 //上下左右
#define LEFT 75
#define RIGHT 77
#define SPACE 32
#define ESC 27
#define KONG 0
#define WALL 1
#define FOOD 2
#define BODY 3
#define SIZE_X 23 //围墙尺寸大小
#define SIZE_Y 30
void gotoxy(
int x,
int y);
void hidden_cursor();
int color(
int c);
void inter_face();
void init_snake();
void draw_snake(
int x);
void rand_food();
void move_snake(
int x,
int y);
void run(
int x,
int y,
int *time_count);
void pd();
void game();
void MaxGrade();
int map[SIZE_X][SIZE_Y];
int speed=
1000;
int food;
int grade=
0;
int max_grade=
0;
const int snake_color=
11;
const int wall_color=
2;
const int food_color=
12;
struct Snake
{
int len;
int x;
int y;
}snake;
struct Body
{
int x;
int y;
};
struct Body body[SIZE_X*SIZE_Y];
int main()
{
system(
"title 贪吃蛇");
system(
"cls");
system(
"mode con cols=84 lines=26");
srand(time(NULL));
hidden_cursor();
grade=
0;
MaxGrade();
inter_face();
init_snake();
rand_food();
draw_snake(
1);
game();
return 0;
}
void game()
{
int n=RIGHT,time_count=
0,n_tmp;
goto loop;
while(
1)
{
n=getch();
switch(n)
{
case UP:
case DOWN:
if(n_tmp!=LEFT && n_tmp!=RIGHT) n=n_tmp;
break;
case LEFT:
case RIGHT:
if(n_tmp!=UP && n_tmp!=DOWN) n=n_tmp;
break;
case 'r':
case 'R':
case SPACE:
case ESC:
break;
default: n=n_tmp;
break;
}
loop:
switch(n)
{
case UP:
if(snake.x-
1!=body[
0].x)
{ run(-
1,
0,&time_count);
n_tmp=UP;
}
break;
case DOWN:
if(snake.x+
1!=body[
0].x)
{ run(
1,
0,&time_count);
n_tmp=DOWN;
}
break;
case LEFT:
if(snake.y-
1!=body[
0].y)
{
run(
0,-
1,&time_count);
n_tmp=LEFT;
}
break;
case RIGHT:
if(snake.y+
1!=body[
0].y)
{
run(
0,
1,&time_count);
n_tmp=RIGHT;
}
break;
case SPACE:
while(
1)
{
if(kbhit!=
0)
break;
}
break;
case ESC: gotoxy(SIZE_X+
1,
0);
printf(
"按任意键退出游戏!");
getch();
exit(
0);
break;
case 'r':
case 'R': main();
break;
}
}
}
void run(
int x,
int y,
int *time_count)
{
int t=
0;
while(
1)
{
if(*time_count==
0)
*time_count=speed;
while(--(*time_count))
{
if(t==
0)
t=
50000;
while(--t);
if(kbhit()!=
0)
break;
}
if(*time_count==
0)
{
move_snake(x,y);
pd();
}
else
break;
}
}
void pd()
{
if(map[snake.x][snake.y]==WALL || map[snake.x][snake.y]==BODY)
{
char n;
Sleep(
2000);
system(
"cls");
gotoxy(SIZE_X/
2-
2,
2*(SIZE_Y/
3));
if(grade>max_grade)
printf(
"恭喜您打破记录,目前最高纪录为:%d",grade);
else if(grade==max_grade)
printf(
"与纪录持平,请突破你的极限!");
else
printf(
"请继续努力,你与最高记录只差:%d",max_grade-grade);
gotoxy(SIZE_X/
2,
2*(SIZE_Y/
3));
printf(
"GAME OVER!\n");
MaxGrade();
do
{
gotoxy(SIZE_X/
2+
2,
2*(SIZE_Y/
3));
printf(
"是否重新开始游戏(y/n): ");
scanf(
"%c",&n);
gotoxy(SIZE_X/
2+
4,
2*(SIZE_Y/
3));
if(n!=
'n' && n!=
'N' && n!=
'y' && n!=
'Y')
printf(
"输入错误,请重新输入!");
else
break;
}
while(
1);
if(n==
'n' || n==
'N')
{
gotoxy(SIZE_X/
2+
4,
2*(SIZE_Y/
3));
printf(
"按任意键退出游戏!");
exit(
0);
}
else if(n==
'y' || n==
'Y')
main();
}
else if(map[snake.x][snake.y]==FOOD)
{
snake.len++;
grade+=
100;
if(speed>
400)
speed-=
20;
gotoxy(
7,
2*(SIZE_Y+
2));
printf(
"分数: %d",grade);
map[food/SIZE_Y][food%SIZE_Y]=KONG;
rand_food();
}
}
void rand_food()
{
do
{
food=rand()%(SIZE_X*SIZE_Y);
}
while(map[food/SIZE_Y][food%SIZE_Y]!=KONG);
map[food/SIZE_Y][food%SIZE_Y]=FOOD;
color(food_color);
gotoxy(food/SIZE_Y,
2*(food%SIZE_Y));
printf(
"★");
}
void move_snake(
int x,
int y)
{
int i;
draw_snake(
0);
map[body[snake.len-
1].x][body[snake.len-
1].y]=KONG;
map[snake.x][snake.y]=BODY;
for(i=snake.len-
1;i>
0;i--)
{
body[i].x=body[i-
1].x;
body[i].y=body[i-
1].y;
}
body[
0].x=snake.x;
body[
0].y=snake.y;
snake.x=snake.x+x;
snake.y=snake.y+y;
draw_snake(
1);
}
void draw_snake(
int x)
{
int i;
if(x!=
0)
{ color(snake_color);
gotoxy(snake.x,
2*snake.y);
printf(
"■");
for(i=
0;i<snake.len;i++)
{
gotoxy(body[i].x,
2*body[i].y);
printf(
"□");
}
}
else
{
if(body[snake.len-
1].x!=
0)
{ gotoxy(body[snake.len-
1].x,
2*body[snake.len-
1].y);
printf(
" ");
}
}
}
void inter_face()
{
int i,j;
for(i=
0;i<SIZE_X;i++)
{
for(j=
0;j<SIZE_Y+
12;j++)
{
if(i==
0 || j==
0 || i==SIZE_X-
1 || j==SIZE_Y-
1 || j==SIZE_Y+
11)
{
color(wall_color);
gotoxy(i,
2*j);
printf(
"■");
map[i][j]=WALL;
}
else if((i==SIZE_X/
3 || i==SIZE_X*
2/
3) && j>SIZE_Y/
3 && j<SIZE_Y*
2/
3)
{
gotoxy(i,
2*j);
printf(
"■");
map[i][j]=WALL;
}
else
{
gotoxy(i,
2*j);
printf(
" ");
map[i][j]=KONG;
}
}
printf(
"\n");
}
color(snake_color);
gotoxy(
5,
2*(SIZE_Y+
2));
printf(
"最高纪录: %d",max_grade);
gotoxy(
7,
2*(SIZE_Y+
2));
printf(
"分数: %d",grade);
gotoxy(
9,
2*(SIZE_Y+
2));
printf(
"重新开始: R");
gotoxy(
11,
2*(SIZE_Y+
2));
printf(
"暂停: space");
gotoxy(
13,
2*(SIZE_Y+
2));
printf(
"退出游戏: ESC");
}
void init_snake()
{
snake.len=
2;
snake.x=SIZE_X/
2;
snake.y=SIZE_Y/
2;
body[
0].x=SIZE_X/
2;
body[
0].y=SIZE_Y/
2-
1;
body[
1].x=SIZE_X/
2;
body[
1].y=SIZE_Y/
2-
2;
map[body[
0].x][body[
0].y]=BODY;
map[body[
1].x][body[
1].y]=BODY;
}
void MaxGrade()
{
FILE *fp;
fp=fopen(
"贪吃蛇最高记录.txt",
"r+");
if(fp==NULL)
{
fp=fopen(
"贪吃蛇最高记录.txt",
"w+");
fwrite(&max_grade,
sizeof(
int),
1,fp);
}
fseek(fp,
0,SEEK_SET);
fread(&max_grade,
sizeof(
int),
1,fp);
fseek(fp,
0,SEEK_SET);
if(max_grade<grade)
{
fwrite(&grade,
sizeof(
int),
1,fp);
}
}
void gotoxy(
int x,
int y)
{
COORD coord;
coord.X=y;
coord.Y=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
void hidden_cursor()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=
0;
SetConsoleCursorInfo(hOut,&cci);
}
int color(
int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}