#include<stdio.h>
#include<windows.h>
#include<conio.h>
#define border 20
int X = 1, Y = 1, end_x = 1, end_y = 1, food_x = border*3, food_y = border*3;
int start=0, end=0; 
int score = 0;
struct snake{   
	int x;
};
struct snake_body{    //用来记录整个蛇身体的 
	int x;
	int y;
};
struct snake s[border][border*2];
struct snake_body s_body[border*border*10];
void print (struct snake s[][border*2], int *food_x, int *food_y)
{
	printf("\t\t贪吃蛇小游戏\n");
	printf("\t\t作者:尤晓兴\n");
	printf("\t\t成绩:%d\n", score);
	for (int i=0; i<=border; i++)
	{
		for (int j=0; j<=border*2; j++)
		{
//			printf("%d ", s[i][j].x);
			if (i == 0 || j == 0 || i == border || j == border * 2)
			{
				printf("#");
			}
			else {
				if ((s[i][j]).x == 1)
					printf("@");
				else {
					if (*food_x == i && *food_y == j)
						printf("*");
					else
						printf(" ");
				}
			}
		}
		printf("\n");
	}
}
void food(struct snake s[][border*2], int *food_x, int *food_y)
{
	int x = *food_x;
	int y = *food_y;
	do {
		(*food_x) = 1+rand()%(border - 3);
		(*food_y) = 1+rand()%(border*2 - 3);	
	}while((*food_x) == x && (*food_y) == y);
	
	while (s[*food_x][*food_y].x == 1)    //让食物不出现在蛇的身体上 
	{
		(*food_x) = 1+rand()%(border - 3);
		(*food_y) = 1+rand()%(border*2 - 3);
	}
}

void getkey(struct snake s[][border*2],struct snake_body s_body[], int *X, int *Y, int *food_x, int *food_y, int *end_x, int *end_y)
{
	int x = *X;
	int y = *Y;
	if (_kbhit())
	{
		switch (_getch()) {
		case 'w':
		case 'W': if (s[*X-1][*Y].x != 1)
						(*X)--; break;
		case 's':
		case 'S': if (s[*X+1][*Y].x != 1)
						(*X)++; break;
		case 'a':
		case 'A': if (s[*X][*Y-1].x != 1)
						(*Y)--; break;
		case 'd':
		case 'D': if (s[*X][*Y+1].x != 1)
						(*Y)++; break;
		default:
					break;
		}
		if ((*X) != x || (*Y) != y)  //不是后退就记录这个移动 
		{
			s[*X][*Y].x = 1;
			start++;
			s_body[start].x = *X;
			s_body[start].y = *Y;
			if (start == border*(border*10))
				start = 0;
			if (*X == *food_x && *Y == *food_y)   //吃到苹果就尾巴就不用减一了 
			{
				score++;
				return ;
			}
			else {       // 没吃到果子尾巴变为0,根据记录身体的结构体来让记录尾巴的坐标更换 
				end++;
				s[*end_x][*end_y].x = 0;
				*end_x = s_body[end].x;
				*end_y = s_body[end].y;
				if (end == border*(border*10))
					end = 0;
			}
		}
	}
	
}
//初始化一下数值
void initsnake(struct snake s[][border*2], struct snake_body *s_body)   
{                                                                       
	for (int i=0; i<border; i++)
	{
		for (int j=0; j<border*2; j++)
			s[i][j].x = 0;
	}
	s[1][1].x = 1;
	s_body[0].x = 1;
	s_body[0].y = 1;
}
int main()
{
	initsnake(&s[border], s_body);
	food(&s[border], &food_x, &food_y);
	print(&s[border], &food_x, &food_y);
	system("cls");
	while(1)
	{
		getkey(&s[border], s_body, &X, &Y, &food_x, &food_y, &end_x, &end_y);
		if (X == food_x && Y == food_y)
			food(&s[border], &food_x, &food_y);
		if (X == 0 || X == border || Y == 2*border || Y == 0)
		{
			system("cls");
			printf("你输了,成绩为:%d", score);
			system("pause");
			return 0;
		}
		else if (score == (border - 1) * (2*border - 1))
		{
			system("cls");
			printf("你过关了!");
			system("pause");
			return 0;
		}
		print(&s[border], &food_x, &food_y);
//		Sleep(140);
		system("cls");
	}
	return 0;
}