程序设计实践课作业——利用easyx库实现贪吃蛇

本贪吃蛇最高支持双人+电脑对战,电脑实际上就是一个普通的最短路(顺便草草判断了割点防止将自己堵死(但还是会被堵死))
这个程序用了easyx库,小熊猫dev可以直接编译运行,如果懒得下载的话,文章末尾还有一个没有图形库的版本。

#include<bits/stdc++.h>
#include<graphics.h>
#include<conio.h>
#include<windows.h>
#define Graph(x)for(int i=lastG[x],y=edgeG[i].ver;i;i=edgeG[i].next,y=edgeG[i].ver)
#define Tree(x)for(int i=lastT[x],y=edgeT[i].ver;i;i=edgeT[i].next,y=edgeT[i].ver)
using namespace std;
const int WIDTH=1200;
const int HEIGHT=800;
const char _UP_[4]={0,72,'W',72};
const char _DOWN_[4]={0,80,'S',80};
const char _LEFT_[4]={0,75,'A',75};
const char _RIGHT_[4]={0,77,'D',77};
const int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};
int tou[10],wei[10],posx[10][2010],posy[10][2010],PPPPP[10];
int playercnt=1,chuanqiang,zhangaiwu,zawcnt=3,AI,ZANTING,ZANTINGUP;
int zaw[2010];
bool vis[50][50];
int DIR[10],len[10],SCORE[10],FDX[10],FDY[10],FDEXP[10];
int nextTIME[10],JSTIME[10],TIME[10]={0,CLOCKS_PER_SEC/2,CLOCKS_PER_SEC*2/5,CLOCKS_PER_SEC*3/10,CLOCKS_PER_SEC/5,CLOCKS_PER_SEC/10,CLOCKS_PER_SEC/20},LEVEL;
int _EXP[10]={0,5,15,35,60,100,99999};
int phbtot=0,phbrk[1010];
int dis[42][42],que[2010],TOU,WEI,sihuo[210];
int dis2[42][42],que2[2010],TOU2,WEI2;
pair<int,int>phb[1010];
int FANG,dfn[1900],low[1900],sta[1900],dfs_clock,statop,lastG[1900],lastT[3700],numG,numT,GNAF;
struct EDGE
{int ver,next;}edgeG[3700],edgeT[7300];
mt19937 mt(time(0));
ExMessage mes;
struct DIRSYZ
{int d[4];};
void updphb(int val1,int val2)
{
	phb[++phbtot]=make_pair(-val1,-val2);
	sort(phb+1,phb+1+phbtot);
	int temp=0;
	for(int i=1;i<=phbtot;i++){
		if(phb[i]!=phb[i-1])
			temp++;
		phbrk[i]=temp;
	}
	phbtot=min(phbtot,10);
}
void updfs(int val1,int val2,int val3,int val4)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	sprintf(str,"%-10d",val1),outtextxy(925,10,str);
	if(playercnt>=1)
		sprintf(str,"%-10d",val2),outtextxy(925,1*40+10,str);
	if(playercnt>=2)
		sprintf(str,"%-10d",val3),outtextxy(925,2*40+10,str);
	if(playercnt>=3)
		sprintf(str,"%-10d",val4),outtextxy(925,3*40+10,str);
}
void updcd(int val1,int val2,int val3)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	if(playercnt>=1)
		sprintf(str,"%-10d",val1),outtextxy(925,1*40+30,str);
	if(playercnt>=2)
		sprintf(str,"%-10d",val2),outtextxy(925,2*40+30,str);
	if(playercnt>=3)
		sprintf(str,"%-10d",val3),outtextxy(925,3*40+30,str);
}
void updsd(int val)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	sprintf(str,"%-10d",val),outtextxy(925,30,str);
}
void ptZFX(int x,int y)
{
	x--;y--;
	solidrectangle(20*x+10-8,20*y+10+8,20*x+10+8,20*y+10-8);
}
void ptX(int x,int y)
{
	x--;y--;
	line(20*x+10-6,20*y+10-6,20*x+10+6,20*y+10+6);
	line(20*x+10-6,20*y+10+6,20*x+10+6,20*y+10-6);
}
void ptYUAN(int x,int y)
{
	x--;y--;
	solidcircle(20*x+10,20*y+10,8);
}
bool cmpwjfs(int n1,int n2)
{
	return SCORE[n1]*10000+len[n1]>SCORE[n2]*10000+len[n2];
}
void SAVEPHB()
{
	ofstream fout;
	fout.open("C:\\tcsphb\\tcsphb.txt");
	for(int i=1;i<=phbtot;i++)
		fout<<-phb[i].first<<' '<<-phb[i].second<<'\n';
	fout.close();
}
void makefood(int iD)
{
	int x,y;
	FDX[iD]=FDY[iD]=-1;
	do{
		x=mt()%40+1;
		y=mt()%40+1;
	}while(vis[x][y]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	FDX[iD]=x;FDY[iD]=y;
	int temp=mt()%5;
	if(temp==0){
		setfillcolor(RGB(255,215,0));
		if(playercnt==1)
			FDEXP[iD]=10;
		else FDEXP[iD]=5;
	}else if(temp==1){
		setfillcolor(RGB(0,255,255));
		FDEXP[iD]=0;
	}else{
		setfillcolor(RGB(255,255,255));
		FDEXP[iD]=1;
	}
	ptYUAN(x,y);
}
void makezaw()
{
	if(zaw[0]>500)return;
	int x,y;
	do{
		x=mt()%40+1;
		y=mt()%40+1;
	}while(vis[x][y]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	zaw[++zaw[0]]=x+y*1000;
	vis[x][y]=1;
	setlinecolor(RGB(128,128,128));
	setlinestyle(PS_SOLID|PS_ENDCAP_ROUND,3);
	ptX(x,y);
}
void init()
{
	initgraph(WIDTH,HEIGHT,EX_NOCLOSE|EX_NOMINIMIZE);
	HWND hWnd = GetHWnd();
	SetWindowText(hWnd, "贪吃蛇:新起点!");
	ifstream fin;
	fin.open("C:\\tcsphb\\tcsphb.txt");
	for(int i=1;i<=10;i++){
		int x,y;
		if(fin>>x>>y)
			updphb(x,y);
	}
	fin.close();
}
char calc2DIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	que[TOU=WEI=1]=posx[iD][(wei[iD]-1)%2000+1]*1000+posy[iD][(wei[iD]-1)%2000+1];
	dis[posx[iD][(wei[iD]-1)%2000+1]][posy[iD][(wei[iD]-1)%2000+1]]=0;
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY]||dis[X][Y]+1>=dis[XX][YY])
				continue;
			dis[XX][YY]=dis[X][Y]+1;
			que[++WEI]=XX*1000+YY;
		}
	}
	for(int j=WEI;j;j--){
		int X=que[j]/1000,Y=que[j]%1000;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY])
				continue;
			dis[X][Y]=max(dis[XX][YY],dis[X][Y]);
		}
	}
	int Max=0,FX=-1;
	int X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	for(int i=0;i<4;i++){
		int XX=X+dx[i],YY=Y+dy[i];
		if(chuanqiang){
			if(XX==0)XX=40;
			else if(XX==41)XX=1;
			if(YY==0)YY=40;
			else if(YY==41)YY=1;
		}
		if(vis[XX][YY]||dis[XX][YY]>200)continue;
		if(dis[XX][YY]>Max)
			Max=dis[YY][XX],FX=i;
	}
	if(FX==0)return _UP_[iD];
	if(FX==1)return _DOWN_[iD];
	if(FX==2)return _LEFT_[iD];
	if(FX==3)return _RIGHT_[iD];
	return 0;
}
void addG(int U,int V)
{edgeG[++numG]=(EDGE){V,lastG[U]};lastG[U]=numG;}
void addT(int U,int V)
{edgeT[++numT]=(EDGE){V,lastT[U]};lastT[U]=numT;}
void tarjan(int x)
{
	dfn[x]=low[x]=++dfs_clock;
	sta[++statop]=x;
	Graph(x)
	if(!dfn[y]){
		tarjan(y);
		low[x]=min(low[x],low[y]);
		if(dfn[x]<=low[y]){
			++FANG;
			for(;sta[statop]!=y;statop--){
				addT(FANG,sta[statop]);
				addT(sta[statop],FANG);
			}
			statop--;
			addT(y,FANG);addT(FANG,y);
			addT(x,FANG);addT(FANG,x);
		}
	}else low[x]=min(low[x],dfn[y]);
}
void dfsGNAF(int x,int F)
{
	Tree(x){
		if(y==F)continue;
		if(y==GNAF)GNAF=0;
		if(!GNAF)return;
		if(y>1690)
			dfsGNAF(y,x);
	}
}
bool checkFD(int iD,int iD2)
{
	memset(lastG,0,sizeof lastG);
	memset(lastT,0,sizeof lastT);
	memset(dfn,0,sizeof dfn);
	numG=numT=0;FANG=1690;
	dfs_clock=statop=0;
	for(int Y=1;Y<=40;Y++)
	for(int X=1;X<=40;X++){
		if(vis[X][Y])continue;
		for(int i=0;i<4;i+=2){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY])
				continue;
			addG(X*41+Y,XX*41+YY);
			addG(XX*41+YY,X*41+Y);
		}
	}
	for(int Y=1;Y<=40;Y++)
	for(int X=1;X<=40;X++)
	if(!vis[X][Y]&&!dfn[X*41+Y])
		tarjan(X*41+Y);
	GNAF=iD2;
	dfsGNAF(FDX[iD]*41+FDY[iD],0);
	return !GNAF;
}
int calcDIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	TOU=1;WEI=0;
	for(int i=0;i<3;i++)
	if(checkFD(i,iD)){
		dis[FDX[i]][FDY[i]]=0;
		que[++WEI]=FDX[i]*1000+FDY[i];
	}
	if(!WEI){
		dis[FDX[0]][FDY[0]]=0;
		dis[FDX[1]][FDY[1]]=0;
		dis[FDX[2]][FDY[2]]=0;
		que[TOU=1]=FDX[0]*1000+FDY[0];
		que[2]=FDX[1]*1000+FDY[1];
		que[WEI=3]=FDX[2]*1000+FDY[2];
	}
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;#include<bits/stdc++.h>
#include<graphics.h>
#include<conio.h>
#include<windows.h>
#define Graph(x)for(int i=lastG[x],y=edgeG[i].ver;i;i=edgeG[i].next,y=edgeG[i].ver)
#define Tree(x)for(int i=lastT[x],y=edgeT[i].ver;i;i=edgeT[i].next,y=edgeT[i].ver)
using namespace std;
const int WIDTH=1200;
const int HEIGHT=800;
const char _UP_[4]={0,72,'W',72};
const char _DOWN_[4]={0,80,'S',80};
const char _LEFT_[4]={0,75,'A',75};
const char _RIGHT_[4]={0,77,'D',77};
const int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};
int tou[10],wei[10],posx[10][2010],posy[10][2010],PPPPP[10];
int playercnt=1,chuanqiang,zhangaiwu,zawcnt=3,AI,ZANTING,ZANTINGUP;
int zaw[2010];
bool vis[50][50];
int DIR[10],len[10],SCORE[10],FDX[10],FDY[10],FDEXP[10];
int nextTIME[10],JSTIME[10],TIME[10]={0,CLOCKS_PER_SEC/2,CLOCKS_PER_SEC*2/5,CLOCKS_PER_SEC*3/10,CLOCKS_PER_SEC/5,CLOCKS_PER_SEC/10,CLOCKS_PER_SEC/20},LEVEL;
int _EXP[10]={0,5,15,35,60,100,99999};
int phbtot=0,phbrk[1010];
int dis[42][42],que[2010],TOU,WEI,sihuo[210];
int dis2[42][42],que2[2010],TOU2,WEI2;
pair<int,int>phb[1010];
int FANG,dfn[1900],low[1900],sta[1900],dfs_clock,statop,lastG[1900],lastT[3700],numG,numT,GNAF;
struct EDGE
{int ver,next;}edgeG[3700],edgeT[7300];
mt19937 mt(time(0));
ExMessage mes;
struct DIRSYZ
{int d[4];};
void updphb(int val1,int val2)
{
	phb[++phbtot]=make_pair(-val1,-val2);
	sort(phb+1,phb+1+phbtot);
	int temp=0;
	for(int i=1;i<=phbtot;i++){
		if(phb[i]!=phb[i-1])
			temp++;
		phbrk[i]=temp;
	}
	phbtot=min(phbtot,10);
}
void updfs(int val1,int val2,int val3,int val4)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	sprintf(str,"%-10d",val1),outtextxy(925,10,str);
	if(playercnt>=1)
		sprintf(str,"%-10d",val2),outtextxy(925,1*40+10,str);
	if(playercnt>=2)
		sprintf(str,"%-10d",val3),outtextxy(925,2*40+10,str);
	if(playercnt>=3)
		sprintf(str,"%-10d",val4),outtextxy(925,3*40+10,str);
}
void updcd(int val1,int val2,int val3)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	if(playercnt>=1)
		sprintf(str,"%-10d",val1),outtextxy(925,1*40+30,str);
	if(playercnt>=2)
		sprintf(str,"%-10d",val2),outtextxy(925,2*40+30,str);
	if(playercnt>=3)
		sprintf(str,"%-10d",val3),outtextxy(925,3*40+30,str);
}
void updsd(int val)
{
	settextcolor(RGB(255,255,255));
	char str[20];
	sprintf(str,"%-10d",val),outtextxy(925,30,str);
}
void ptZFX(int x,int y)
{
	x--;y--;
	solidrectangle(20*x+10-8,20*y+10+8,20*x+10+8,20*y+10-8);
}
void ptX(int x,int y)
{
	x--;y--;
	line(20*x+10-6,20*y+10-6,20*x+10+6,20*y+10+6);
	line(20*x+10-6,20*y+10+6,20*x+10+6,20*y+10-6);
}
void ptYUAN(int x,int y)
{
	x--;y--;
	solidcircle(20*x+10,20*y+10,8);
}
bool cmpwjfs(int n1,int n2)
{
	return SCORE[n1]*10000+len[n1]>SCORE[n2]*10000+len[n2];
}
void SAVEPHB()
{
	ofstream fout;
	fout.open("C:\\tcsphb\\tcsphb.txt");
	for(int i=1;i<=phbtot;i++)
		fout<<-phb[i].first<<' '<<-phb[i].second<<'\n';
	fout.close();
}
void makefood(int iD)
{
	int x,y;
	FDX[iD]=FDY[iD]=-1;
	do{
		x=mt()%40+1;
		y=mt()%40+1;
	}while(vis[x][y]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	FDX[iD]=x;FDY[iD]=y;
	int temp=mt()%5;
	if(temp==0){
		setfillcolor(RGB(255,215,0));
		if(playercnt==1)
			FDEXP[iD]=10;
		else FDEXP[iD]=5;
	}else if(temp==1){
		setfillcolor(RGB(0,255,255));
		FDEXP[iD]=0;
	}else{
		setfillcolor(RGB(255,255,255));
		FDEXP[iD]=1;
	}
	ptYUAN(x,y);
}
void makezaw()
{
	if(zaw[0]>500)return;
	int x,y;
	do{
		x=mt()%40+1;
		y=mt()%40+1;
	}while(vis[x][y]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	zaw[++zaw[0]]=x+y*1000;
	vis[x][y]=1;
	setlinecolor(RGB(128,128,128));
	setlinestyle(PS_SOLID|PS_ENDCAP_ROUND,3);
	ptX(x,y);
}
void init()
{
	initgraph(WIDTH,HEIGHT,EX_NOCLOSE|EX_NOMINIMIZE);
	HWND hWnd = GetHWnd();
	SetWindowText(hWnd, "贪吃蛇:新起点!");
	ifstream fin;
	fin.open("C:\\tcsphb\\tcsphb.txt");
	for(int i=1;i<=10;i++){
		int x,y;
		if(fin>>x>>y)
			updphb(x,y);
	}
	fin.close();
}
char calc2DIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	que[TOU=WEI=1]=posx[iD][(wei[iD]-1)%2000+1]*1000+posy[iD][(wei[iD]-1)%2000+1];
	dis[posx[iD][(wei[iD]-1)%2000+1]][posy[iD][(wei[iD]-1)%2000+1]]=0;
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY]||dis[X][Y]+1>=dis[XX][YY])
				continue;
			dis[XX][YY]=dis[X][Y]+1;
			que[++WEI]=XX*1000+YY;
		}
	}
	for(int j=WEI;j;j--){
		int X=que[j]/1000,Y=que[j]%1000;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY])
				continue;
			dis[X][Y]=max(dis[XX][YY],dis[X][Y]);
		}
	}
	int Max=0,FX=-1;
	int X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	for(int i=0;i<4;i++){
		int XX=X+dx[i],YY=Y+dy[i];
		if(chuanqiang){
			if(XX==0)XX=40;
			else if(XX==41)XX=1;
			if(YY==0)YY=40;
			else if(YY==41)YY=1;
		}
		if(vis[XX][YY]||dis[XX][YY]>200)continue;
		if(dis[XX][YY]>Max)
			Max=dis[YY][XX],FX=i;
	}
	if(FX==0)return _UP_[iD];
	if(FX==1)return _DOWN_[iD];
	if(FX==2)return _LEFT_[iD];
	if(FX==3)return _RIGHT_[iD];
	return 0;
}
void addG(int U,int V)
{edgeG[++numG]=(EDGE){V,lastG[U]};lastG[U]=numG;}
void addT(int U,int V)
{edgeT[++numT]=(EDGE){V,lastT[U]};lastT[U]=numT;}
void tarjan(int x)
{
	dfn[x]=low[x]=++dfs_clock;
	sta[++statop]=x;
	Graph(x)
	if(!dfn[y]){
		tarjan(y);
		low[x]=min(low[x],low[y]);
		if(dfn[x]<=low[y]){
			++FANG;
			for(;sta[statop]!=y;statop--){
				addT(FANG,sta[statop]);
				addT(sta[statop],FANG);
			}
			statop--;
			addT(y,FANG);addT(FANG,y);
			addT(x,FANG);addT(FANG,x);
		}
	}else low[x]=min(low[x],dfn[y]);
}
void dfsGNAF(int x,int F)
{
	Tree(x){
		if(y==F)continue;
		if(y==GNAF)GNAF=0;
		if(!GNAF)return;
		if(y>1690)
			dfsGNAF(y,x);
	}
}
bool checkFD(int iD,int iD2)
{
	memset(lastG,0,sizeof lastG);
	memset(lastT,0,sizeof lastT);
	memset(dfn,0,sizeof dfn);
	numG=numT=0;FANG=1690;
	dfs_clock=statop=0;
	for(int Y=1;Y<=40;Y++)
	for(int X=1;X<=40;X++){
		if(vis[X][Y])continue;
		for(int i=0;i<4;i+=2){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY])
				continue;
			addG(X*41+Y,XX*41+YY);
			addG(XX*41+YY,X*41+Y);
		}
	}
	for(int Y=1;Y<=40;Y++)
	for(int X=1;X<=40;X++)
	if(!vis[X][Y]&&!dfn[X*41+Y])
		tarjan(X*41+Y);
	GNAF=iD2;
	dfsGNAF(FDX[iD]*41+FDY[iD],0);
	return !GNAF;
}
int calcDIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	TOU=1;WEI=0;
	for(int i=0;i<3;i++)
	if(checkFD(i,iD)){
		dis[FDX[i]][FDY[i]]=0;
		que[++WEI]=FDX[i]*1000+FDY[i];
	}
	if(!WEI){
		dis[FDX[0]][FDY[0]]=0;
		dis[FDX[1]][FDY[1]]=0;
		dis[FDX[2]][FDY[2]]=0;
		que[TOU=1]=FDX[0]*1000+FDY[0];
		que[2]=FDX[1]*1000+FDY[1];
		que[WEI=3]=FDX[2]*1000+FDY[2];
	}
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=40;
				else if(XX==41)XX=1;
				if(YY==0)YY=40;
				else if(YY==41)YY=1;
			}
			if(vis[XX][YY]||dis[X][Y]+1>=dis[XX][YY])
				continue;
			dis[XX][YY]=dis[X][Y]+1;
			que[++WEI]=XX*1000+YY;
		}
	}
	char TEMP[5]={0,0,0,0,0};
	int tot=0,Min=0x3f3f3f3f,X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	int XX,YY;
	for(int i=0;i<4;i++){
		XX=X+dx[i],YY=Y+dy[i];
		if(chuanqiang){
			if(XX==0)XX=40;
			else if(XX==41)XX=1;
			if(YY==0)YY=40;
			else if(YY==41)YY=1;
		}
		Min=min(Min,dis[XX][YY]);
	}
	XX=X+dx[0],YY=Y+dy[0];
	if(chuanqiang){
		if(XX==0)XX=40;
		else if(XX==41)XX=1;
		if(YY==0)YY=40;
		else if(YY==41)YY=1;
	}
	if(Min==dis[XX][YY]){
		sihuo[int(_UP_[iD])]=vis[XX][YY];
		TEMP[++tot]=_UP_[iD];
	}
	XX=X+dx[1],YY=Y+dy[1];
	if(chuanqiang){
		if(XX==0)XX=40;
		else if(XX==41)XX=1;
		if(YY==0)YY=40;
		else if(YY==41)YY=1;
	}
	if(Min==dis[XX][YY]){
		sihuo[int(_DOWN_[iD])]=vis[XX][YY];
		TEMP[++tot]=_DOWN_[iD];
	}
	XX=X+dx[2],YY=Y+dy[2];
	if(chuanqiang){
		if(XX==0)XX=40;
		else if(XX==41)XX=1;
		if(YY==0)YY=40;
		else if(YY==41)YY=1;
	}
	if(Min==dis[XX][YY]){
		sihuo[int(_LEFT_[iD])]=vis[XX][YY];
		TEMP[++tot]=_LEFT_[iD];
	}
	XX=X+dx[3],YY=Y+dy[3];
	if(chuanqiang){
		if(XX==0)XX=40;
		else if(XX==41)XX=1;
		if(YY==0)YY=40;
		else if(YY==41)YY=1;
	}
	if(Min==dis[XX][YY]){
		sihuo[int(_RIGHT_[iD])]=vis[XX][YY];
		TEMP[++tot]=_RIGHT_[iD];
	}
	if(Min<=200){
		random_shuffle(TEMP+1,TEMP+1+tot);
		for(int i=1;i<=tot;i++)
		if(!sihuo[int(TEMP[i])])
			return TEMP[i];
	}
	return calc2DIR(iD);
}
DIRSYZ getDIR()
{
	DIRSYZ temp;
	memset(temp.d,0,sizeof temp.d);
	if(AI&&!ZANTING)
		temp.d[playercnt]=calcDIR(playercnt);
	while(1){
		int clo=clock(),flag=0;
		for(int i=1;i<=playercnt;i++)
		if(clo>=nextTIME[i])flag=1;
		if(flag)break;
		if(peekmessage(&mes,EX_KEY)){
			if(mes.vkcode==VK_SPACE&&ZANTINGUP){temp.d[0]=32;break;}
			if(mes.vkcode==VK_SPACE&&mes.message==WM_KEYUP)
				ZANTINGUP=1;
			if(mes.vkcode==VK_ESCAPE&&mes.message==WM_KEYUP){temp.d[0]=27;break;}
			if((mes.vkcode==VK_UP||mes.vkcode==VK_DOWN||mes.vkcode==VK_LEFT||mes.vkcode==VK_RIGHT)&&!(AI&&playercnt==1)){
				if(mes.vkcode==VK_UP)temp.d[1]=72;
				if(mes.vkcode==VK_DOWN)temp.d[1]=80;
				if(mes.vkcode==VK_LEFT)temp.d[1]=75;
				if(mes.vkcode==VK_RIGHT)temp.d[1]=77;
			}
			if((mes.vkcode=='W'||mes.vkcode=='A'||mes.vkcode=='S'||mes.vkcode=='D')&&!(AI&&playercnt==2))
				temp.d[2]=mes.vkcode;
		}
	}
	return temp;
}
/*
if(mes.message==WM_KEYUP){flag=0;continue;}
if(mes.message==WM_KEYDOWN&&flag)continue;
*/
void initMAP()
{
	setfillcolor(RGB(255,255,255));
	solidrectangle(802,0,805,HEIGHT);
	settextcolor(RGB(255,255,255));
	outtextxy(830,10,"分数(总):");
	outtextxy(830,30,"间隔:");
	for(int i=1;i<=playercnt;i++){
		char str[20];
		if(i==1)settextcolor(RGB(255,0,0));
		if(i==2)settextcolor(RGB(0,255,0));
		if(i==3)settextcolor(RGB(0,0,255));
		sprintf(str,"分数(玩家%d):",i);
		outtextxy(830,i*40+10,str);
		sprintf(str,"长度(玩家%d):",i);
		outtextxy(830,i*40+30,str);
	}
	settextcolor(RGB(255,255,255));
	outtextxy(830,200,"按esc返回标题。");
	outtextxy(830,230,"按空格键暂停。");
	for(int i=1;i<=40;i++)
		vis[i][0]=vis[i][41]=vis[0][i]=vis[41][i]=1;
	for(int i=1;i<=zaw[0];i++){
		int x=zaw[i]%1000,y=zaw[i]/1000;
		vis[x][y]=0;
	}
	zaw[0]=0;
}
void initDATA()
{
	SCORE[0]=0;ZANTINGUP=1;
	for(int i=1;i<=playercnt;i++){
		len[i]=wei[i]=DIR[i]=3;
		PPPPP[i]=tou[i]=1;
		SCORE[i]=nextTIME[i]=JSTIME[i]=0;
	}
	PPPPP[1]=LEVEL=1;
	vis[posx[1][1]=18][posy[1][1]=17]=1;
	vis[posx[1][2]=19][posy[1][2]=17]=1;
	vis[posx[1][3]=20][posy[1][3]=17]=1;
	if(playercnt>=2){
		PPPPP[2]=1;
		vis[posx[2][1]=18][posy[2][1]=23]=1;
		vis[posx[2][2]=19][posy[2][2]=23]=1;
		vis[posx[2][3]=20][posy[2][3]=23]=1;
	}
	if(playercnt>=3){
		PPPPP[3]=1;
		vis[posx[3][1]=18][posy[3][1]=20]=1;
		vis[posx[3][2]=19][posy[3][2]=20]=1;
		vis[posx[3][3]=20][posy[3][3]=20]=1;
	}
	updfs(SCORE[0],SCORE[1],SCORE[2],SCORE[3]);
	updsd(TIME[LEVEL]);
	updcd(len[1],len[2],len[3]);
}
int MOVE(int iD)
{
	int X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	int XX=X+dx[DIR[iD]],YY=Y+dy[DIR[iD]];
	int XXX=posx[iD][(tou[iD]-1)%2000+1],YYY=posy[iD][(tou[iD]-1)%2000+1];
	if(chuanqiang){
		if(XX==0)XX=40;
		else if(XX==41)XX=1;
		if(YY==0)YY=40;
		else if(YY==41)YY=1;
	}
	if(vis[XX][YY]&&(XX!=XXX||YY!=YYY))
		return 0;
	vis[XXX][YYY]=0;
	wei[iD]++;
	posx[iD][(wei[iD]-1)%2000+1]=XX;
	posy[iD][(wei[iD]-1)%2000+1]=YY;
	if(iD==1)setfillcolor(RGB(255,0,0));
	if(iD==2)setfillcolor(RGB(0,255,0));
	if(iD==3)setfillcolor(RGB(0,0,255));
	ptZFX(XX,YY);
	vis[XX][YY]=1;
	setfillcolor(RGB(128,128,128));
	ptZFX(X,Y);
	int flag=0;
	for(int i=0;i<3;i++)
	if(FDX[i]==XX&&FDY[i]==YY){
		flag=i+1;
		vis[XXX][YYY]=1;
		SCORE[0]+=FDEXP[i]*(1/*+EGG*9*/);
		SCORE[iD]+=FDEXP[i]*(1/*+EGG*9*/);
		if(!FDEXP[i])
			JSTIME[iD]=clock()+5*CLOCKS_PER_SEC;
		updfs(SCORE[0],SCORE[1],SCORE[2],SCORE[3]);
		len[iD]++;
		updcd(len[1],len[2],len[3]);
		while(SCORE[0]>=_EXP[LEVEL])
			updsd(TIME[++LEVEL]);
		if(zhangaiwu)
			for(int j=1;j<=zawcnt;j++)
				makezaw();
	}
	if(flag)makefood(flag-1);
	else{
		if(XX!=XXX||YY!=YYY){
			setfillcolor(RGB(0,0,0));
			ptZFX(XXX,YYY);
		}
		tou[iD]++;
	}
	return 1;
}
void KILL(int iD)
{
	PPPPP[iD]=0;
	setfillcolor(RGB(0,0,0));
	setlinestyle(PS_SOLID|PS_ENDCAP_ROUND,3);
	for(int j=wei[iD];(j+1)!=tou[iD];j--){
		int i=(j-1)%2000+1;
		ptZFX(posx[iD][i],posy[iD][i]);
		if(j==wei[iD]){
			if(iD==1)setlinecolor(RGB(255,0,0));
			if(iD==2)setlinecolor(RGB(0,255,0));
			if(iD==3)setlinecolor(RGB(0,0,255));
		}else setlinecolor(RGB(128,128,128));
		ptX(posx[iD][i],posy[iD][i]);
	}
}
void GAME()
{
	cleardevice();
	initMAP();
	initDATA();
	for(int k=1;k<=playercnt;k++)
	for(int j=wei[k];(j+1)!=tou[k];j--){
		int i=(j-1)%1000+1;
		if(j==wei[k]){
			if(k==1)setfillcolor(RGB(255,0,0));
			if(k==2)setfillcolor(RGB(0,255,0));
			if(k==3)setfillcolor(RGB(0,0,255));
		}else setfillcolor(RGB(128,128,128));
		ptZFX(posx[k][i],posy[k][i]);
	}
	int temp=(clock()/CLOCKS_PER_SEC+1)*CLOCKS_PER_SEC;
	while(clock()<=temp);
	int clo=clock();
	for(int i=1;i<=playercnt;i++)
		nextTIME[i]=clo+TIME[LEVEL]/(1+2*(clo<=JSTIME[i]));
	makefood(0);
	makefood(1);
	makefood(2);
	ZANTING=0;
	bool P[4]={0,1,playercnt>=2,playercnt>=3};
	int ztTIME=0;
	do{
		DIRSYZ FX=getDIR();
		clo=clock();
		int Id[5]={0,0,0,0,0};
		if(!ZANTING){
			for(int i=1;i<=playercnt;i++)
			if(clo>=nextTIME[i]&&P[i])
				Id[++Id[0]]=i;
			random_shuffle(Id+1,Id+1+Id[0]);
			for(int i=1;i<=Id[0];i++)
			if(FX.d[Id[i]]){
				if(FX.d[Id[i]]==_UP_[Id[i]])FX.d[Id[i]]=0;
				else if(FX.d[Id[i]]==_DOWN_[Id[i]])FX.d[Id[i]]=1;
				else if(FX.d[Id[i]]==_LEFT_[Id[i]])FX.d[Id[i]]=2;
				else if(FX.d[Id[i]]==_RIGHT_[Id[i]])FX.d[Id[i]]=3;
				if(DIR[Id[i]]!=(FX.d[Id[i]]^1)&&0<=FX.d[Id[i]]&&FX.d[Id[i]]<4)
					DIR[Id[i]]=FX.d[Id[i]];
			}
		}
		if(FX.d[0]==27)break;
		if(ZANTING){
			for(int i=1;i<=playercnt;i++){
				JSTIME[i]=clo+JSTIME[i]-ztTIME;
				nextTIME[i]=clo+nextTIME[i]-ztTIME;
			}
			ztTIME=clo;
		}
		if(FX.d[0]==32){
			ZANTING^=1;
			ztTIME=clo;
			ZANTINGUP=0;
		}
		if(!ZANTING){
			for(int i=1;i<=Id[0];i++)
			if(!MOVE(Id[i]))
				P[Id[i]]=0,KILL(Id[i]);
			for(int i=1;i<=playercnt;i++)
			if(clo>=nextTIME[i])
				nextTIME[i]=clo+TIME[LEVEL]/(1+2*(clo<=JSTIME[i]));
		}
	}while(P[1]|P[2]|P[3]);
	for(int i=1;i<=playercnt;i++){
		updphb(SCORE[i],len[i]);
		for(int j=tou[i];j<=wei[i];j++){
			int x=posx[i][(j-1)%2000+1],y=posy[i][(j-1)%2000+1];
			vis[x][y]=0;
		}
	}
	SAVEPHB();
	cleardevice();
	if(playercnt==1){
		if(SCORE[0]<1000){
			settextcolor(RGB(255,255,255));
			char str[40];
			sprintf(str,"很遗憾,你的分数为:%d",SCORE[0]);
			outtextxy(550,400,str);
		}else{
			settextcolor(RGB(255,215,0));
			outtextxy(550,400,"恭喜,你赢了。");
		}
	}else{
		int id[4];
		for(int i=1;i<=playercnt;i++)
			id[i]=i;
		sort(id+1,id+1+playercnt,cmpwjfs);
		bool flag=1;
		for(int i=2;i<=playercnt;i++)
		if(SCORE[id[i]]*10000+len[id[i]]!=SCORE[id[1]]*10000+len[id[1]])
			flag=0;
		if(flag){
			settextcolor(RGB(255,215,0));
			outtextxy(590,400,"平局。");
		}else{
			for(int i=1;i<=playercnt;i++)
			if(SCORE[id[i]]*10000+len[id[i]]==SCORE[id[1]]*10000+len[id[1]]){
				settextcolor(RGB(255,215,0));
				char str[40];
				sprintf(str,"恭喜玩家 %d 胜利。",id[i]);
				outtextxy(550,300+30*i,str);
			}
		}
	}
	settextcolor(RGB(255,255,255));
	outtextxy(550,430,"按esc返回标题。");
	while(1)
		if(peekmessage(&mes,EX_KEY))
			if(mes.vkcode==VK_ESCAPE)
				break;
	return;
}
void SET_AI()
{
	if(AI)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(820,220,"是");
	if(!AI)settextcolor(RGB(255,0,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(850,220,"否");
}
void SET_CQ()
{
	if(chuanqiang)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(820,100,"是");
	if(!chuanqiang)settextcolor(RGB(255,0,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(850,100,"否");
}
void SET_RS()
{
	if(playercnt==1)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(820,130,"1");
	if(playercnt==2)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(840,130,"2");
	if(playercnt==3)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(860,130,"3");
}
void SET_ZA()
{
	if(zhangaiwu)settextcolor(RGB(0,255,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(820,160,"是");
	if(!zhangaiwu)settextcolor(RGB(255,0,0));
	else settextcolor(RGB(128,128,128));
	outtextxy(850,160,"否");
}
void SET_ZS()
{
	for(int i=1;i<=10;i++){
		settextcolor(RGB(128,128,128));
		if(i==zawcnt)
			settextcolor(RGB(0,255,0));
		char str[5];
		sprintf(str,"%d",i);
		outtextxy(800+i*20,190,str);
	}
}
void SETTING()
{
	cleardevice();
	settextcolor(RGB(0,255,255));
	outtextxy(480,0,"按下选项前的数字,即可切换选项。");
	outtextxy(540,20,"按下esc返回标题。");

	settextcolor(RGB(255,255,255));
	outtextxy(200,100,"1.是否允许穿墙?");
	outtextxy(200,130,"2.玩家人数");
	outtextxy(200,160,"3.是否自动产生障碍物");
	outtextxy(200,190,"4.单次障碍物产生数目");
	outtextxy(200,220,"5.是否由电脑控制蛇(双人模式下将控制P2,三人P3)");

	SET_AI();
	SET_CQ();
	SET_RS();
	SET_ZA();
	SET_ZS();
	bool flag=1;
	while(1){
		if(peekmessage(&mes,EX_KEY)){
			if(mes.message==WM_KEYUP){flag=0;continue;}
			if(mes.message==WM_KEYDOWN&&flag)continue;
			if(mes.vkcode==VK_ESCAPE)break;
			else if(mes.vkcode==49||mes.vkcode==VK_NUMPAD1){
				chuanqiang^=1;
				SET_CQ();
			}else if(mes.vkcode==50||mes.vkcode==VK_NUMPAD2){
				playercnt++;
				playercnt=(playercnt-1)%3+1;
				SET_RS();
			}else if(mes.vkcode==51||mes.vkcode==VK_NUMPAD3){
				zhangaiwu^=1;
				SET_ZA();
			}else if(mes.vkcode==52||mes.vkcode==VK_NUMPAD4){
				zawcnt++;
				zawcnt=(zawcnt-1)%10+1;
				SET_ZS();
			}else if(mes.vkcode==53||mes.vkcode==VK_NUMPAD5){
				AI^=1;
				SET_AI();
			}
			flag=1;
		}
	}
}
void ABOUTANDHELP()
{
	cleardevice();
	settextcolor(RGB(0,255,255));
	outtextxy(550,20,"关于&帮助");
	settextcolor(RGB(255,255,255));
	outtextxy(430,60,"本游戏需要你操纵一条蛇吃食物同时躲避障碍,");
	outtextxy(300,90,"当然你不能咬到自己或者撞墙,单人模式下当你的分数达到1000分的时候你就赢了!");
	outtextxy(380,120,"如果是多人模式,当你们的蛇都死亡时,分数高的玩家获胜。");
	outtextxy(460,150,"本游戏的食物分为3种,一种是白色的");
	outtextxy(360,180,"分数为1、另一种是金色的分数为10(多人时为5)、还有一种为天蓝色的");
	outtextxy(320,210,"不加分数,但使你5秒内间隔变为33%。不管吃哪种食物,都会让你的长度加一。");
	outtextxy(420,240,"间隔的意思是两次移动的时间间隔,单位为毫秒。");
	outtextxy(400,270,"你们需要至少获得0,5,15,35,60,100分才能达到这些间隔。");
	settextcolor(RGB(0,255,255));
	outtextxy(540,330,"按任意键返回。");
	bool flag=1;
	while(1){
		if(peekmessage(&mes,EX_KEY)){
			if(mes.message==WM_KEYUP){flag=0;continue;}
			if(mes.message==WM_KEYDOWN&&flag)continue;
			break;
		}
	}
}
void PHB()
{
	cleardevice();
	settextcolor(RGB(0,255,255));
	outtextxy(580,0,"排行榜");
	for(int i=1;i<=phbtot;i++){
		settextcolor(RGB(128,128,128));
		if(phbrk[i]==1)settextcolor(RGB(255,215,0));
		if(phbrk[i]==2)settextcolor(RGB(255,255,255));
		if(phbrk[i]==3)settextcolor(RGB(120,101,24));
		char str[50];
		sprintf(str,"第 %4d 名",phbrk[i]);outtextxy(460,100+i*20,str);
		sprintf(str,"分数: %8d",-phb[i].first);outtextxy(560,100+i*20,str);
		sprintf(str,"长度: %4d",-phb[i].second);outtextxy(680,100+i*20,str);
	}
	settextcolor(RGB(255,255,255));
	outtextxy(550,600,"按任意键返回。");
	bool flag=1;
	while(1){
		if(peekmessage(&mes,EX_KEY)){
			if(mes.message==WM_KEYUP){flag=0;continue;}
			if(mes.message==WM_KEYDOWN&&flag)continue;
			break;
		}
	}
}
bool MENU()
{
	// tan chi she
	cleardevice();
	settextcolor(RGB(255,255,255));
	outtextxy(15, 45,"                                                                                                                                    000                                0000                                                    000");
	outtextxy(15, 60,"            000                                                                                                                  000                                0000                                                    000");
	outtextxy(15, 75,"            000                                                                                                                  000                                                                                            000");
	outtextxy(15, 90,"  00000000000000        00000000          00      00000                            00000000    000    00000          00000                                    00000000      000    00000                  000000");
	outtextxy(15,105,"  00000000000000      00000000000      000000000000                    0000000000    000000000000      00000000                          0000000000      000000000000          0000000000      ");
	outtextxy(15,120,"            000                                    000    0000          000                  000                    00000        0000              000                        000                      00000        000        000            000");
	outtextxy(15,135,"            000                                    000    000            000                000                      000              000              000                        000                      000              000    000                000");
	outtextxy(15,150,"            000                      0000000000    000            000                000                      000              000              000                          0000000            000              000    00000000000000");
	outtextxy(15,165,"            000                  000000000000    000            000                000                      000              000              000                              00000000      000              000    0000000000000");
	outtextxy(15,180,"            000                000              000    000            000                000                      000              000              000                                        0000    000              000    000");
	outtextxy(15,195,"            000                000            0000    000            000                0000                    000              000              000                                          000    000              000    0000");
	outtextxy(15,210,"            000000000    0000000000000    000            000                  00000000000    000              000    000000000000                00000000000      000              000      000000000000");
	outtextxy(15,225,"            000000000        000000    000    000            000                      000000000    000              000    000000000000                000000000          000              000          0000000000");

	outtextxy(560,540,"1.开始游戏");
	outtextxy(575,580,"2.设置");
	outtextxy(555,620,"3.关于&帮助");
	outtextxy(565,660,"4.排行榜");
	outtextxy(560,700,"5.退出游戏");
	outtextxy(0,780,"v1.5");

	while(1){
		if(peekmessage(&mes, EX_KEY)){
			// if(mes.message == WM_KEYDOWN)
			if(mes.message == WM_KEYUP)
				continue;
			if(mes.vkcode==49||mes.vkcode==97){
				GAME();
				return MENU();
			}else if(mes.vkcode==50||mes.vkcode==98){
				SETTING();
				return MENU();
			}else if(mes.vkcode==51||mes.vkcode==99){
				ABOUTANDHELP();
				return MENU();
			}else if(mes.vkcode==52||mes.vkcode==100){
				PHB();
				return MENU();
			}else if(mes.vkcode==53||mes.vkcode==101)
				return 0;
		}
	}
	return 1;
}
int main()
{
	init();
	while(MENU());
	closegraph();
}
/*
v1.5
修复:
修复了结算页面显示错误的bug。
v1.4
修复&修改:
将地图尺寸由60*30改为40*40
P2的颜色由蓝改为绿
P3的颜色由紫改为蓝
程序名称由“贪吃蛇:旅途的终点”改为“贪吃蛇:新起点!”
删去了原本的彩蛋
将存档位置由 D:\tcsphb.txt 改为 C:\tcsphb\tcsphb.txt
新功能:
利用easyx库,将原先的显示字符改为显示图形。
v1.3
修复&修改:
修复了吃完加速食物后立马退出游戏重开加速时间会保留的bug。
新功能:
现在主页面会显示版本号了。
v1.2
修复&修改:
修复了暂停失效的bug。
现在排行榜可以永久保存在D盘位置。
v1.1
修复&修改:
修复了暂停不会暂停加速时间的bug。
修复了仅剩AI且三个食物吃了都必死,AI什么也不吃的bug,即强制游戏结束。
新功能:
增强了AI,当AI被围住时,会尽力拖时间。
v1.0
修复&修改:
修复了食物颜色与作用不匹配的bug。
增强了AI,判断能否吃食物的能力增强。
v0.9
修复&修改:
重构代码,分别控制不同蛇的移动。
新功能:
添加了一种食物,使得蛇在五秒内加速。
v0.8
修复&修改:
重构代码,增强游戏稳定性与流畅度。
新功能:
增加了食物数目,场上同时会出现3个食物。
增强了AI,使得AI不会吃吃了就必死的食物。
v0.7
修复&修改:
多人模式下,金色食物分数降低为5分。
新功能:
添加三人模式。
主页增加排行榜功能。
v0.6
新功能:
添加AI功能。
v0.5
修复&修改:
双人模式下,分数和长度分别统计。
新功能:
添加障碍物选项,每吃一个食物可增加若干障碍物。
v0.4
修复&修改:
删去原本的设置选项。
新功能:
添加穿墙功能,可以在设置里选择。
添加双人模式,可以在设置里选择。
v0.3
新功能:
添加设置,可以更改操作方式。
v0.2
新功能:
添加暂停功能,同时可以在游戏中直接退出。
主页添加关于&帮助,可以查看游戏的信息。
添加彩蛋。
v0.1
新功能:
可以玩单人模式。
*/

这里还有一个没有用图形库,而是用控制台字符做的

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define Graph(x)for(int i=lastG[x],y=edgeG[i].ver;i;i=edgeG[i].next,y=edgeG[i].ver)
#define Tree(x)for(int i=lastT[x],y=edgeT[i].ver;i;i=edgeT[i].next,y=edgeT[i].ver)
using namespace std;
const int WIDTH=100;
const int HEIGHT=30;
const char UP[3]={72,'w',72};
const char DOWN[3]={80,'s',80};
const char LEFT[3]={75,'a',75};
const char RIGHT[3]={77,'d',77};
int tou[4],wei[4],posx[4][2010],posy[4][2010],PPPPP[4];
int ydtp=0,playercount=1,chuanqiang=0,zhangaiwu=0,zawcnt=3,AI=0,ZANTING;
int zaw[510];
int DIR[4],len[4],FDX[3],FDY[3],SCORE[4],FOODEXP[3];
int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};
int nextTIME[4],JSTIME[4],TIME[10]={0,CLOCKS_PER_SEC/2,CLOCKS_PER_SEC*2/5,CLOCKS_PER_SEC*3/10,CLOCKS_PER_SEC/5,CLOCKS_PER_SEC/10,CLOCKS_PER_SEC/20},LEVEL;
int _EXP[10]={0,5,15,35,60,100,99999};
int EGG=0,_EGG[1010];
int dis[32][62],que[2010],TOU,WEI,sihuo[200];
int dis2[32][62],que2[2010],TOU2,WEI2;
int phbtot=0,phbrk[1010];
pair<int,int>phb[1010];
int FANG,dfn[1900],low[1900],sta[1900],dfs_clock,statop,lastG[1900],lastT[3700],numG,numT,GNAF;
struct EDGE
{int ver,next;}edgeG[3700],edgeT[7300];
//UUDDLLRR BA
bool vis[32][62];
mt19937 mt(time(0));
void HIDE()
{
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cor_info = { 1, 0 };
	SetConsoleCursorInfo(hout, &cor_info);
}
void setcolor(int col,int ld=1)
{
	if(col==0){
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
	}
	if(col==1){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
	}
	if(col==2){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
	}
	if(col==3){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE);
	}
	if(col==4){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE);
	}
	if(col==5){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE);
	}
	if(col==6){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN);
	}
	if(col==7){
		if(ld==1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
		else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
	}
}
void GotoXY(int x,int y){
	HANDLE hout;
	COORD cor;
	hout=GetStdHandle(STD_OUTPUT_HANDLE);
	cor.X=x;
	cor.Y=y;
	SetConsoleCursorPosition(hout,cor);
}
int MENU()
{
	system("cls");
	setcolor(1,0);
	printf("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n");
	printf("0000000000000000000000000000000000000000000000  00000000000  000000000000000000 00000000000000000000\n");
	printf("000000  00000000000000000000000000000000000000  000000000000000000000000000000  00000000000000000000\n");
	printf("000        0000    00000      000000000    000      00000   00000000000    000      000000    000000\n");
	printf("000000  00000  0000  00  0000  0000000  000000  0000  00000  00000000  0000000   00  000  000  00000\n");
	printf("000000  00000 00 00  00  0000  000000  0000000  0000  00000  000000000   00000  000  000        0000\n");
	printf("000000  00000 0000  000  0000  00000   0000000  0000  0000  0000000000000  000  000  000  0000000000\n");
	printf("000000     000       00  0000  0000000     000  0000  000      000000  00  000  000  0000      00000\n");
	printf("00000000000000000000000000000000000000000000000000000000000000000000000  000000000000000000000000000\n");
	printf("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n");

	GotoXY(44,18);
	printf("1.开始游戏");
	GotoXY(46,20);
	printf("2.设置");
	GotoXY(44,22);
	printf("3.关于&帮助");
	GotoXY(45,24);
	printf("4.排行榜");
	GotoXY(44,26);
	printf("5.退出游戏");
	GotoXY(0,29);
	printf("v1.3");
	return 0;
}
void SAVEPHB()
{
	ofstream fout;
	fout.open("D:\\tcsphb.txt");
	for(int i=1;i<=phbtot;i++)
		fout<<-phb[i].first<<' '<<-phb[i].second<<'\n';
	fout.close();
}
void initMAP()
{
	cout<<'+';
	vis[0][0]=1;
	for(int i=1;i<59;i++)
		cout<<'-',vis[0][i]=1;
	cout<<'+';
	vis[0][59]=1;
	for(int i=1;i<29;i++){
		GotoXY(0,i);
		vis[i][0]=1;
		cout<<'|';
		GotoXY(59,i);
		vis[i][59]=1;
		cout<<'|';
	}
	GotoXY(0,29);
	cout<<'+';
	vis[29][0]=1;
	for(int i=1;i<59;i++)
		cout<<'-',vis[29][i]=1;
	cout<<'+';
	vis[29][59]=1;
	if(playercount==1){
		GotoXY(70,2);
		printf("分数: ");
		GotoXY(80,2);
		printf("%d",0);
	}else{
		GotoXY(70,2);
		printf("玩家1分数: ");
		GotoXY(80,2);
		printf("%d",0);
		GotoXY(70,4);
		printf("玩家2分数: ");
		GotoXY(80,4);
		printf("%d",0);
		if(playercount==3){
			GotoXY(70,3);
			printf("玩家3分数: ");
			GotoXY(80,3);
			printf("%d",0);
		}
	}
	if(playercount==1){
		GotoXY(70,6);
		printf("长度: ");
		GotoXY(80,6);
		printf("%d",0);
	}else{
		GotoXY(70,6);
		printf("玩家1长度: ");
		GotoXY(80,6);
		printf("%d",0);
		GotoXY(70,8);
		printf("玩家2长度: ");
		GotoXY(80,8);
		printf("%d",0);
		if(playercount==3){
			GotoXY(70,7);
			printf("玩家3长度: ");
			GotoXY(80,7);
			printf("%d",0);
		}
	}
	GotoXY(70,10);
	printf("间隔: ");
	GotoXY(80,10);
	printf("%d",0);

	GotoXY(70,12);
	printf("按esc返回标题。");

	GotoXY(70,14);
	printf("按空格键暂停。");
}
void updfs(int val1,int val2,int val3,int val4)
{
	if(playercount==1){
		GotoXY(80,2);
		printf("%d",val1);
	}else{
		GotoXY(80,2);
		printf("%d",val2);
		GotoXY(80,4);
		printf("%d",val3);
		if(playercount==3){
			GotoXY(80,3);
			printf("%d",val4);
		}
	}
}
void updcd(int val1,int val2,int val3)
{
	if(playercount==1){
		GotoXY(80,6);
		printf("%d",val1);
	}else{
		GotoXY(80,6);
		printf("%d",val1);
		GotoXY(80,8);
		printf("%d",val2);
		if(playercount==3){
			GotoXY(80,7);
			printf("%d",val3);
		}
	}
}
void updsd(int val)
{
	GotoXY(80,10);
	printf("%3d",val);
}
void initDATA()
{
	len[1]=len[2]=len[3]=3;tou[1]=tou[2]=tou[3]=1;
	wei[1]=wei[2]=wei[3]=3;DIR[1]=DIR[2]=DIR[3]=3;
	LEVEL=1;SCORE[0]=SCORE[1]=SCORE[2]=SCORE[3]=0;
	PPPPP[1]=1;
	updfs(SCORE[0],SCORE[1],SCORE[2],SCORE[3]);
	updcd(len[1],len[2],len[3]);
	updsd(TIME[LEVEL]);
	JSTIME[1]=JSTIME[2]=JSTIME[3]=0;
	nextTIME[1]=nextTIME[2]=nextTIME[3]=0;
	vis[posy[1][1]=13][posx[1][1]=28]=1;
	vis[posy[1][2]=13][posx[1][2]=29]=1;
	vis[posy[1][3]=13][posx[1][3]=30]=1;
	if(playercount>=2){
		PPPPP[2]=1;
		vis[posy[2][1]=17][posx[2][1]=28]=1;
		vis[posy[2][2]=17][posx[2][2]=29]=1;
		vis[posy[2][3]=17][posx[2][3]=30]=1;
	}
	if(playercount>=3){
		PPPPP[3]=1;
		vis[posy[3][1]=15][posx[3][1]=28]=1;
		vis[posy[3][2]=15][posx[3][2]=29]=1;
		vis[posy[3][3]=15][posx[3][3]=30]=1;
	}
	for(int i=1;i<=zaw[0];i++){
		int x=zaw[i]%1000,y=zaw[i]/1000;
		vis[y][x]=0;
	}
	zaw[0]=0;
}
void makezaw()
{
	if(zaw[0]>500)return;
	int x,y;
	do{
		x=mt()%58+1;
		y=mt()%28+1;
	}while(vis[y][x]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	zaw[++zaw[0]]=x+y*1000;
	vis[y][x]=1;
	GotoXY(x,y);
	setcolor(0,0);
	printf("X");
}
void makefood(int iD)
{
	int x,y;
	FDX[iD]=FDY[iD]=-1;
	do{
		x=mt()%58+1;
		y=mt()%28+1;
	}while(vis[y][x]||(FDX[0]==x&&FDY[0]==y)||(FDX[1]==x&&FDY[1]==y)||(FDX[2]==x&&FDY[2]==y));
	FDX[iD]=x;FDY[iD]=y;
	GotoXY(x,y);
	int temp=mt()%5;
	if(temp==0){
		setcolor(6,1);
		if(playercount==1)
			FOODEXP[iD]=10;
		else FOODEXP[iD]=5;
	}else if(temp==1){
		setcolor(3,1);
		FOODEXP[iD]=0;
	}else{
		setcolor(2,1);
		FOODEXP[iD]=1;
	}
	printf("#");
}
char calc2DIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	que[TOU=WEI=1]=posx[iD][(wei[iD]-1)%2000+1]*1000+posy[iD][(wei[iD]-1)%2000+1];
	dis[posy[iD][(wei[iD]-1)%2000+1]][posx[iD][(wei[iD]-1)%2000+1]]=0;
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=58;
				else if(XX==59)XX=1;
				if(YY==0)YY=28;
				else if(YY==29)YY=1;
			}
			if(vis[YY][XX]||dis[Y][X]+1>=dis[YY][XX])
				continue;
			dis[YY][XX]=dis[Y][X]+1;
			que[++WEI]=XX*1000+YY;
		}
	}
	for(int j=WEI;j;j--){
		int X=que[j]/1000,Y=que[j]%1000;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=58;
				else if(XX==59)XX=1;
				if(YY==0)YY=28;
				else if(YY==29)YY=1;
			}
			if(vis[YY][XX])
				continue;
			dis[Y][X]=max(dis[YY][XX],dis[Y][X]);
		}
	}
	int Max=0,FX=-1;
	int X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	for(int i=0;i<4;i++){
		int XX=X+dx[i],YY=Y+dy[i];
		if(chuanqiang){
			if(XX==0)XX=58;
			else if(XX==59)XX=1;
			if(YY==0)YY=28;
			else if(YY==29)YY=1;
		}
		if(vis[YY][XX]||dis[YY][XX]>200)continue;
		if(dis[YY][XX]>Max)
			Max=dis[YY][XX],FX=i;
	}
	if(FX==0)return UP[iD-1];
	if(FX==1)return DOWN[iD-1];
	if(FX==2)return LEFT[iD-1];
	if(FX==3)return RIGHT[iD-1];
	return 0;
}
void addG(int U,int V)
{edgeG[++numG]=(EDGE){V,lastG[U]};lastG[U]=numG;}
void addT(int U,int V)
{edgeT[++numT]=(EDGE){V,lastT[U]};lastT[U]=numT;}
void tarjan(int x)
{
	dfn[x]=low[x]=++dfs_clock;
	sta[++statop]=x;
	Graph(x)
	if(!dfn[y]){
		tarjan(y);
		low[x]=min(low[x],low[y]);
		if(dfn[x]<=low[y]){
			++FANG;
			for(;sta[statop]!=y;statop--){
				addT(FANG,sta[statop]);
				addT(sta[statop],FANG);
			}
			statop--;
			addT(y,FANG);addT(FANG,y);
			addT(x,FANG);addT(FANG,x);
		}
	}else low[x]=min(low[x],dfn[y]);
}
void dfsGNAF(int x,int F)
{
	Tree(x){
		if(y==F)continue;
		if(y==GNAF)GNAF=0;
		if(!GNAF)return;
		if(y>1800)
			dfsGNAF(y,x);
	}
}
bool checkFD(int iD,int iD2)
{
	memset(lastG,0,sizeof lastG);
	memset(lastT,0,sizeof lastT);
	memset(dfn,0,sizeof dfn);
	numG=numT=0;FANG=1800;
	dfs_clock=statop=0;
	for(int Y=1;Y<=28;Y++)
	for(int X=1;X<=58;X++){
		if(vis[Y][X])continue;
		for(int i=0;i<4;i+=2){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=58;
				else if(XX==59)XX=1;
				if(YY==0)YY=28;
				else if(YY==29)YY=1;
			}
			if(vis[YY][XX])
				continue;
			addG(X*30+Y,XX*30+YY);
			addG(XX*30+YY,X*30+Y);
		}
	}
	for(int Y=1;Y<=28;Y++)
	for(int X=1;X<=58;X++)
	if(!vis[Y][X]&&!dfn[X*30+Y])
		tarjan(X*30+Y);
	GNAF=iD2;
	dfsGNAF(FDX[iD]*30+FDY[iD],0);
	return !GNAF;
}
char calcDIR(int iD)
{
	memset(dis,0x3f,sizeof dis);
	TOU=1;WEI=0;
	for(int i=0;i<3;i++)
	if(checkFD(i,iD)){
		dis[FDY[i]][FDX[i]]=0;
		que[++WEI]=FDX[i]*1000+FDY[i];
	}
	if(!WEI){
		dis[FDY[0]][FDX[0]]=0;
		dis[FDY[1]][FDX[1]]=0;
		dis[FDY[2]][FDX[2]]=0;
		que[TOU=1]=FDX[0]*1000+FDY[0];
		que[2]=FDX[1]*1000+FDY[1];
		que[WEI=3]=FDX[2]*1000+FDY[2];
	}
	while(TOU<=WEI){
		int X=que[TOU]/1000,Y=que[TOU]%1000;
		TOU++;
		for(int i=0;i<4;i++){
			int XX=X+dx[i],YY=Y+dy[i];
			if(chuanqiang){
				if(XX==0)XX=58;
				else if(XX==59)XX=1;
				if(YY==0)YY=28;
				else if(YY==29)YY=1;
			}
			if(vis[YY][XX]||dis[Y][X]+1>=dis[YY][XX])
				continue;
			dis[YY][XX]=dis[Y][X]+1;
			que[++WEI]=XX*1000+YY;
		}
	}
	char TEMP[5]={0,0,0,0,0};
	int tot=0,Min=0x3f3f3f3f,X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	int XX,YY;
	for(int i=0;i<4;i++){
		XX=X+dx[i],YY=Y+dy[i];
		if(chuanqiang){
			if(XX==0)XX=58;
			else if(XX==59)XX=1;
			if(YY==0)YY=28;
			else if(YY==29)YY=1;
		}
		Min=min(Min,dis[YY][XX]);
	}
	XX=X+dx[0],YY=Y+dy[0];
	if(chuanqiang){
		if(XX==0)XX=58;
		else if(XX==59)XX=1;
		if(YY==0)YY=28;
		else if(YY==29)YY=1;
	}
	if(Min==dis[YY][XX]){
		sihuo[int(UP[iD-1])]=vis[YY][XX];
		TEMP[++tot]=UP[iD-1];
	}
	XX=X+dx[1],YY=Y+dy[1];
	if(chuanqiang){
		if(XX==0)XX=58;
		else if(XX==59)XX=1;
		if(YY==0)YY=28;
		else if(YY==29)YY=1;
	}
	if(Min==dis[YY][XX]){
		sihuo[int(DOWN[iD-1])]=vis[YY][XX];
		TEMP[++tot]=DOWN[iD-1];
	}
	XX=X+dx[2],YY=Y+dy[2];
	if(chuanqiang){
		if(XX==0)XX=58;
		else if(XX==59)XX=1;
		if(YY==0)YY=28;
		else if(YY==29)YY=1;
	}
	if(Min==dis[YY][XX]){
		sihuo[int(LEFT[iD-1])]=vis[YY][XX];
		TEMP[++tot]=LEFT[iD-1];
	}
	XX=X+dx[3],YY=Y+dy[3];
	if(chuanqiang){
		if(XX==0)XX=58;
		else if(XX==59)XX=1;
		if(YY==0)YY=28;
		else if(YY==29)YY=1;
	}
	if(Min==dis[YY][XX]){
		sihuo[int(RIGHT[iD-1])]=vis[YY][XX];
		TEMP[++tot]=RIGHT[iD-1];
	}
	if(Min<=200){
		random_shuffle(TEMP+1,TEMP+1+tot);
		for(int i=1;i<=tot;i++)
		if(!sihuo[int(TEMP[i])])
			return TEMP[i];
	}
	return calc2DIR(iD);
}
pair<char,pair<char,char>> getDIR()
{
	char ch1=0,ch2=0,ch3=0,ch=0;
	if(AI&&!ZANTING){
		if(playercount==1)
			ch1=calcDIR(1);
		else if(playercount==2)ch2=calcDIR(2);
		else ch3=calcDIR(3);
	}
	while(1){
		int clo=clock(),flag=0;
		for(int i=1;i<=playercount;i++)
		if(clo>=nextTIME[i])
			flag=1;
		if(flag)break;
		if(_kbhit())
			ch=_getch();
		if(ch==32||ch==27){
			ch1=ch2=ch3=ch;break;
		}
		if((ch==72||ch==80||ch==75||ch==77)&&!(AI&&playercount==1))
			ch1=ch;
		if((ch=='w'||ch=='a'||ch=='s'||ch=='d')&&!(AI&&playercount==2))
			ch2=ch;
	}
	return make_pair(ch1,make_pair(ch2,ch3));
}
bool MOVE(int iD)
{
	int X=posx[iD][(wei[iD]-1)%2000+1],Y=posy[iD][(wei[iD]-1)%2000+1];
	int XXX=posx[iD][(tou[iD]-1)%2000+1],YYY=posy[iD][(tou[iD]-1)%2000+1];
	vis[YYY][XXX]=0;
	int XX=X+dx[DIR[iD]],YY=Y+dy[DIR[iD]];
	if(chuanqiang){
		if(XX==0)XX=58;
		else if(XX==59)XX=1;
		if(YY==0)YY=28;
		else if(YY==29)YY=1;
	}
	if(vis[YY][XX])return 0;
	if(!EGG||playercount==2)setcolor(0,0);
	else{
		int temp=mt()%5+3;
		setcolor(temp,0);
	}
	GotoXY(X,Y);
	cout<<'O';
	if(playercount==1)
		setcolor(1,1);
	else if(iD==1)setcolor(7,0);
	else if(iD==2)setcolor(4,0);
	else setcolor(5,1);
	GotoXY(XX,YY);
	wei[iD]++;
	posx[iD][(wei[iD]-1)%2000+1]=XX;
	posy[iD][(wei[iD]-1)%2000+1]=YY;
	vis[YY][XX]=1;
	cout<<'O';
	setcolor(1,0);
	int flag=0;
	for(int i=0;i<3;i++)
	if(FDX[i]==XX&&FDY[i]==YY){
		flag=i+1;
		vis[YYY][XXX]=1;
		SCORE[0]+=FOODEXP[i]*(1+EGG*9);
		SCORE[iD]+=FOODEXP[i]*(1+EGG*9);
		if(!FOODEXP[i])
			JSTIME[iD]=clock()+5*CLOCKS_PER_SEC;
		updfs(SCORE[0],SCORE[1],SCORE[2],SCORE[3]);
		len[iD]++;
		updcd(len[1],len[2],len[3]);
		while(SCORE[0]>=_EXP[LEVEL])
			updsd(TIME[++LEVEL]);
		if(zhangaiwu)
			for(int j=1;j<=zawcnt;j++)
				makezaw();
	}
	if(flag)makefood(flag-1);
	else{
		if(XX!=XXX||YY!=YYY){
			GotoXY(XXX,YYY);
			cout<<' ';
		}
		tou[iD]++;
	}
	return 1;
}
void updphb(int val1,int val2)
{
	phb[++phbtot]=make_pair(-val1,-val2);
	sort(phb+1,phb+1+phbtot);
	int temp=0;
	for(int i=1;i<=phbtot;i++){
		if(phb[i]!=phb[i-1])
			temp++;
		phbrk[i]=temp;
	}
	phbtot=min(phbtot,10);
}
void KILL(int iD)
{
	PPPPP[iD]=0;
	for(int j=wei[iD];(j+1)!=tou[iD];j--){
		int i=(j-1)%2000+1;
		if(j==wei[iD]){
			if(iD==1)
				setcolor(7,0);
			else if(iD==2)setcolor(4,0);
			else setcolor(5,1);
		}else setcolor(0,0);
		GotoXY(posx[iD][i],posy[iD][i]);
		printf("X");
	}
}
bool cmpwjfs(int n1,int n2)
{
	return SCORE[n1]*10000+len[n1]>SCORE[n2]*10000+len[n2];
}
void GAME()
{
	system("cls");
	initMAP();
	initDATA();
	for(int k=1;k<=playercount;k++)
	for(int j=wei[k];(j+1)!=tou[k];j--){
		int i=(j-1)%2000+1;
		if(j==wei[k]){
			if(playercount==1)
				setcolor(1,1);
			else if(k==1)setcolor(7,0);
			else if(k==2)setcolor(4,0);
			else if(k==3)setcolor(5,1);
		}else if(!EGG)setcolor(0,0);
		else{
			int temp=mt()%5+3;
			setcolor(temp,0);
		}
		GotoXY(posx[k][i],posy[k][i]);
		printf("O");
	}
	int temp=(clock()/CLOCKS_PER_SEC+1)*CLOCKS_PER_SEC;
	while(clock()<=temp);
	int clo=clock();
	for(int i=1;i<=playercount;i++)
		nextTIME[i]=clo+TIME[LEVEL]/(1+2*(clo<=JSTIME[i]));
	makefood(0);
	makefood(1);
	makefood(2);
	ZANTING=0;
	bool P[4]={0,1,playercount>=2,playercount>=3};
	int LASTFX[4]={0,0,0,0},ztTIME;
	do{
		HIDE();
		pair<char,pair<char,char> >FFXX=getDIR();
		char FX[4]={0,FFXX.first,FFXX.second.first,FFXX.second.second};
		if(!FX[1])FX[1]=LASTFX[1];
		if(!FX[2])FX[2]=LASTFX[2];
		if(!FX[3])FX[3]=LASTFX[3];
		if(FX[1]!=32)LASTFX[1]=FX[1];
		if(FX[2]!=32)LASTFX[2]=FX[2];
		if(FX[3]!=32)LASTFX[3]=FX[3];
		clo=clock();
		int Id[4]={0,0,0,0};
		if(!ZANTING){
			for(int i=1;i<=playercount;i++)
			if(clo>=nextTIME[i]&&P[i])
				Id[++Id[0]]=i;
			random_shuffle(Id+1,Id+1+Id[0]);
			for(int i=1;i<=Id[0];i++){
				if(FX[Id[i]]){
					if(FX[Id[i]]==UP[(Id[i]+1)&1])FX[Id[i]]=0;
					else if(FX[Id[i]]==DOWN[(Id[i]+1)&1])FX[Id[i]]=1;
					else if(FX[Id[i]]==LEFT[(Id[i]+1)&1])FX[Id[i]]=2;
					else if(FX[Id[i]]==RIGHT[(Id[i]+1)&1])FX[Id[i]]=3;
					if(DIR[Id[i]]!=(FX[Id[i]]^1)&&0<=FX[Id[i]]&&FX[Id[i]]<4)
						DIR[Id[i]]=FX[Id[i]];
				}
			}
		}
		if(FX[1]==27)break;
		if(ZANTING){
			for(int i=1;i<=playercount;i++){
				JSTIME[i]=clo+JSTIME[i]-ztTIME;
				nextTIME[i]=clo+nextTIME[i]-ztTIME;
			}
			ztTIME=clo;
		}
		if(FX[1]==32){
			ZANTING^=1;
			ztTIME=clo;
		}
		if(!ZANTING){
			for(int i=1;i<=Id[0];i++)
			if(!MOVE(Id[i]))
				P[Id[i]]=0,KILL(Id[i]);
			for(int i=1;i<=playercount;i++)
			if(clo>=nextTIME[i])
				nextTIME[i]=clo+TIME[LEVEL]/(1+2*(clo<=JSTIME[i]));
		}
	}while(P[1]|P[2]|P[3]);
	for(int i=1;i<=playercount;i++){
		updphb(SCORE[i],len[i]);
		for(int j=tou[i];j<=wei[i];j++){
			int x=posx[i][(j-1)%2000+1],y=posy[i][(j-1)%2000+1];
			vis[y][x]=0;
		}
	}
	SAVEPHB();
	system("cls");
	if(playercount==1){
		if(SCORE[0]<1000){
			setcolor(1,0);
			GotoXY(40,14);
			printf("很遗憾,你的分数为:%d",SCORE[0]);
		}else{
			setcolor(6,0);
			GotoXY(43,14);
			printf("恭喜,你赢了。");
		}
	}else{
		int id[4];
		for(int i=1;i<=playercount;i++)
			id[i]=i;
		sort(id+1,id+1+playercount,cmpwjfs);
		if(SCORE[id[1]]*10000+len[id[1]]>SCORE[id[2]]*10000+len[id[2]]){
			setcolor(6,0);
			GotoXY(41,14);
			printf("恭喜玩家 %d 胜利。",id[1]);
		}else{
			setcolor(1,0);
			GotoXY(48,14);
			printf("平局");
		}
	}
	GotoXY(43,16);
	setcolor(1,0);
	printf("按esc返回标题。");
	while(1){
		if(kbhit()){
			if(_getch()==27)
				break;
		}
	}
	return;
}
void ABOUTANDHELP()
{
	system("cls");
	setcolor(1,0);
	GotoXY(29,2);
	printf("本游戏需要你操纵一条蛇吃食物同时躲避障碍,");
	GotoXY(18,4);
	printf("当然你不能咬到自己或者撞墙,当你的分数达到1000分的时候你就赢了!");
	GotoXY(23,6);
	printf("如果是多人模式,当你们的蛇都死亡时,分数高的玩家获胜。");
	GotoXY(11,8);
	printf("本游戏的食物分为3种,一种是绿色的");
	setcolor(2,1);
	printf("#");
	setcolor(1,0);
	printf("分数为1、另一种是金色的");
	setcolor(6,1);
	printf("#");
	setcolor(1,0);
	printf("分数为10(多人时为5)、");
	GotoXY(6,10);
	printf("还有一种为天蓝色的");
	setcolor(3,1);
	printf("#");
	setcolor(1,0);
	printf("不加分数,但使你5秒内间隔变为33%。不管吃哪种食物,都会让你的长度加一。");
	GotoXY(27,12);
	printf("间隔的意思是两次移动的时间间隔,单位为毫秒。");
	GotoXY(27,14);
	printf("间隔有5个挡位,分别为500,400,300,200,100,50。");
	GotoXY(25,16);
	printf("你需要至少获得0,5,15,35,60,100分才能达到这些间隔。");
	GotoXY(28,18);
	printf("本游戏开始界面按下");
	setcolor(7,1);
	printf("某些按键");
	setcolor(1,0);
	printf("可以触发彩蛋。");
	GotoXY(21,20);
	printf("彩蛋:单人模式下蛇的颜色会变得");
	setcolor(7,0);
	printf("五");
	setcolor(6,0);
	printf("颜");
	setcolor(4,0);
	printf("六");
	setcolor(2,0);
	printf("色");
	setcolor(1,0);
	printf(",并且得分乘10。");
	setcolor(1,0);
	GotoXY(43,25);
	printf("按任意键返回。");
	while(1){
		if(kbhit()){
			_getch();
			return;
		}
	}
}
void SET_CQ()
{
	GotoXY(80,7);
	if(chuanqiang){
		setcolor(2,1);
		printf("是");
		setcolor(1,0);
		printf("/否");
	}else{
		setcolor(1,0);
		printf("是/");
		setcolor(7,0);
		printf("否");
	}
	setcolor(1,0);
}
void SET_RS()
{
	GotoXY(80,9);
	if(playercount==1){
		setcolor(2,1);
		printf("1");
		setcolor(1,0);
		printf("/2/3");
	}else if(playercount==2){
		setcolor(1,0);
		printf("1/");
		setcolor(2,1);
		printf("2");
		setcolor(1,0);
		printf("/3");
	}else{
		setcolor(1,0);
		printf("1/2/");
		setcolor(2,1);
		printf("3");
	}
	setcolor(1,0);
}
void SET_ZA()
{
	GotoXY(80,11);
	if(zhangaiwu){
		setcolor(2,1);
		printf("是");
		setcolor(1,0);
		printf("/否");
	}else{
		setcolor(1,0);
		printf("是/");
		setcolor(7,0);
		printf("否");
	}
	setcolor(1,0);
}
void SET_ZS()
{
	GotoXY(73,13);
	setcolor(1,0);
	for(int i=1;i<=10;i++){
		if(i==zawcnt)
			setcolor(2,1);
		else setcolor(1,0);
		printf("%d",i);
		setcolor(1,0);
		if(i<10)
			printf("/");
	}
	setcolor(1,0);
}
void SET_AI()
{
	GotoXY(80,15);
	if(AI){
		setcolor(2,1);
		printf("是");
		setcolor(1,0);
		printf("/否");
	}else{
		setcolor(1,0);
		printf("是/");
		setcolor(7,0);
		printf("否");
	}
	setcolor(1,0);
}
void SETTING()
{
	system("cls");
	GotoXY(34,3);
	setcolor(3,1);
	printf("按下选项前的数字,即可切换选项。");
	GotoXY(40,5);
	printf("按下esc返回标题。");
	setcolor(1,0);
	GotoXY(10,7);
	printf("1.是否允许穿墙? ");
	SET_CQ();
	GotoXY(10,9);
	printf("2.玩家人数 ");
	SET_RS();
	GotoXY(10,11);
	printf("3.是否自动产生障碍物 ");
	SET_ZA();
	GotoXY(10,13);
	printf("4.单次障碍物产生数目 ");
	SET_ZS();
	GotoXY(10,15);
	printf("5.是否由电脑控制蛇(双人模式下将控制P2,三人P3) ");
	SET_AI();
	setcolor(1,0);
	char ch=0;
	while(1){
		if(kbhit()){
			ch=_getch();
			if(ch==27)break;
			else if(ch==49){
				chuanqiang^=1;
				SET_CQ();
			}else if(ch==50){
				playercount++;
				playercount=(playercount-1)%3+1;
				SET_RS();
			}else if(ch==51){
				zhangaiwu^=1;
				SET_ZA();
			}else if(ch==52){
				zawcnt++;
				zawcnt=(zawcnt-1)%10+1;
				SET_ZS();
			}else if(ch==53){
				AI^=1;
				SET_AI();
			}
		}
	}
	setcolor(1,0);
}
void PHB()
{
	system("cls");
	GotoXY(47,3);
	setcolor(3,1);
	printf("排行榜");
	for(int i=1;i<=phbtot;i++){
		setcolor(0,0);
		if(phbrk[i]==1)setcolor(6,1);
		if(phbrk[i]==2)setcolor(1,1);
		if(phbrk[i]==3)setcolor(6,0);
		GotoXY(33,4+i*2);
		printf("第 %2d 名  分数: %6d  长度: %4d",phbrk[i],-phb[i].first,-phb[i].second);
	}
	setcolor(1,0);
	GotoXY(43,26);
	printf("按任意键返回。");
	while(1){
		if(kbhit()){
			_getch();
			return;
		}
	}
}
void init()
{
	system("mode con cols=100 lines=30");
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//得到窗口句柄
	SetConsoleTitle("zyz的贪吃蛇"); //设置窗口标题
	SMALL_RECT rc = {0,0,99,29}; //{Y位置,X位置,宽,高}
	SetConsoleWindowInfo(hOut,true,&rc);//重置窗口位置和大小
	SetConsoleScreenBufferSize(hOut,{100,30});
	srand(time(0));
	HIDE();
	ifstream fin;
	fin.open("D:\\tcsphb.txt");
	for(int i=1;i<=10;i++){
		int x,y;
		if(fin>>x>>y)
			updphb(x,y);
	}
	fin.close();
}
int main()
{
	init();
	bool flag=1;
	while(1){
		HIDE(); 
		if(flag){
			MENU();
			flag=0;
		}
		char ch=0;
		if(_kbhit()){
			ch=_getch();
			if(ch>=0)
				_EGG[++_EGG[0]]=ch;
		}
		//UUDDLLRR BA
		if(_EGG[0]>9){
			if(_EGG[_EGG[0]-9]==72&&_EGG[_EGG[0]-8]==72&&_EGG[_EGG[0]-7]==80&&_EGG[_EGG[0]-6]==80&&_EGG[_EGG[0]-5]==75&&_EGG[_EGG[0]-4]==77&&_EGG[_EGG[0]-3]==75&&_EGG[_EGG[0]-2]==77&&_EGG[_EGG[0]-1]=='b'&&_EGG[_EGG[0]]=='a')
				EGG=1;
		}
		if(ch-48==1){
			GAME();
			flag=1;
		}else if(ch-48==2){
			SETTING();flag=1;
		}else if(ch-48==3){
			ABOUTANDHELP();flag=1;
		}else if(ch-48==4){
			PHB();flag=1;
		}else if(ch-48==5)
			break;
	}
	SAVEPHB();
	system("cls");
	setcolor(6,0);
	GotoXY(46,14);
	printf("感谢游玩\n");
	setcolor(1,0);
	GotoXY(42,16);
	system("pause");
	GotoXY(42,18);
}
posted @ 2024-04-01 22:56  zYzYzYzYz  阅读(121)  评论(0编辑  收藏  举报