是你想要的贪吃蛇吗?
快来看看吧~
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#include <time.h>
//宏定义
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
typedef struct snake //链表,存放蛇身坐标
{
int x;
int y;
struct snake *next; //蛇身的下一个节点
}snake;
snake *head = NULL;
snake *food = NULL;
int score;
int add = 1;
int direction = RIGHT;
int sleepTime = 300;
int endStatus = 0;
int setColor(int c);
int gotoXY(int x, int y);
int printSnake(void);
int welcomeGame(void);
int aboutGame(void);
int printMap(void);
int showScoreTips(void);
int readFile(void);
int initSnake(void);
int randFood(void);
int moveSnake(void);
int moveKeyControl(void);
int speedUp(void);
int isHitWall(void);
int isBiteSelf(void);
int failGameUi(void);
int endGame(void);
int writeFile(int score);
int snakeDestroy(void);
int setColor(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
int gotoXY(int x, int y)
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
int printSnake(void)
{
//清屏
system("cls");
gotoXY(35, 1);
setColor(6);
printf("/^\\/^\\"); //蛇眼睛
gotoXY(34, 2);
printf("|__| O|"); //蛇眼睛
gotoXY(33, 2);
setColor(2);
printf("_");
gotoXY(25, 3);
setColor(12);
printf("\\/"); //蛇信
gotoXY(31, 3);
setColor(2);
printf("/");
gotoXY(37, 3);
setColor(6);
printf(" \\_/"); //蛇眼睛
gotoXY(41, 3);
setColor(10);
printf(" \\");
gotoXY(26, 4);
setColor(12);
printf("\\____"); //舌头
gotoXY(32, 4);
printf("_________/");
gotoXY(31, 4);
setColor(2);
printf("|");
gotoXY(43, 4);
setColor(10);
printf("\\");
gotoXY(32, 5);
setColor(2);
printf("\\_______"); //蛇嘴
gotoXY(44, 5);
setColor(10);
printf("\\");
gotoXY(39, 6);
printf("| | \\"); //下面都是画蛇身
gotoXY(38, 7);
printf("/ / \\");
gotoXY(37, 8);
printf("/ / \\ \\");
gotoXY(35, 9);
printf("/ / \\ \\");
gotoXY(34, 10);
printf("/ / \\ \\");
gotoXY(33, 11);
printf("/ / _----_ \\ \\");
gotoXY(32, 12);
printf("/ / _-~ ~-_ | |");
gotoXY(31, 13);
printf("( ( _-~ _--_ ~-_ _/ |");
gotoXY(32, 14);
printf("\\ ~-____-~ _-~ ~-_ ~-_-~ /");
gotoXY(33, 15);
printf("~-_ _-~ ~-_ _-~");
gotoXY(35, 16);
printf("~--______-~ ~-___-~");
}
int welcomeGame(void)
{
int i;
int j;
int n;
printSnake();
setColor(11);
gotoXY(45, 18);
printf("贪 吃 蛇 游 戏");
setColor(14);
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("|");
}
else
{
printf(" ");
}
}
}
//输出菜单
setColor(12);
gotoXY(35, 22);
printf("1.开始游戏");
gotoXY(55, 22);
printf("2.游戏说明");
gotoXY(35, 24);
printf("3.退出游戏");
setColor(3);
gotoXY(27, 27);
printf("请选择[1 2 3]: [ ]\b\b\b");
scanf("%d", &n);
getchar();
return n;
}
int aboutGame(void)
{
int i, j;
system("cls");
setColor(13);
gotoXY(44, 3);
printf("游戏说明");
setColor(2);
for(i=6; i <= 22; i++)
{
for(j = 20; j<=75; j++)
{
gotoXY(j, i);
if(i == 6 || i == 22)
{
printf("=");
}
else if(j == 20 || j == 75)
{
printf("||");
}
else
{
printf(" ");
}
}
}
//输出游戏说明界面
setColor(3);
gotoXY(30, 8);
printf("☆1: 不能穿墙,不能咬到自己");
setColor(10);
gotoXY(30, 11);
printf("☆2: 用↑、↓、←、→控制蛇的移动方向");
setColor(14);
gotoXY(30, 14);
printf("☆3: F1加速,F2减速");
setColor(11);
gotoXY(30, 17);
printf("☆4: 按空格键暂停游戏,再按空格键继续");
setColor(4);
gotoXY(30, 20);
printf("☆5: ESC退出游戏,spece暂停游戏");
gotoXY(20, 24);
setColor(12);
printf("请按下回车键返回主界面");
return 0;
}
int printMap(void)
{
int i=0, j=0;
system("cls");
//一个方块占两列
for(i=0; i<27; i++)
{
for(j=0; j<57; j+=2)
{
gotoXY(j, i);
if(i == 0 || i == 26 || j == 0 || j == 56)
{
setColor(5);
printf("□");
}
else
{
setColor(3);
printf("■");
}
}
}
}
int showScoreTips(void)
{
int highScore = 0;
setColor(11);
gotoXY(64, 4);
highScore = readFile();
printf("☆最高记录☆: %d", highScore);
setColor(14);
gotoXY(64, 8);
printf("得分: %d", score );
setColor(12);
gotoXY(72, 11);
printf("温 馨 提 示");
setColor(6);
gotoXY(60, 13);
printf("==============================");
gotoXY(60, 25);
printf("==============================");
setColor(3);
gotoXY(61, 14);
printf("每个食物得分:%d", score);
gotoXY(61, 16);
printf("不能穿墙,不能咬到自己");
gotoXY(61, 18);
printf("用↑↓←→分别控制蛇移动方向");
gotoXY(61, 20);
printf("tip3: F1加速,F2减速");
gotoXY(61, 22);
printf("space: 暂停游戏");
gotoXY(61, 24);
printf("ESC: 退出游戏");
}
int readFile(void)
{
int n = 0;
FILE *fp = NULL;
//打开文件
fp = fopen("save.txt", "a+");
if(NULL == fp)
{
printf("打开文件失败、、、\n");
return -1;
}
fscanf(fp, "%d", &n);
fclose(fp);
return n;
}
int initSnake(void)
{
int i= 0;
snake *new1 = NULL;
snake *tmp = NULL;
//创建四个蛇节点
for (i = 0; i < 4; i++)
{
//分配空间
new1 = (snake*)malloc(sizeof(snake));
if(NULL == new1)
{
printf("malloc failes...\n");
break;
}
//清零
memset(new1, 0, sizeof(snake));
//初始化列为偶数
new1->x = 24 + i * 2;
new1->y = 5;
//头插法
new1->next = head;
head = new1;
}
tmp = head;
while (NULL != tmp)
{
setColor(14);
gotoXY(tmp->x, tmp->y);
if (head == tmp)
{
printf("◆");
}
else
{
printf("★");
}
//指向下一个节点
tmp = tmp->next;
}
return 0;
}
int randFood(void)
{
snake *new2 = NULL;
snake *tmp = NULL;
//分配空间
new2 = malloc(sizeof(snake));
if (NULL == new2)
{
gotoXY(1, 28);
printf("malloc failed...\n");
return -1;
}
while (1)
{
//清零
memset(new2, 0, sizeof(snake));
//随机X值
while (1)
{
//随机X值,为偶数
new2->x = rand() % 53 + 2;
if (new2->x % 2 == 0)
{
break;
}
}
//1-25
new2->y = rand() % 25 + 1;
//判断食物不能在蛇身上
tmp = head;
while (NULL != tmp)
{
if ((tmp->x == new2->x) && ( tmp->y == new2->y))
{
break;
}
tmp = tmp->next;
}
//食物不在蛇身上
if (NULL == tmp)
{
gotoXY(new2->x, new2->y);
setColor(12);
printf("●");
food = new2;
break;
}
else
{
continue;
}
}
return 0;
}
int moveSnake(void)
{
snake *new = NULL;
snake *tmp = NULL;
snake *save = NULL; //保存上一个节点
//分配空间
new = malloc(sizeof(snake));
if(NULL == new)
{
printf("malloc failed...\n");
return -1;
}
memset(new, 0, sizeof(snake));
//向上
if(direction == UP)
{
new->x = head->x;
new->y = head->y-1;
}
//向下
if(direction == DOWN)
{
new->x = head->x;
new->y = head->y+1;
}
//向左
if(direction == LEFT)
{
new->x = head->x-2;
new->y = head->y;
}
//向右
if(direction == RIGHT)
{
new->x = head->x+2;
new->y = head->y;
}
//头插法
new->next = head;
head = new;
//使用临时节点指向链表第一个节点
tmp = head;
//前面是否为食物
if(head->x == food->x && head->y == food->y)
{
while (NULL != tmp)
{
setColor(14);
gotoXY(tmp->x, tmp->y);
if (tmp == head)
{
printf("◆");
}
else
{
printf("★");
}
//指向下一个节点
tmp = tmp->next;
}
//吃掉食物后,分数增加
score += add;
//随机食物
randFood();
}
else
{
//删除最后一个节点
while (NULL != tmp->next)
{
setColor(14);
gotoXY(tmp->x, tmp->y);
if (tmp == head)
{
printf("◆");
}
else
{
printf("★");
}
//保存tmp节点
save = tmp;
//指向下一个节点
tmp = tmp->next;
}
gotoXY(tmp->x, tmp->y);
setColor(3);
printf("■");
save->next = NULL;
free(tmp);
tmp = NULL;
}
return 0;
}
int moveKeyControl(void)
{
//默认向右
direction = RIGHT;
while(1)
{
showScoreTips();
if(GetAsyncKeyState(VK_UP) && direction != DOWN)
{
direction = UP;
}
if(GetAsyncKeyState(VK_DOWN) && direction != UP)
{
direction = DOWN;
}
if(GetAsyncKeyState(VK_LEFT) && direction != RIGHT)
{
direction = LEFT;
}
if(GetAsyncKeyState(VK_RIGHT) && direction != LEFT)
{
direction = RIGHT;
}
if(GetAsyncKeyState(VK_SPACE))
{
while(1)
{
if(GetAsyncKeyState(VK_SPACE))
{
break;
}
Sleep(200);
}
}
if(GetAsyncKeyState(VK_F1))
{
speedUp();
}
if(GetAsyncKeyState(VK_F2))
{
speedDown();
}
//ESC结束游戏
if(GetAsyncKeyState(VK_ESCAPE))
{
endStatus = 3;
endGame();
break;
}
moveSnake();
if(isHitWall() == 1)
{
endStatus = 1;
endGame();
break;
}
if(isBiteSelf())
{
endStatus = 2;
endGame();
break;
}
Sleep(sleepTime);
}
return 0;
}
int speedUp(void)
{
if(sleepTime > 50)
{
sleepTime -= 50;
add +=2;
}
return 0;
}
int speedDown(void)
{
if(sleepTime <300)
{
sleepTime += 10;
add -=2;
}
if(sleepTime > 250)
{
add =1;
}
return 0;
}
int isHitWall(void)
{
if(head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
{
return 1;
}
return 0;
}
int isBiteSelf(void)
{
snake *tmp = NULL;
tmp = head->next;
while(tmp != NULL)
{
if(head->x == tmp->x && head->y == tmp->y)
{
return 1;
}
tmp = tmp->next;
}
return 0;
}
int failGameUi(void)
{
system("cls");
int i;
gotoXY(46, 2);
setColor(6);
printf("\\\\\\|///");
gotoXY(44, 3);
printf("\\\\");
setColor(15);
gotoXY(47, 3);
printf(".-.-");
setColor(6);
gotoXY(53, 3);
printf("//");
setColor(14);
gotoXY(44, 4);
printf("("); //左耳朵
setColor(15);
gotoXY(47, 4);
printf(".@.@");
setColor(14);
gotoXY(53, 4);
printf(")"); //右耳朵
//边框
setColor(11);
gotoXY(17, 5);
printf("+-----------------");
gotoXY(35, 5);
setColor(14);
printf("o00o");
gotoXY(39, 5);
setColor(11);
printf("----------");
gotoXY(48, 5);
setColor(14);
printf("(_)");
gotoXY(51, 5);
setColor(11);
printf("----------");
gotoXY(61, 5);
setColor(14);
printf("o00o");
gotoXY(65, 5);
setColor(11);
printf("-----------------+");
for(i=6; i<20; i++)
{
gotoXY(17, i);
printf("|");
gotoXY(82, i);
printf("|");
}
gotoXY(17, 20);
printf("+----------------------------------");
gotoXY(52, 20);
setColor(14);
printf("☆☆☆");
gotoXY(60, 20);
setColor(11);
printf("----------------------+");
return 0;
}
int endGame(void)
{
system("cls");
//显示失败界面边框
failGameUi();
int highScore=0;
int n=0;
while(1)
{
gotoXY(38, 9);
setColor(12);
switch(endStatus)
{
case 1:
printf("对不起,您已撞墙,游戏结束!");
break;
case 2:
printf("对不起,您咬到自己,游戏结束!");
break;
case 3:
printf("您已经结束了游戏!");
break;
default:
break;
}
//显示得分
setColor(13);
gotoXY(43, 12);
printf("您的得分是:%d", score);
//显示最高记录
highScore = readFile();
if(score > highScore)
{
setColor(10);
gotoXY(38, 16);
printf("您已创造新的最高记录!");
writeFile(score);
}
else
{
setColor(10);
gotoXY(38, 16);
printf("继续努力,离最高分还差:%d", highScore - score);
}
//显示选择菜单
setColor(12);
gotoXY(25, 23);
printf("我要再玩一局----1");
gotoXY(52, 23);
printf("不玩了,退出----2");
setColor(11);
gotoXY(46, 25);
printf("请选择:[ ]\b\b\b");
scanf("%d", &n);
getchar();
if(n == 1)
{
//回到初始状态
sleepTime = 250;
score = 0;
add = 1;
//销毁蛇节点
snakeDestroy();
//初始化头指针
head = NULL;
break;
}
else if(n == 2)
{
exit(0);
}
else
{
setColor(12);
gotoXY(30, 27);
printf("您的输入有误,请重新输入,按下任意键继续");
getchar();
continue;
}
}
return 0;
}
int writeFile(int score)
{
FILE *fp = NULL;
fp = fopen("save.txt", "w");
if(NULL == fp)
{
printf("打开文件失败...\n");
return -1;
}
fprintf(fp, "%d", score);
return 0;
}
int snakeDestroy(void)
{
snake *tmp = NULL;
snake *save = NULL;
tmp = head;
while(NULL != tmp)
{
save = tmp->next;
free(tmp);
tmp = save;
}
head = NULL;
return 0;
}
int main()
{
//显示控制台宽高
system("mode con cols=100 lines=30");
int n;
while(1)
{
system("cls");
n = welcomeGame();
switch(n)
{
case 1:
printMap();
showScoreTips();
initSnake();
randFood();
moveKeyControl();
break;
case 2:
aboutGame();
break;
case 3:
exit(0);
break;
default:
;
}
getchar();
}
system("pause");
return 0;
}