头文件
#pragma once
#ifndef __TCS_H__
#define __TCS_H__
#include
#include
#include
#include
#include
#define Filename "tcs.52m"
#define U 1
#define D 2
#define L 3
#define R 4 //蛇的状态,U:上 ;D:下;L:左 R:右
typedef struct SNAKE //蛇身的一个节点
{
int x;
int y;
struct SNAKE *next;
}snake;
typedef struct PLAYER
{
char name[20];
int scores;
char len[3];
int steps;
}player;
typedef struct ACHEVE
{
int step;
int eat;
int score;
}acheve;
//声明全部函数//
void Pos();
void creatMap();
void initsnake();
int biteself();
void createfood();
void cantcrosswall();
void snakemove();
void pause();
void gamecircle();
void welcometogame();
void gamestart();
void endgame();
void print();
void menu();
void inittop();
void showtop();
void sorttop();
void startshow();
void selectmap();
void mapmenu();
int topmenu();
void loadtop();
void savetop();
void color();
void showach();
void loadach();
void saveach();
#endif//__TCS_H__
源文件
#define _CRT_SECURE_NO_WARNINGS
#include "TCS.h"
//全局变量//
int level = 0; //关卡数,0表示无尽模式
int score = 0, add = 10; //总得分与每次吃食物得分
int status, sleeptime = 200; //每次运行的时间间隔
snake *head, *food; //蛇头指针,食物指针
snake *q; //遍历蛇的时候用到的指针
int endgamestatus = 0; //游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏。
int run = 0; //判断游戏是否还能运行
player top[61]; //排行榜
int MAX_LL = 130; //游戏窗口长度
int MAX_CC = 36; //游戏窗口高度
int MAX_L = 92; //游戏区域长度
int MAX_C = 35; //游戏区域高度
int steps = 0; //计数步数
int lenth = 4; //计数长度
acheve ach; //成就数据
//设置字体颜色
void color(int x)
{
if (!x)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), rand()%6+9); //只有一个参数,改变字体颜色
else
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
}
//设置光标位置
void Pos(int x, int y)
{
COORD pos;
HANDLE hOutput;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, pos);
}
//创建地图
void creatMap()
{
int i;
for (i = 0; ix=24;
tail->y = 15;
tail->next = NULL;
for (i = 1; i <= 4; i++)
{
head = (snake*)malloc(sizeof(snake)); head->next = tail;
head->x = 24 + 2 * i;
head->y = 15;
tail = head;
}
Pos(tail->x, tail->y);
printf("●");
tail = tail->next;
while (tail != NULL)//从头到尾,输出蛇身
{
Pos(tail->x, tail->y);
printf("■");
tail = tail->next;
}
}
//判断是否咬到了自己
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 createfood()
{
snake * food_1;
res:
food_1 = (snake*)malloc(sizeof(snake)); //保证其为偶数,使得食物能与蛇头对其
food_1->x = (rand() % (MAX_L-4) + 2)/2*2;
food_1->y = rand() % (MAX_C-1) + 1;
q = head;
//food_1 = (snake*)malloc(sizeof(snake));
//while ((food_1->x % 2) != 0) //保证其为偶数,使得食物能与蛇头对其
//{
// food_1->x = rand() % (MAX_L - 4) + 2;
//}
//food_1->y = rand() % (MAX_C - 3) + 1;
//q = head;
while (q != NULL)
{
if (q->x == food_1->x && q->y == food_1->y) //判断蛇身是否与食物重合
{
free(food_1);
goto res;
}
q = q->next;
}
Pos(food_1->x, food_1->y);
food = food_1;
color(0);
printf("★");
}
//不能穿墙
void cantcrosswall()
{
if (head->x == 0 || head->x == MAX_L-2 || head->y == 0 || head->y == MAX_C)
{
system("color cf");
Sleep(200);
system("color 0f");
Sleep(200);
system("color cf");
Sleep(200);
system("color 0f");
endgamestatus = 1;
endgame();
}
}
//蛇前进,上U,下D,左L,右R
void snakemove()
{
snake * nexthead;
cantcrosswall();
if (run)return;
nexthead = (snake*)malloc(sizeof(snake));
if (status == U)
{
nexthead->x = head->x;
nexthead->y = head->y - 1;
}
else if (status == D)
{
nexthead->x = head->x;
nexthead->y = head->y + 1;
}
else if (status == L)
{
nexthead->x = head->x - 2;
nexthead->y = head->y;
}
else if (status == R)
{
nexthead->x = head->x + 2;
nexthead->y = head->y;
}
if (nexthead->x == food->x && nexthead->y == food->y)//如果下一个有食物//
{
nexthead->next = head;
head = nexthead;
q = head;
Pos(q->x, q->y);
//color(0);
printf("●");
Pos(q->next->x, q->next->y);
//color(0);
printf("■");
while (q->next != NULL)
{
q = q->next;
}
Pos(q->x, q->y);
//color(0);
printf("■");
score = score + add;
lenth++;
createfood();
}
else //如果没有食物//
{
nexthead->next = head;
head = nexthead;
q = head;
Pos(q->x, q->y);
//color(0);
printf("●");
Pos(q->next->x, q->next->y);
//color(0);
printf("■");
while (q->next->next != NULL)
{
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = NULL;
}
steps++;
if (biteself() == 1) //判断是否会咬到自己
{
endgamestatus = 2;
system("color cf");
Sleep(200);
system("color 0f");
Sleep(200);
system("color cf");
Sleep(200);
system("color 0f");
endgame();
}
if (run)return;
}
//暂停
void pause()
{
while (1)
{
Sleep(300);
if (GetAsyncKeyState(VK_SPACE))
{
break;
}
}
}
//控制游戏
void gamecircle()
{
Pos(MAX_L+4, 15);
color(0);
printf("不能穿墙,不能咬到自己\n");
Pos(MAX_L + 4, 16);
color(0);
printf("用↑.↓.←.→分别控制蛇的移动.");
Pos(MAX_L + 4, 17);
color(0);
printf("F1 为加速,F2 为减速\n");
Pos(MAX_L + 4, 18);
color(0);
printf("ESC :退出游戏.Space:暂停游戏.");
Pos(MAX_L + 4, 20);
color(0);
printf("\n");
status = D;
while (1)
{
Pos(MAX_L + 6, 10);
printf("得分:%d ", score);
Pos(MAX_L + 6, 11);
printf("每个食物得分:%d分", add);
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;
}
else if (GetAsyncKeyState(VK_SPACE))
{
pause();
}
else if (GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus = 3;
break;
}
else if (GetAsyncKeyState(VK_F1))
{
if (sleeptime >= 50)
{
sleeptime = sleeptime - 30;
add = add + 2;
if (sleeptime == 320)
{
add = 2;//防止减到1之后再加回来有错
}
}
}
else if (GetAsyncKeyState(VK_F2))
{
if (sleeptime<350)
{
sleeptime = sleeptime + 30;
add = add - 2;
if (sleeptime == 350)
{
add = 1; //保证最低分为1
}
}
}
Sleep(sleeptime);
snakemove();
if (run)return;
}
}
//简介界面
void welcometogame()
{
system("cls");
//int i = 7;
//color(13);
//Pos(6, 7);
//printf("■■■■ ★");
//for (i = 8; i < 20; i++)
//{
// Pos(6, i);
// printf("■");
// Pos(MAX_L + 6, i);
// printf("■");
//}
//Pos(6, i);
//for (i = 6; i <= MAX_L + 6; i+=2)
// printf("■");
print();
Pos(MAX_L/2-12, 7);
color(15);
printf("用");
color(10);
printf("↑ ↓ ← →");
color(15);
printf("分别控制蛇的移动");
Pos(MAX_L / 2 - 12, 9);
color(12);
printf("F1 ");
color(15);
printf("为加速");
color(12);
printf(" F2 ");
color(15);
printf("为减速\n");
Pos(MAX_L / 2 - 12, 11);
color(15);
printf("可以多点几下");
color(11);
printf(" F1 ");
color(15);
printf("或者");
color(11);
printf(" F2 ");
color(15);
printf("切换到你认为最适合你的难度\n");
Pos(MAX_L/2-12, 13);
printf("加速将能得到");
color(13);
printf("更高的分数。");
Pos(MAX_L / 2 - 12, 15);
color(14);
printf("开始进行愉快的贪吃蛇游戏吧 ^ _ ^\n");
Pos(MAX_L / 2-12, 25);
color(15);
system("pause");
system("cls");
}
//结束游戏
void endgame()
{
char c;
system("cls");
print();
Pos(MAX_L/2, 12);
if (endgamestatus == 1)
{
color(12);
printf("很遗憾,你撞到了墙。游戏结束.");
}
else if (endgamestatus == 2)
{
color(12);
printf("很遗憾,你咬到了自己。游戏结束.");
}
else if (endgamestatus == 3)
{
color(12);
printf("你已经结束了游戏。");
}
Pos(MAX_L / 2, 13);
printf("你的得分是:%d,在本局游戏中你一共走了:%d格", score,steps);
if (score >= top[(MAX_LL-70)/30*20-1].scores)
{
Pos(MAX_L / 2, 14);
system("pause");
top[60].scores = score;
sprintf(top[60].len, "%d", lenth);
top[60].steps = steps;
Pos(MAX_L / 2, 14);
printf("恭喜你进入排行榜!!!!");
Pos(MAX_L / 2, 15);
while ((c = getchar()) != '\n' && c != EOF);
printf("是否留下你的名字?(y/n)");
scanf("%c", &c);
if ('y' == c || 'Y' == c)
{
Pos(MAX_L / 2, 16);
printf("请输入你的昵称:>");
scanf("%s", top[60].name);
sorttop();
Pos(MAX_L / 2, 17);
printf("排行榜已更新...");
}
else
{
strcpy(top[60].name, "noname");
sorttop();
Pos(MAX_L / 2, 17);
printf("排行榜已更新...");
}
}
ach.step += steps;
ach.score += score;
ach.eat += (lenth - 4);
saveach();
run = 1;
Pos(MAX_L / 2, 18);
system("pause");
}
//游戏初始化
void gamestart()
{
char p[50];
sleeptime = 200;
score = 0;
add = 10;
steps = 0;
lenth = 4;
system("cls");
run = 0;
sprintf((char * )p, "mode con cols=%d lines=%d", MAX_LL, MAX_CC);
system((const char*)p);
creatMap();
initsnake();
createfood();
}
//选择地图界面
void mapmenu()
{
print();
Pos((MAX_LL - 78) / 2 - 1, MAX_CC / 5);
printf("■■■■■■■■ ★ ■■■■■■■■");
Pos(MAX_LL / 2 - 6, MAX_CC / 2 - 5);
printf("1.地图:小");
Pos(MAX_LL / 2 - 6, MAX_CC / 2 - 3);
printf("2.地图:中");
Pos(MAX_LL / 2 - 6, MAX_CC / 2 - 1);
printf("3.地图:大");
Pos((MAX_LL - 78) / 2 - 1, MAX_CC / 2+1);
printf("选择你的地图大小:>");
}
//选择地图
void selectmap()
{
int input;
do
{
system("cls");
mapmenu();
fflush(stdin);
scanf("%d", &input);
switch (input)
{
case 1:
MAX_LL = 100;
MAX_CC = 30;
MAX_L = 64;
MAX_C = 29;
return;
break;
case 2:
MAX_LL = 130;
MAX_CC = 36;
MAX_L = 92;
MAX_C = 35;
return;
break;
case 3:
MAX_LL = 160;
MAX_CC = 45;
MAX_L = 120;
MAX_C = 44;
return;
break;
default:
Pos((MAX_LL - 78) / 2 - 1, MAX_CC / 2 + 2);
printf("输入有误!");
Sleep(500);
break;
}
} while (1);
}
//打印边框
void print()
{
int i;
for (i = 0; i=16)
{
Pos(i-16, t);
printf(" ");
}
if (i >= (MAX_LL / 2 + 8) && i <= (MAX_LL / 2 + 10))
{
color(13);
}
Sleep(15);
}
//system("pause");
}
//测试食物是否会生成在地图外
void test()
{
int x = 0;
int y = 0;
system("cls");
creatMap();
color(15);
Pos(MAX_L + 4, 15);
printf("按下Esc结束测试状态");
while(1) //保证其为偶数,使得食物能与蛇头对其
{
x = (rand() % (MAX_L - 4) + 2)/2*2;
y = rand() % (MAX_C - 1) + 1;
Pos(x,y);
color(0);
printf("█");
if (GetAsyncKeyState(VK_ESCAPE))
{
break;
}
}
}
//主函数
int main()
{
int input;
char p[50];
color(0);
srand((unsigned)time(NULL));
inittop();
loadach();
sprintf((char * )p, "mode con cols=%d lines=%d", MAX_LL, MAX_CC);
system((const char*)p);
startshow();
do{
system("cls");
menu();
Pos(MAX_LL / 2 - 14, MAX_CC / 2 + 3);
printf("请选择:>");
//printf("%d", sizeof(player));
fflush(stdin);
scanf("%d", &input);
switch (input)
{
case 5:
test();
break;
case 4:
showach();
break;
case 3:
showtop();
break;
case 2:
welcometogame();
break;
case 1:
game();
break;
case 0:
break;
default:
Pos(MAX_LL / 2 - 14, MAX_CC / 2 + 4);
printf("输入有误请重新输入!\n");
Sleep(500);
break;
}
} while (input);
Pos(MAX_LL / 2 - 14, MAX_CC / 2 + 4);
printf("感谢你的游玩,再见!");
Sleep(800);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include "TCS.h"
//全局变量//
extern int level ;
extern int score , add ;
extern int status, sleeptime ;
extern snake *head, *food;
extern snake *q;
extern int endgamestatus ;
extern int run ;
extern player top[61];
extern int MAX_LL ;
extern int MAX_CC ;
extern int MAX_L ;
extern int MAX_C ;
//初始化排行
void inittop()
{
int j = 0;
for (j = 0; j < 3; j++)
{
int i = 0;
top[20 * j + i].scores = 999;
sprintf(top[20 * j + i].len, "%d", 56);
top[20 * j + i].steps = 1658;
for (i = 1; i < 20; i++)
{
top[20 * j + i].scores = 480 - 20 * i;
sprintf(top[20 * j + i].len ,"%d", 48 - 2 * i);
top[20 * j + i].steps = 999 - 20 * i;
}
for (i = 0; i < 21; i++)
{
strcpy(top[20 * j + i].name, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
strcpy(top[20 * j + i].name, "LRS");
}
}
top[60].scores = 0;
loadtop();
}
//排行菜单
int topmenu()
{
int input;
do
{
system("cls");
mapmenu();
fflush(stdin);
scanf("%d", &input);
switch (input)
{
case 1:
return 0;
break;
case 2:
return 1;
break;
case 3:
return 2;
break;
default:
Pos((MAX_LL - 78) / 2 - 1, MAX_CC / 2 + 2);
printf("输入有误!");
Sleep(500);
break;
}
} while (1);
}
//显示排行
void showtop()
{
int i = 0;
int j = topmenu();
system("cls");
print();
Pos(MAX_LL / 5, i + 3);
color(15);
printf("%-5s\t%-20s%-6s\t%-3s\t%-8s", "名次", "昵称", "分数","体长","路程");
for (i = 0; i < 20; i++)
{
Pos(MAX_LL / 5, i + 4);
if (i < 20)color(15);
if (i < 10)color(10);
if (i < 5)color(9);
if (i < 3)color(13);
if (i < 2)color(14);
if (i < 1)color(12);
printf("%-5d\t%-20s%-6d\t%-3s\t%-8d", i + 1, top[j * 20 + i].name, top[j * 20 + i].scores, top[j * 20 + i].len, top[j * 20 + i].steps);
}
Pos(MAX_LL / 5, i + 6);
system("pause");
system("cls");
}
//排序排行
void sorttop()
{
int i = 0;
int j = 0;
int m = (MAX_LL - 100) / 30 * 20;
for (i = 0; i < 20; i++)
{
if (top[60].scores >= top[m + i].scores)
{
for (j = 19 + m; j >(i + m); j--)
{
top[j] = top[j - 1];
}
top[i + m] = top[60];
break;
}
}
savetop();
}
//加载
void loadtop()
{
int ret = 0;
FILE* c = fopen(Filename,"a+");
FILE* load = fopen(Filename, "rb");
fclose(c);
c = NULL;
if (load == NULL)
{
perror("load top");
exit(1);
}
while(fread(&top[ret++], sizeof(player), 1, load));
//printf("%d", ret);
//system("pause");
fclose(load);
load = NULL;
}
//保存
void savetop()
{
int i = 0;
FILE* save = fopen(Filename, "w");
if (save == NULL)
{
perror("save top");
exit(1);
}
fwrite(&top[0], sizeof(player), 60, save);
fclose(save);
save = NULL;
}
#define _CRT_SECURE_NO_WARNINGS
#include "TCS.h"
extern acheve ach;
extern int MAX_LL;
struct achname
{
char name[20];
int num;
}name[9] = { { "旅行蛇",10000 }
,{ "环游中国",100000 } ,{"遨游太空",1000000 },{"大胃王", 100}
,{ "上古腐鲸蛇",10000 },{ "宇宙级大蛇", 100000},{ "得分高手",10000 }
,{ "得分大师",100000 },{"得分宗师",1000000 }};
//展示成就
void showach()
{
int i = 0;
system("cls");
print();
Pos(MAX_LL / 5, i + 3);
color(15);
printf("%-20s\t %-12s\t", "成就", "状态");
for (i = 0; i < 9; i++)
{
color(i % 3 + 10);//判断颜色
Pos(MAX_LL / 5, 2 * (i + 1) + 3);
printf("%-20s\t", name[i].name);
switch (i / 3)//判断类型
{
case 0:
if (ach.step >= name[i].num)
{
printf("%10d/%-9d", name[i].num, name[i].num);
}
else
printf("%10d/%-9d", ach.step, name[i].num);
break;
case 1:
if (ach.eat >= name[i].num)
{
printf("%10d/%-9d", name[i].num, name[i].num);
}
else
printf("%10d/%-9d", ach.eat, name[i].num);
break;
case 2:
if (ach.score >= name[i].num)
{
printf("%10d/%-9d", name[i].num, name[i].num);
}
else
printf("%10d/%-9d", ach.score, name[i].num);
break;
}
}
Pos(MAX_LL / 5, 2 * (i + 1) + 5);
printf("走过的总步数:%d步\t吃过的食物总数:%d个\t得到的总分数:%d分"
,ach.step, ach.eat, ach.score);
Pos(MAX_LL / 5, 2 * (i + 1) + 7);
system("pause");
}
//加载
void loadach()
{
FILE* c = fopen("ach.52m","a+");//如果没有就新建
FILE* load = fopen("ach.52m", "rb");
fclose(c);
c = NULL;
if (load == NULL)
{
perror("load ach");
exit(1);
}
ach.eat = 0;
ach.score = 0;
ach.step = 0;
fread(&ach, sizeof(acheve), 1, load);
fclose(load);
load = NULL;
}
//保存
void saveach()
{
FILE* save = fopen("ach.52m", "wb");
if (save == NULL)
{
perror("save ach");
exit(1);
}
fwrite(&ach, sizeof(acheve), 1, save);
fclose(save);
save = NULL;
}
这样我们的贪吃蛇游戏就做好了...
更多精彩请看我的个人博客:LRS的博客