C语言使用EsayX库实现简易贪吃蛇

运行画面如下:


源码:

#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);
	}
}

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值