//-----C-FREE上测试通过-----//
//-----可能有BUG,欢迎指出------//
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
struct COOR
{
int x;
int y;
};
struct SNAKE
{
int length;
struct COOR body[500];
char dir;
};
struct SNAKE snake = {3, {6, 0}, 77};
struct FOOD
{
int x;
int y;
};
typedef enum {false = 0, true = !false} bool;
#define B_DU 58
#define B_LR 26
struct FOOD food;
char KEY=77; //键盘按键
bool flag_isgameover=false;
bool flag_iseat=false;
int foodcount=0;
int score=0;
int delaytime=700;
int gamelevel=1;
/*************设置光标位置*****************/
void gopos(int x,int y)
{
COORD pos; //COORD系统已定义的一个关于光标的结构体
HANDLE han; //新建一个句柄
pos.X=x; //为结构体赋初值
pos.Y=y;
han=GetStdHandle(STD_OUTPUT_HANDLE); //将获得的输入输出状态的函数 句柄赋给已经新建的那个
SetConsoleCursorPosition(han,pos); //windows api 设置光标位置函数
}
void creatmap()
{
int x,y;
for(x=0;x<=B_DU;x+=2)
{
gopos(x,0);
printf("■");
gopos(x,26);
printf("■");
}
for(y=0;y<=B_LR;y++)
{
gopos(0,y);
printf("■");
gopos(58,y);
printf("■");
}
}
void initconlose()
{
HANDLE han; //新建一个句柄
srand((long)time(NULL)); //使用time函数做随机数种子 【time:函数返回当前时
//间,如果发生错误返回零。如果给定参数time ,那么
//当前时间存储到参数time中。 】
system ("mode con: cols=60 lines=29");//显示模式
system ("title 贪吃蛇");
han=GetStdHandle(STD_OUTPUT_HANDLE); //将获得的输入输出状态的函数 句柄赋给已经新建的那个
SetConsoleTextAttribute(han, 0xe); //设置控制台显示颜色
}
void initsnake() //初始化蛇身
{
int i;
for(i=0;i<snake.length;i++)
{
snake.body[i].x=6-i*2;
snake.body[i].y=1;
gopos(snake.body[i].x,snake.body[i].y);
printf("■");
}
}
void setlevel()
{
if(foodcount==15)
{
foodcount=0;
gamelevel++;
delaytime-=50;
}
gopos(0,27);
printf("score=%d",score);
gopos(10,27);
printf("等级=%d",gamelevel);
}
void initfood()
{
int i;
while (1)
{
food.x = (rand() % 28 + 1) * 2;
food.y = rand() % 24 +1;
for(i=0;i<snake.length;i++)
{
if(food.x==snake.body[i].x&&food.y==snake.body[i].y)
break;
}
if(i==snake.length)
break;
}
gopos(food.x,food.y);
printf("■");
flag_iseat=false;
setlevel();
}
int jbitself(int x,int y) //判断蛇是否咬到自己
{
int i;
for(i=1;i<snake.length;i++)
{
if(x==snake.body[i].x&&y==snake.body[i].y)
return 1; //咬到了自己
}
return 0;
}
int jgameover()
{
int x=snake.body[0].x;
int y=snake.body[0].y;
if(jbitself(x,y)||x==0||x==B_DU||y==0||y==B_LR)
return 1; //游戏结束
else
return 0; //没有结束
}
void move(char key)
{
int i;
int s_x=snake.body[0].x;
int s_y=snake.body[0].y;
switch(key)
{
case 72:s_y--;break;
case 75:s_x-=2;break;
case 77:s_x+=2;break;
case 80:s_y++;break;
default:break;
}
if(jgameover())
{
flag_isgameover=true;
}
else
{
if(s_y==food.y&&s_x==food.x)
{
score=score+gamelevel;
foodcount++;
snake.length++;
flag_iseat=true;
}
else
{
gopos(snake.body[snake.length-1].x,snake.body[snake.length-1].y);
printf(" ");
}
gopos(s_x,s_y);
printf("■");
for(i=snake.length-1;i>0;i--)
{
snake.body[i]=snake.body[i-1];
}
snake.body[0].x=s_x;
snake.body[0].y=s_y;
KEY=key;
}
}
int play()
{
char key1=0,key2=0;
while(key1!=27&&flag_isgameover==false)
{
Sleep(delaytime);
if(kbhit())
{
key1=getch();
if(key1<=0)
{
key2=getch();
}
if (key2 == 72 || key2 == 75 || key2 == 77 || key2 == 80)//说明是方向键
{
if (key2 != KEY && key2 + KEY != 152)//说明是使蛇转向的方向键
move(key2);
else
move(KEY);
}
else //暂停
{
gopos(10,10);
printf("游戏暂停中,请按回车键继续游戏!");
key1=getchar();
gopos(10,10);
printf(" ");
}
}
else
move(KEY);
if(flag_iseat==true)
initfood();
if(flag_isgameover==true)
{
gopos(10,10);
printf("游戏结束,请按任意键结束程序!");
key1=getch();
break;
}
}
return;
}
int main()
{
initconlose();
creatmap();
initsnake();
initfood();
play();
return 0;
}