运行画面如下:
源码:
#include <graphics.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <tchar.h>
int map[51][51] = { 0 }; //设置一个二维数组作为坐标
int lenth; //蛇的长度
TCHAR grade[20]=_T("0");
TCHAR present[] = _T("当前分数:");
TCHAR end[40] = _T("最终得分:");
TCHAR top_grade[] = _T("历史最高分:");
TCHAR diffult[] = _T("当前难度:");
TCHAR top[20] = _T("0");
TCHAR diff[10] = _T("0");
struct snake { //蛇的链表(坐标和移动方向)
int x;
int y;
char dir;
struct snake *next;
};
void move(struct snake *); //处理移动
int eat(struct snake *,struct snake *); //处理蛇吃食物
void setfood(struct snake *); //随机设置食物
int gameover(struct snake *); //判断游戏是否结束
void show(struct snake *); //显示
int history_score(int); //处理历史记录(读取和记录)
int main()
{
char input;
int begin = 0, over = 0, retry=4, i, j, h_score=0,time;
struct snake *head;
while (retry == 4) {
time = 500;
lenth = 1;
h_score = history_score(0);
sprintf(diff, _T("%d"), (500 - time) / 100 + 1);
sprintf(top, _T("%d"), h_score);
sprintf(grade, _T("%d"), (lenth - 1) * 10);
head = (struct snake *)malloc(sizeof(struct snake));
head->x = 20;
head->y = 20;
head->next = NULL;
for (i = 1; i < 51; i++) {
for (j = 1; j < 51; j++) {
map[i][j] = 0;
}
}
setfood(head);
initgraph(600, 500);
setfillcolor(RED);
settextcolor(WHITE);
while (1) {
if (_kbhit()) { //监控键盘
if ((input = _getch()) == -32) {
input = _getch();
if ((input == 80 && head->dir == 72) || (input == 72 && head->dir == 80)
|| (input == 75 && head->dir == 77) || (input == 77 && head->dir == 75)) {
}
else {
if (head->dir != 0 && head->dir != input) {
map[head->x][head->y] = input;
}
head->dir = input;
}
begin = 1;
}
}
if (begin == 1) { //是否开始
struct snake *body = (struct snake *)malloc(sizeof(struct snake));
if (eat(body, head) == 1) {
head = body;
lenth ++;
if(lenth<=26){ //改变游戏速度
time = 500 - lenth * 15;
sprintf(diff, _T("%d"), (500-time)/100+1);
}else{
sprintf(diff, _T("%d"), 5);
}
sprintf(grade, _T("%d"), (lenth-1) * 10);
setfood(head);
}
move(head);
over = gameover(head);
if (over == 1) {
printf("\a");
if ((lenth - 1) * 10 <= h_score) {
retry = MessageBox(NULL, grade, _T("游戏结束,最终得分"), MB_RETRYCANCEL);
closegraph();
}
else {
retry = MessageBox(NULL, grade, _T("打破记录!最终得分"), MB_RETRYCANCEL);
history_score((lenth - 1) * 10);
closegraph();
}
break;
}
}
show(head);
Sleep(time); //控制蛇移动速度
}
}
return 0;
}
void move(struct snake *body) {
struct snake *head;
int dire=0;
head = body;
while (head) {
if (map[head->x][head->y] != 0&&map[head->x][head->y]!=1) {
dire = map[head->x][head->y];
head->dir = dire;
if (head->next == NULL) {
map[head->x][head->y] = 0;
}
if (dire == 72) {
head->x--;
}
else if (dire == 80) {
head->x++;
}
else if (dire == 75) {
head->y--;
}
else if (dire == 77) {
head->y++;
}
}
else {
dire = head->dir;
if (dire == 72) {
head->x--;
}
else if (dire == 80) {
head->x++;
}
else if (dire == 75) {
head->y--;
}
else if (dire == 77) {
head->y++;
}
}
head = head->next;
}
}
int eat(struct snake *head,struct snake *body) {
int i, j;
for (i = 1; i <= 50; i++) {
for (j = 1; j <= 50; j++) {
if (map[i][j]==1&&((body->x - 1 == i && body->y == j && body->dir == 72) || (body->x + 1 == i && body->y == j && body->dir == 80)
|| (body->y - 1 == j && body->x == i && body->dir == 75) || (body->y + 1 == j && body->x == i && body->dir == 77))) {
map[i][j] = 0;
head->x = i;
head->y = j;
head->next = body;
head->dir = body->dir;
return 1;
}
}
}
return 0;
}
void setfood(struct snake *head) {
struct snake *pre = head;
int x1, y1;
srand((unsigned)time(NULL));
x1 = rand()%50+1;
y1 = rand()%50+1;
while (pre) {
if (pre->x == x1 && pre->y == y1) {
x1 = rand()%50+1;
y1 = rand()%50+1;
}
pre = pre->next;
}
map[x1][y1] = 1;
}
int gameover(struct snake *head) {
struct snake *pre;
pre = head->next;
if ((head->x == 51 && head->dir == 80) || (head->x == 0 && head->dir == 72)
|| (head->y == 51 && head->dir == 77) || (head->y == 0 && head->dir == 75)) {
return 1; //判断是否撞到边界
}
while (pre) { //判断是否撞到身体
if (pre->x == head->x&&pre->y == head->y) {
return 1;
}
pre = pre->next;
}
return 0;
}
void show(struct snake *head) {
int i, j;
struct snake *pre = head;
cleardevice();
line(500, 0, 500, 500); //显示分割线
(510, 120, present); //显示当前分数
outtextxy(530, 140, grade);
outtextxy(510, 220, top_grade); //显示最高分
outtextxy(530, 240, top);
outtextxy(510, 320, diffult); //显示难度
outtextxy(530, 340, diff);
for (i = 1; i < 51; i++) { //显示食物
for (j = 1; j < 51; j++) {
if (map[i][j] == 1) {
fillrectangle((j - 1) * 10, (i - 1) * 10, j * 10, i * 10);
}
}
}
while (pre) { //显示蛇
fillrectangle((pre->y - 1) * 10, (pre->x - 1) * 10, pre->y * 10, pre->x * 10);
pre = pre->next;
}
}
int history_score(int grade) {
FILE *fp;
int score=0;
if (grade==0) { //读取最高分
fp=fopen("top.txt", "r");
if (fp == NULL) {
fp=fopen("top.txt", "w");
fprintf(fp, "%d", score);
fclose(fp);
return 0;
}
else {
fscanf(fp, "%d", &score);
fclose(fp);
return score;
}
}
else { //记录最高分
fp=fopen("top.txt", "w");
fprintf(fp, "%d", grade);
fclose(fp);
}
}