#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#define WHITE "\033[37m"
#define CYAN "\033[36m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define PURPLE "\033[35m"
#define Y 20
#define X 18
//地图
int map[Y][X];
//蛇的长度
int length,Time,type=0,
//蛇的速度
speed=260,
d=0,last=0,food=0;
//常量包括地图打印用到的空地、墙、食物
int WALL=-2,FOOD=-1,VOID=0;
char color=3,big_c,x,y,
//文件名
file_name[]="/storage/emulated/0/AnyegameRecord.txt";
clock_t start[10]={
0}
,end;
//计时器,当过了ms个毫秒的时间就返回真
int Timer(clock_t ms,int id)
{
end=clock();
if(end-start[id]>=ms*1000)
{
start[id]=end;
return 1;
}
return 0;
}
//改变光标位置
void Gb( int x, int y)
{
printf("\033[%d;%dH",y,x);
}
//清屏
void cls()
{
printf("\033[2J");
fflush(stdout);
}
//打印游戏画面
void print_map()
{
Gb(1,1);
printf(WHITE"时间:%d秒 长度:%d格 最高记录%d\n",Time,length,big_c);
for(int y=0;y<Y;++y)
{
for(int x=0;x<X;++x)
{
if(map[y][x]==VOID)
printf("\033[40m ");
else if(map[y][x]==WALL)
printf("\033[47m \033[40m");
else if(map[y][x]==FOOD)
printf(PURPLE"%s",type?"\033[45m \033[40m":"💎 ");
else if(map[y][x]==length)
printf("\033[32m口");
else
printf("\033[3%dm〇",color);
}
printf("\n");
}
fflush(stdout);
}
//将最高记录保存至文件
void file_save_record()
{
FILE *fp=fopen(file_name,"w");
fprintf(fp,"%d",length);
fclose(fp);
}
//将最高记录从文件中读取并赋值给big_c
void file_read_record()
{
FILE *fp=fopen(file_name,"r");
if(NULL==fp)
printf("文件不存在\n");
fscanf(fp,"%d",&big_c);
fclose(fp);
}
//随机生成食物
void creat_food()
{
srand(time(NULL));
int x=1,y=1,I=1,J=1,flag,sub=2,n=0;
if(type)
I=3,J=3,food=9,sub=5;
do{
flag=0,n++;
if (n>1000&&type)
I=2,J=2,food=4;
y=rand()%(Y-sub)+1;
x=rand()%(X-sub)+1;
for( int i=0;i<I;i++)
for( int j=0;j<J;j++)
if(map[y+i][x+j]!=VOID)
flag=1;
}
while(flag);
for( int i=0;i<I;i++)
for( int j=0;j<J;j++)
map[y+i][x+j]=FOOD;
}
//将蛇的身体消减,直到等于0就会变成空地
void minus()
{
for(int y=0;y<Y;++y)
for(int x=0;x<X;++x)
if(map[y][x]>VOID)
map[y][x]-=1;
}
/*
蛇的移动 d为方向,t为新坐标下的数值。蛇头的值最大,等于自身长度length,
蛇身从头往尾依次少1,将要达到的坐标点赋值为蛇头的值,y+d/2和x+d%2是
根据方向d确定蛇头新的位置,只有2和-2除以2才是非0值,1和-1模2才有余数
*/
int move()
{
int t;
x+=d%2,y+=d/2;
t=map[y][x];
if(t==VOID)
{
minus();
map[y][x]=length;
}
else if(t==FOOD)
{
length++,food--;
map[y][x]=length;
if(food==0||!type)
creat_food();
if(length>50)
{
cls();
Gb(14,13);
printf(GREEN"恭喜通关!!!\n"WHITE);
exit(0);
}
if(length>big_c)
{
file_save_record(file_name);
big_c=length;
}
}
else if(t==WALL||t>VOID)
{
if(!type||t>VOID)
return 1;
minus();
y-=d/2*18,x-=d%2*16;
map[y][x]=length;
}
last =d;
return 0;
}
//用户输入方向ch,如果不等于之前的相反的方向就赋值
void input()
{
int arr[8]={'2','4','6','8',2,1,-1,-2} ;
int ch=getch();
for(int i=0;i<4;i++)
if(ch==arr[i]&&last!=arr[i+4])
d=-arr[i+4];
if(ch=='5')
while(getch()!='5');
}
//速度更改
void spe()
{
int arr[5]={
1400,900,300,150,90}
,str
;
printf(GREEN"1.极慢 2.慢 3.适中 4.快\n5.极快\n"WHITE);
printf(PURPLE"[输入对应的序号,其他为退出]\n"WHITE);
str=getch()-49;
if(str>-1&&str<5)
{
speed=arr[str];
printf(GREEN"更改成功!"WHITE);
fflush(stdout);
usleep(500000);
}
}
void col()
{
printf(" \033[31m1.红色\033[32m 2.绿色\033[33m 3.黄色 \033[34m 4.青色\n");
printf("\t \033[35m5.紫色\033[36m 6.蓝色\033[37m 7.白色\n");
printf(PURPLE"[输入对应的序号,其他为退出]:"WHITE);
color=getch()-48;
if(color>0&&color<8)
{
printf(GREEN"\n更改成功!"WHITE);
fflush(stdout);
usleep(500000);
}
}
void mod()
{
printf(CYAN"撞墙不会死,有地图边缘传送功能,并且生成大量食物。\n按回车设定为此模式,其他退出:");
if(getch()=='\n')
{
printf("设定成功");
fflush(stdout);
type=1;
sleep(1);
}
}
//菜单界面与功能实现
void menu()
{
void(* func[3])() ={
spe,col,mod}
;
while(1){
cls();
Gb(15,9);
printf(CYAN"贪吃蛇\n"WHITE);
Gb(6,10);
printf("\033[34m方向按钮为2468,5为暂停\n");
Gb(12,11);
printf(GREEN"1.开始游戏\n");
Gb(12,12);
printf(GREEN"2.速度更改\n");
Gb(12,13);
printf(GREEN"3.颜色更改\n");
Gb(12,14);
printf(GREEN"4.超爽模式\n");
Gb(10,15);
printf(PURPLE"[输入对应的序号]\n");
char ch=getch()-48;
cls();
if(ch==1)
break;
else if(ch>0&&ch<5)
func[ch-2]();
}
}
//初始化游戏属性和地图
void init_game()
{
for(int y=0;y<Y;++y)
{
for(int x=0;x<X;++x)
{
if(y>0&&y<Y-1&&x>0&&x<X-1)
map[y][x]=VOID;
else
map[y][x]=WALL;
}
}
length=3,Time=0;
//蛇的初始位置
map[y=Y/2][x=X/2]=length;
//菜单
menu();
// 部分机型不可用file_read_record();
creat_food();
print_map();
input();
}
//失败时展示的内容
void fail()
{
Gb(14,10);
printf(RED"游戏失败!\n"WHITE);
Gb(4,12);
printf(WHITE"是否继续?按回车退出,其他继续\n");
fflush(stdout);
sleep(2);
if(getch()!='\n')
{
init_game();
return;
}
else
{
cls();
Gb(13,12);
printf(CYAN"感谢您的游玩!");
exit(0);
}
}
int main()
{
//隐藏光标
printf("\033[?25l\033[1m");
init_game();
while(1)
//主程序反复运行,判断键盘有没有敲击
{
Time+=Timer(1000,0);
//如果过了满一秒,状态栏的时间加1秒
if(kbhit())
input();
if(Timer(speed,1))
//如果过了一个以speed毫秒为刷新屏幕的单位时间
{
//调用移动函数并且判断蛇是否撞墙或咬到自己
if(move())
fail();
print_map();
//刷新状态栏并且显示游戏场景内容
}
}
return 0;
}
06-18
2768
01-23
07-23
07-23
05-28