一、程序设计目标
1. 能够统计当次游戏的成绩,并对历史最高分进行记录与展示;
2. 创建一张23*23的地图,四周墙体用"□"实现,中间用"■"实现;
3. 在地图中生成一条蛇,蛇由蛇头和蛇身组成,头为"¤"符号,蛇身为"★"符号;
4. 在地图中的随机位置生成一苹果,由"●"符号实现;
5. 按W、S、A、D四个键代表上、下、左、右四个方向,以此控制蛇头前进的方向,同时蛇身随蛇头方向移动;
6. 当蛇吃到苹果后(蛇头的坐标与苹果的坐标重合),苹果消失,表示其被蛇吃掉,蛇身长度增加1节,得分增加10分,再在地图中的随机位置生成一个新的苹果;
7. 当蛇头撞墙或咬到蛇身时(蛇头的坐标与围墙或蛇身的坐标重合),游戏终止,提示游戏结束;
二、函数模块讲解(附代码)
1. 头文件
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
2. 变量初始化
int wall[30][30]; //创建围墙
int snake[900][2] = { 0 }; //创建蛇
int apple[2] = { 0 }; //创建苹果
int poison[2] = { 0 }; //创建毒药
int ch = 'a'; //创建初始选择变量
int lastch = 'a'; //创建末尾选择变量
int L = 3; //初始蛇长度
int score = 0; //初始得分
int change = 0; //判断蛇头方向是否改变的变量
int HighScore; //历史最高得分
int flag = 0; //记录吃下苹果数目
int apple2[2] = { 0 }; //创建苹果2
char name[5] = { 0 }; //历史得分面板人员名字
3. 光标移动函数
void gotoxy(int x, int y)
{
COORD pos;
pos.X = 2 * x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//获得控制台光标位置
}
4. 颜色设置函数
void color(int a)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
}
5. 建立墙体与得分面板
void makewall()
{
int i, j;
for (i = 0; i < 30; i++)
{
for (j = 0; j < 30; j++)
{
wall[i][j] = 1;
}
}
for (i = 0; i < 30; i++)
{
wall[0][i] = 0;
wall[29][i] = 0;
wall[i][0] = 0;
wall[i][29] = 0;
}
color(11);
for (i = 0; i < 30; i++)
{
for (j = 0; j < 30; j++)
{
if (wall[i][j] == 1)
{
gotoxy(i, j);
printf("■");
}
else
{
gotoxy(i, j);
printf("□");
}
}
}
File_out();
gotoxy(33, 5);
color(11);
printf("☆最高记录☆:%s %d", name, HighScore);
color(14);
gotoxy(33, 15);
printf("当前得分:0");
}
6. 初始化蛇、苹果、毒药
void snake_apple_poison()
{
int i;
color(14);
snake[0][0] = 14;
snake[0][1] = 14;
gotoxy(snake[0][0], snake[0][1]);
printf("¤");
for (i = 1; i < L; i++)
{
snake[i][0] = snake[0][0] + i;
snake[i][1] = snake[0][1];
gotoxy(snake[i][0], snake[i][1]);
printf("★");
}
color(12);
srand((unsigned)time(NULL));
apple[0] = (rand() * 2) % 28 + 1;
apple[1] = (rand() * 3) % 28 + 1;
int j;
for (j = 1; j < L; j++)
{
if (apple[0] == snake[j][0] && apple[1] == snake[j][1])
{
srand((unsigned)time(NULL));
apple[0] = (rand() * 2) % 28 + 1;
apple[1] = (rand() * 3) % 28 + 1;
}
}
gotoxy(apple[0], apple[1]);
printf("●");
color(10);
srand((unsigned)time(NULL));
poison[0] = (rand() * 5) % 28 + 1;
poison[1] = (rand() * 7) % 28 + 1;
int k;
for (k = 1; k < L; k++)
{
if ((poison[0] == snake[k][0] && poison[1] == snake[k][1]) || (poison[0] == apple[0] && poison[1] == apple[1]))
{
srand((unsigned)time(NULL));
poison[0] = (rand() * 5) % 28 + 1;
poison[1] = (rand() * 7) % 28 + 1;
}
}
gotoxy(poison[0], poison[1]);
printf("●");
}
7. 蛇移动函数
void movesnake()
{
if (_kbhit())
{
ch = _getch();
if ((ch != 'w') && (ch != 'a') && (ch != 's') && (ch != 'd'))
ch = lastch;
}
if (!change)
{
gotoxy(snake[L - 1][0], snake[L - 1][1]);
color(11);
printf("■");
}
for (int i = L - 1; i > 0; i--)
{
snake[i][0] = snake[i - 1][0];
snake[i][1] = snake[i - 1][1];
}
if (lastch == 'w' && ch == 's')
ch = 'w';
if (lastch == 's' && ch == 'w')
ch == 's';
if (lastch == 'a' && ch == 'd')
ch = 'a';
if (lastch == 'd' && ch == 'a')
ch = 'd';
switch (ch)
{
case'w':
snake[0][1]--;
break;
case's':
snake[0][1]++;
break;
case'a':
snake[0][0]--;
break;
case'd':
snake[0][0]++;
break;
}
gotoxy(snake[0][0], snake[0][1]);
color(14);
printf("¤");
for (int i = 1; i < L - 1; i++)
{
gotoxy(snake[i][0], snake[i][1]);
color(14);
printf("★");
}
if (GetAsyncKeyState(VK_SPACE)) //按暂停键,执行pause暂停函数
{
while (1)
{
Sleep(300); //sleep()函数,头文件#include <unistd.h> 令进程暂停,直到达到里面设定的参数的时间
if (GetAsyncKeyState(VK_SPACE)) //按空格键暂停
{
break;
}
}
}
gotoxy(29, 0);
change = 0;
Sleep(abs(270-(score/10)));
lastch = ch;
}
8. 打开文件并提取资料
void File_out()
{
FILE* fp;
fp = fopen("save.txt", "a+");
fscanf(fp, "%s %d", &name, &HighScore);
fclose(fp);
}
9. 将资料存入文件
void File_in()
{
FILE* fp;
fp = fopen("save.txt", "w+");
fprintf(fp, "%s %d", name, score);
fclose(fp);
}
10. 创建苹果2
void makeapple2()
{
if (flag == 10)
{
srand((unsigned)time(NULL));
apple2[0] = (rand() * 7) % 28 + 1;
apple2[1] = (rand() * 5) % 28 + 1;
int i, j, k;
for (i = 1; i < L; i++)
{
for (j = 1; j <= 11; j++)
{
for (k = 19; k <= 29; k++)
{
if ((apple2[0] == poison[0] && apple2[1] == poison[1]) || (apple2[0] == snake[i][0] && apple2[1] == snake[i][1]) || (apple2[0] == apple[0] && apple2[1] == apple[1]) || (apple2[0] == 15 && (apple2[1] == j || apple2[1] == k)) || ((apple2[0] == j || apple2[0] == k) && apple2[1] == 15))
{
srand((unsigned)time(NULL));
apple2[0] = (rand() * 71) % 28 + 1;
apple2[1] = (rand() * 103) % 28 + 1;
}
}
}
}
gotoxy(apple2[0], apple2[1]);
color(12);
printf("●");
}
}
11. 创建附加墙体
void longwall()
{
int i, j;
if (flag == 2)
{
i = 15;
for (j = 1; j <= 11; j++)
{
color(11);
gotoxy(i, j);
printf("□");
}
}
if (flag == 4)
{
i = 15;
for (j = 19; j <= 29; j++)
{
color(11);
gotoxy(i, j);
printf("□");
}
}
if (flag == 6)
{
i = 15;
for (j = 1; j <= 11; j++)
{
color(11);
gotoxy(j, i);
printf("□");
}
}
if (flag == 8)
{
i = 15;
for (j = 19; j <= 29; j++)
{
color(11);
gotoxy(j, i);
printf("□");
}
}
}
12. 吃下苹果
void eat_apple()
{
if (snake[0][0] == apple[0] && snake[0][1] == apple[1])
{
flag++;
makeapple2();
longwall();
score += 10;
L++;
color(12);
srand((unsigned)time(NULL));
apple[0] = (rand() * 2) % 28 + 1;
apple[1] = (rand() * 3) % 28 + 1;
int i, j, k;
for (i = 1; i < L; i++)
{
for (j = 1; j <= 11; j++)
{
for (k = 19; k <= 29; k++)
{
if ((apple[0] == poison[0] && apple[1] == poison[1]) || (apple[0] == snake[i][0] && apple[1] == snake[i][1]) || (apple[0] == apple2[0] && apple[1] == apple2[1]) || (apple[0] == 15 && (apple[1] == j || apple[1] == k)) || ((apple[0] == j || apple[0] == k) && apple[1] == 15))
{
srand((unsigned)time(NULL));
apple[0] = (rand() * 39) % 28 + 1;
apple[1] = (rand() * 47) % 28 + 1;
}
}
}
}
gotoxy(apple[0], apple[1]);
printf("●");
change = 1;
gotoxy(38, 15);
color(14);
printf("%d", score);
}
}
13. 吃下苹果2
void eat_apple2()
{
if (snake[0][0] == apple2[0] && snake[0][1] == apple2[1])
{
score += 10;
flag++;
L++;
color(12);
srand((unsigned)time(NULL));
apple2[0] = (rand() * 7) % 28 + 1;
apple2[1] = (rand() * 5) % 28 + 1;
int i, j, k;
for (i = 1; i < L; i++)
{
for (j = 1; j <= 11; j++)
{
for (k = 19; k <= 29; k++)
{
if ((apple2[0] == poison[0] && apple2[1] == poison[1]) || (apple2[0] == snake[i][0] && apple2[1] == snake[i][1]) || (apple2[0] == apple[0] && apple2[1] == apple[1]) || (apple2[0] == 15 && (apple2[1] == j || apple2[1] == k)) || ((apple2[0] == j || apple2[0] == k) && apple2[1] == 15))
{
srand((unsigned)time(NULL));
apple2[0] = (rand() * 3) % 28 + 1;
apple2[1] = (rand() * 4) % 28 + 1;
}
}
}
}
gotoxy(apple2[0], apple2[1]);
printf("●");
change = 1;
gotoxy(38, 15);
color(14);
printf("%d", score);
}
}
14. 游戏结束后的选择
void choose()
{
score = 0;
L = 3;
int n = 0;
gotoxy(23, 23);
color(12);
printf("重玩一局 [1]");
gotoxy(23, 26);
printf("下次再来 [2]");
gotoxy(23, 29);
color(11);
printf("选择:");
scanf("%d", &n);
switch (n)
{
case 1:
system("cls");
makewall();
snake_apple_poison();
while (1)
{
movesnake();
gotoxy(0, 0);
color(11);
printf("□");
eat_apple();
eat_poison();
if_wall();
if_biteself();
}
break;
case 2:
exit(0);
break;
default:
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
choose();
break;
}
}
15. 吃下毒药
void eat_poison()
{
if (snake[0][0] == poison[0] && snake[0][1] == poison[1])
{
gotoxy(10, 14);
color(10);
printf("对不起,您吃掉毒药了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while(name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
return 0;
}
16. 撞墙
void if_wall()
{
if (flag < 2)
{
if (snake[0][1] == 0 || snake[0][1] == 29 || snake[0][0] == 0 || snake[0][0] == 29)
{
gotoxy(10, 14);
color(10);
printf("对不起,您撞到墙了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
}
if (flag >= 2 && flag < 4)
{
int i;
for (i = 1; i <= 11; i++)
{
if (snake[0][1] == 0 || snake[0][1] == 29 || snake[0][0] == 0 || snake[0][0] == 29 || (snake[0][0] == 15 && snake[0][1] == i))
{
gotoxy(10, 14);
color(10);
printf("对不起,您撞到墙了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
}
}
if (flag >= 4 && flag < 6)
{
int i, j;
for (i = 1; i <= 11; i++)
{
for (j = 19; j <= 29; j++)
{
if (snake[0][1] == 0 || snake[0][1] == 29 || snake[0][0] == 0 || snake[0][0] == 29 || (snake[0][0] == 15 && (snake[0][1] == i || snake[0][1] == j)))
{
gotoxy(10, 14);
color(10);
printf("对不起,您撞到墙了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
}
}
}
if (flag >= 6 && flag <8)
{
int j, k;
for (j = 1; j <= 11; j++)
{
for (k = 19; k <= 29; k++)
{
if (snake[0][1] == 0 || snake[0][1] == 29 || snake[0][0] == 0 || snake[0][0] == 29 || (snake[0][0] == 15 && (snake[0][1] == j || snake[0][1] == k)) || (snake[0][0] == j && snake[0][1] == 15))
{
gotoxy(10, 14);
color(10);
printf("对不起,您撞到墙了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
}
}
}
else if (flag >=8)
{
int j, k;
for (j = 1; j <= 11; j++)
{
for (k = 19; k <= 29; k++)
{
if (snake[0][1] == 0 || snake[0][1] == 29 || snake[0][0] == 0 || snake[0][0] == 29 || (snake[0][0] == 15 && (snake[0][1] == j || snake[0][1] == k)) || ((snake[0][0] == j || snake[0][0] == k) && snake[0][1] == 15))
{
gotoxy(10, 14);
color(10);
printf("对不起,您撞到墙了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
}
}
}
return 0;
}
17. 咬到自己
void if_biteself()
{
int i = 1;
while (i <= L)
{
if (snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1])
{
gotoxy(snake[0][0], snake[0][1]);
color(14);
printf("¤");
gotoxy(10, 14);
color(10);
printf("对不起,您咬到自己了。游戏结束!");
gotoxy(10, 16);
color(14);
printf("您的得分是 %d", score);
if (score >= HighScore)
{
color(10);
gotoxy(10, 17);
printf("创纪录啦!最高分被你刷新啦,真棒!!!请留下您的大名!");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
while (name[0] == 0 || name[1] == 0 || name[2] == 0 || name[3] == 0)
{
gotoxy(23, 30);
color(12);
printf("※※您的输入有误,请重新输入※※");
gotoxy(10, 18);
printf("请为自己取一个两字绰号:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%s", &name);
}
File_in();
}
else
{
color(10);
gotoxy(10, 17);
printf("继续努力吧~ 你离最高分还差:%d", HighScore - score);
}
choose();
}
i++;
}
return 0;
}
18. 游戏说明
void explation()
{
int i, j = 1;
system("cls");
color(15);
gotoxy(26, 3);
printf("游戏说明");
color(2);
for (i = 8; i <= 48; i++)
{
for (j = 6; j <= 22; j++)
{
gotoxy(i, j);
if (i == 8 || i == 48) printf("||");
else if (j == 6 || j == 22) printf("=");
}
}
color(3);
gotoxy(12, 8);
printf("tip1: 不能撞墙,不能咬到自己");
color(10);
gotoxy(12, 11);
printf("tip2: 用 W A S D 分别控制蛇的移动");
color(14);
gotoxy(12, 14);
printf("tip3: 红色●为苹果,吃掉可以得分;绿色●为毒药,吃掉则gameover ");
color(11);
gotoxy(12, 17);
printf("tip4: 按空格键暂停游戏,再按空格键继续");
color(4);
gotoxy(40, 20);
printf("按任意键返回");
_getch();
system("cls");
initializing();
}
19. 菜单函数
void initializing()
{
color(2);
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");
int n;
int i, j = 1;
gotoxy(23, 18);
color(11);
printf("贪 吃 蛇 游 戏");
color(14);
for (i = 10; i <= 42; i++)
{
for (j = 19; j <= 26; j++)
{
gotoxy(i, j);
if (i == 10 || i == 42)
{
printf("|");
}
else if (j == 19 || j == 26)
{
printf("_");
}
}
}
color(10);
gotoxy(15, 21);
printf("1.开始游戏");
gotoxy(15, 23);
printf("2.游戏说明");
gotoxy(15, 25);
printf("3.退出游戏");
gotoxy(25, 25);
color(3);
printf("请选择[1 2 3]:[ ](按回车键确认)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
color(14);
scanf("%d", &n);
switch (n)
{
case 1:
system("cls");
makewall();
snake_apple_poison();
while (1)
{
movesnake();
gotoxy(0, 0);
color(11);
printf("□");
eat_apple();
eat_apple2();
eat_poison();
if_wall();
if_biteself();
}
break;
case 2:
explation();
break;
case 3:
exit(0);
break;
default:
color(12);
gotoxy(40, 28);
printf("请输入1~3之间的数!");
_getch();
system("cls");
initializing();
}
}
20. 主函数
int main()
{
initializing(); //初始化系统
return 0;
}
三、程序运行展示