#include
#include
#include
#include
#include
//宏变量
#define U 1
#define D 2
#define L 3
#define R 4
#define Map_x_left 2
#define Map_x_right 52
#define Map_y_up 2
#define Map_y_down 29
#define Foodd_x (Map_x_right - Map_x_left - 3)//4-50-->0-46-->47
#define Food_x 4
#define Foodd_y (Map_y_down - Map_y_up - 2)
#define Food_y 4
//定义链表(全局变量)
typedef struct snake
{
int x;
int y;
const char* body;
struct snake *next;
} snake;
//障碍物属性 随着分数的增加而增加
typedef struct Obstacle
{
int x; //x,y 障碍物的位置
int y;
const char* body;
struct Obstacle* next; //5
}Obstacle;
typedef struct Player
{
int score;
}Player;
int score = 0,add = 10;//初始分数为0,成功一次增加10分
int Highscore= 0;//初始最高分为0分
int status,sleeptime = 200;//蛇的状态,每运行一次要的时间间隔
snake *head,*food;//定义指针指向蛇的头部和食物
Obstacle* obstacle;
Obstacle* AllocObstacle();
int ObstacleConut;
snake *q;//定义指针指向所需的蛇身的变量
int endgamestatus = 0;//定义结束游戏时蛇的状态
int flagob;
HANDLE hOut;
//函数声明
void gotoxy(int x,int y);//设置光标位置
int color(int c);//更改文字颜色
void printsnake();//描绘蛇
void welcometogame();//游戏开始界面
void createMap();//创建游戏地图
void scoreandtips();//右侧的得分和游戏提示
void initsnake();//蛇身初始化,创建形体
void createfood();//创建和随机出现食物
int biteself();//判定蛇是否咬到自己
int cantcrosswall();//设置蛇撞墙的判定
void speedup();//对蛇加速
void speeddown();//对蛇减速
int snakemove();//控制蛇前进方向
void keyboardcontrol();//控制键盘按钮
void lostdrew();// 游戏结束界面
void endgame();//游戏结束
void choose();//游戏失败之后的选择
void File_out();//在文件中读取最高分
void File_in();//存储最高分进文件
void explation();//游戏说明
void ShowObstacle(Obstacle* obstacle);
Obstacle* AllocObstacle();
void InitObstacle(Obstacle* obstacle);
void CreatObstacle();
//设置文字颜色
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return 0;
}
//获取控制台的坐标位置
void gotoxy(int x,int y)
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
//字符蛇
void printsnake()
{
color(9);
printf(" \n");
printf(" __________ ___ \n");
printf(" / \\ / \\ \\ |____ __\\__ \n");
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
printf(" | | |__| _/_ |_| / [|] |/ \n");
printf(" | | | | | / _|_ \\__/ \n");
printf(" \\ \\_______ / \\ |___/ ____ \n");
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
}
//欢迎界面
void welcometogame()
{
int n;
int i,j = 1;
gotoxy(40,18);
printf("贪 吃 蛇 大 作 战");
for(i = 20;i<=26;i++)
{
for(j = 27;j<=74;j++)
{
gotoxy(j,i);
if(i==20||i==26)
{
printf("-");
}else if(j==27||j==74)
{
printf("|");
}
}
}
gotoxy(35,22);
printf("1.开始游戏");
gotoxy(55,22);
printf("2.游戏说明");
gotoxy(35,24);
printf("3.退出游戏");
gotoxy(29,27);
printf("请选择[1 2 3]:[ ]\b\b");
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");
createMap();
initsnake();
scoreandtips();
createfood();
break;
case 2:
explation();
break;
case 3:
exit(0);break;
};
}
//创建游戏地图
void createMap()
{
int i,j;
for(i=0;i<58;i+=2)
{
gotoxy(i,0);
printf("■");
gotoxy(i,26);
printf("■");
}
for(i=1;i<26;i++)
{
gotoxy(0,i);
printf("■");
gotoxy(56,i);
printf("■");
}
for(i=2;i<56;i+=2)
{
for(j=1;j<26;j++)
{
gotoxy(i,j);
printf("□\n");
}
}
}
//游戏分数和提示
void scoreandtips()
{
File_out();
gotoxy(64,4);
printf("☆最高记录☆:%d",Highscore);
gotoxy(64,8);
printf("您的得分为:%d",score);
gotoxy(73,12);
printf("小 提 示");
gotoxy(60,13);
printf("╬-----------------------------╬");
gotoxy(64,15);
printf("每个食物得分:10分");
gotoxy(64,17);
printf("不能穿墙,也不能咬到自己哦");
gotoxy(64,19);
printf("请用 ↑ ↓ ← → 分别控制蛇的移动哦");
gotoxy(64,21);
printf("F1 为加速,F2 为减速");
gotoxy(64,23);
printf("space :暂停游戏");
gotoxy(64,25);
printf("ESC :退出游戏");
gotoxy(60,25);
printf("╬-----------------------------╬");
}
//在文件中读取最高分
void File_out()
{
FILE *fp;
fp=fopen("save.text ","a+");
fscanf(fp,"%d",&Highscore);
fclose(fp);
}
//初始化蛇身
void initsnake()
{
snake *ss;
int i;
ss = (snake*)malloc(sizeof(snake));
ss->x = 24;
ss->y = 5;
ss->next = NULL;
for(i=1;i<=2;i++)
{
head = (snake*)malloc(sizeof(snake));
head->next =ss;
head->x = 24+i*2;
head->y = 5;
ss = head;
}
while(ss!=NULL)
{
gotoxy(ss->x,ss->y);
printf("★");
ss = ss->next;
}
}
//绘制食物并随机显现
void createfood()
{
snake *food1;
food1 = (snake*)malloc(sizeof(snake));
//
srand((unsigned)time(NULL));
//
food1->x=rand()%53+2;
while((food1->x%2)!=0)
{
//
food1->x = rand()%53+2;
}
//
food1->y = rand()%23+1;
//
q = head;
while(q->next!=NULL)
{
//
if(q->x==food1->x&&q->y==food1->y)
{
free(food1);
createfood();//
}
q=q->next;
}
//
gotoxy(food1->x,food1->y);
color(10);
printf("★");
food = food1;
}
//判断蛇是否咬到自己
int biteself()
{
snake *self;
self = head->next;
while(self!=NULL)
{
if(self->x==head->x&&self->y==head->y)
{
return 1;
}
self=self->next;
}
return 0;
}
void ShowObstacle(Obstacle* obstacle)
{ Obstacle* ss = obstacle;
while (ss)
{
gotoxy(ss->x, ss->y);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x09);
printf("%s", ss->body);
ss = ss->next;
}
}
//标记:食物创建完,在判断是否重复
Obstacle* AllocObstacle()
{
Obstacle* ss = (Obstacle*)malloc(sizeof(Obstacle));//障碍物
ss->x = rand() % Foodd_x + Food_x;
ss->y = rand() % Foodd_y + Food_y;
while (ss->x % 2)
{
ss->x = rand() % Foodd_x + Food_x;
}
ss->body = "▲";
ss->next = NULL;
int flag = 0;
//判断障碍物的坐标是否合法
while (1)
{
snake* t = head;
//判断蛇坐标
while (t)
{
if (t->x == ss->x && t->y == ss->y)
{
flag = 1;
break;
}
t = t->next;
}
//判断食物坐标
if (flagob)
{
if (food->x == ss->x && food->y == ss->y)
{
flag = 1;
}
}
if (flag)
{
ss->x = rand() % Foodd_x + Food_x + 1;
while (ss->x % 2)
{
ss->x = rand() % Foodd_x + Food_x;
}
ss->y = rand() % Foodd_y + Food_y + 1;
}
else
{
break;
}
}
return ss;
}
void InitObstacle(Obstacle* obstacle)
{
Obstacle*ss = AllocObstacle();
ss->next = obstacle->next;
obstacle->next = ss;
}
//全局变
int ObstacleConut = 0;
void CreatObstacle()
{
InitObstacle(obstacle);//头插法创建
ObstacleConut++;
ShowObstacle(obstacle);//展示
}
int JudgeObstacle()
{
Obstacle*ss = obstacle;
while (1)
{
if (head->x == ss->x && head->y == ss->y)
return 0;
ss = ss->next;
}
return 0;
}
// 判断蛇是否撞墙
int cantcrosswall()
{
if(head->x==0 || head->x==56 || head->y==0 || head->y==26)
{
endgamestatus = 1;
return 1;
}
return 0;
}
//蛇减速
void speeddown()
{
if(sleeptime<200)
{
sleeptime = sleeptime -10;
add=add-2;
if(sleeptime==350)
{
add=1;
}
}
}
//蛇加速
void speedup()
{
if(sleeptime<=50)
{
sleeptime = sleeptime +30;
add=add+2;
}
}
//控制方向 snakemove()
int snakemove ()
{
snake *newNode;
newNode = (snake*)malloc(sizeof(snake));
if (status == U)
{
newNode->x = head->x;
newNode->y = head->y - 1;
}
if (status == D)
{
newNode->x = head->x;
newNode->y = head->y + 1;
}
if (status == L)
{
newNode->x = head->x - 2;
newNode->y = head->y;
}
if (status == R)
{
newNode->x = head->x + 2;
newNode->y = head->y;
}
//公共代码
newNode->next = head;
//新结点位置赋值给head
head = newNode;
//新结点赋值给head过后,判断是否撞墙了
if(cantcrosswall())
{
status = 0;
endgame();
return 3;
}
//判断新结点上是否有食物
q = head;
if (newNode->x == food->x && newNode->y == food->y)
{
while (q != NULL)
{
gotoxy(q->x, q->y);
color(14);
printf("◆");
q = q->next;
}
//分值的计算
score+=add;
speedup();
scoreandtips();
//食物吃掉,再创建
createfood();
}
else
{
while (q->next->next != NULL)
{
gotoxy(q->x, q->y);
color(14);
printf("◆");
q = q->next;
}
//把倒数第一个变成原来的地图形状
gotoxy(q->next->x, q->next->y);
color(3);
printf("■") ;
//释放内存和指针
free(q->next);
q->next = NULL;
}
if(biteself()==1)
{
endgame();
return 2;
}
return 0;
}
//控制键盘按键
void keyboardcontrol()
{
status = R;
while(1)
{
scoreandtips();
if(GetAsyncKeyState(VK_UP)&&status!=D)
{
status=U;
}
else if(GetAsyncKeyState(VK_DOWN)&&status!=U)
{
status=D;
}
else if(GetAsyncKeyState(VK_LEFT)&&status!=R)
{
status=L;
}
else if(GetAsyncKeyState(VK_RIGHT)&&status!=L)
{
status=R;
}
if(GetAsyncKeyState(VK_SPACE))
{
Sleep(300);
if(GetAsyncKeyState(VK_SPACE))
{
break;
}
}
if(GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus = 3;
break;
}
if(GetAsyncKeyState(VK_F1))
{
speedup();
}
if(GetAsyncKeyState(VK_F2))
{
speeddown();
}
Sleep(sleeptime);
snakemove();
}
}
//失败界面
void lostdrew()
{
system("cls");
int i;
gotoxy(45,2);
color(6);
printf("\\\\\\|///");
gotoxy(43,3);
printf("\\\\");
color(15);
printf(".-.-");
color(6);
gotoxy(54,3);
printf("//");
color(14);
gotoxy(44,4);
printf("(");
color(15);
gotoxy(47,4);
printf(".@.@");
color(14);
gotoxy(54,4);
printf(")");
color(11);
gotoxy(17,5);
printf("+--------------------");
color(14);
gotoxy(39,5);
printf("oOOo");
color(11);
gotoxy(43,5);
printf("----------");
color(14);
gotoxy(53,5);
printf("<_>");
color(11);
gotoxy(56,5);
printf("----------");
color(14);
gotoxy(66,5);
printf("oOOo");
color(11);
gotoxy(70,5);
printf("----------+");
for(i=6;i<=19;i++)
{
gotoxy(17,i);
printf("|");
gotoxy(82,i);
printf("|");
}
gotoxy(17,20);
printf("+----------------------------------");
gotoxy(52,20);
color(14);
printf("☆☆☆∮");
gotoxy(60,20);
color(11);
printf("--------------------+");
}
//结束界面
void endgame()
{
system("cls");
if(endgamestatus==1)
{
lostdrew();
gotoxy(35,9);
color(12);
printf("您撞到了墙,因此游戏结束,别气馁,再来一局!");
}
else if(endgamestatus==2)
{
lostdrew();
gotoxy(35,9);
color(12);
printf("您咬到了自己,游戏结束,别气馁,再来一局!");
}
else if(endgamestatus==3)
{
lostdrew();
gotoxy(40,9);
color(12);
printf("您自己结束了游戏,是太难了吗");
}
color(13);
gotoxy(43,12);
printf("您的得分是:%d",score);
if(score>=Highscore)
{
color(10);
gotoxy(33,16);
printf("创纪录了,再接再厉!");
File_in();
}
else
{
color(10);
gotoxy(33,16);
printf("加油,离最高分还差:%d",Highscore-score);
}
choose();
}
//将最高分存储进文件
void File_in()
{
FILE *fp;
fp = fopen("save.txt","w+");
fprintf(fp,"%d",score);
fclose(fp);
}
//边框下的分支选项
void choose()
{
int n;
color(12);
gotoxy(25,23);
printf("我想再战一局");
gotoxy(52,23);
color(12);
printf("不玩了,改日再战");
color(11);
gotoxy(46,25);
printf("请选择");
scanf("%d",&n);
switch (n) {
case 1:
system("cls");
score = 0;
sleeptime=400;
add = 5;
printsnake();
welcometogame();
break;
case 2:
exit(0);
break;
default:
color(12);
gotoxy(35,27);
printf("※※您的输入有误,请重新输入※※");
system("pause >nul");
endgame();
choose();
break;
}
}
//游戏说明
void explation()
{
int i,j=1;
system("cls");
color(13);
gotoxy(44,3);
printf("游戏说明");
color(2);
for(i=6;i<=22;i++)
{
for(j=20;j<=75;j++)
{
gotoxy(j,i);
if(i==6||i==22)
{
printf("=");
}
if(j==20||j==75)
{
printf("||");
}
}
}
color(3);
gotoxy(30,8);
printf("tip 1: 不能穿墙,也不能咬到自己哦");
color(10);
gotoxy(30,11);
printf("tip 2:请用↑↓←→分别去控制蛇的移动哦");
color(14);
gotoxy(30,14);
printf("tip 3: F1为加速,F2为减速");
color(11);
gotoxy(30,17);
printf("tip 4: 按空格键暂停游戏,再按继续");
color(4);
gotoxy(30,20);
printf("tip 5: ESC:退出游戏,space:暂停游戏");
getch();
system("cls");
printsnake();
welcometogame();
}
//主函数
int main()
{
system("mode con cols=100 lines=30");
printsnake();
welcometogame();
File_out();
keyboardcontrol();
endgame();
CreatObstacle();
Obstacle* obstacle = AllocObstacle();
return 0;
}