贪吃蛇C语言

贪吃蛇C语言

不知不觉大一已过去了一半, 今天要考试了, 我也是感慨良多, 那是我失去的青春, 呜呜呜~~ 这次代码是继上次的优化和完善, 若有好的建议或意见随时欢迎交流

运行效果图
贪吃蛇C语言_第1张图片
代码奉上

# include 
# include  					//malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()
# include 					//Sleep()、gotoxy()、HideCursor()
# include 						//_getch()、kbhit()
# include 						//time()

void gotoxy(int x, int y) {
     				//移动光标; 网上复制
	COORD pos;
	HANDLE hOutput;
	pos.X = (SHORT)x;
	pos.Y = (SHORT)y;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOutput, pos);
}

void HideCursor() {
     						//隐藏光标; 网上复制
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = FALSE;
	cursor.dwSize = sizeof(cursor);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cursor);
}

typedef struct Node {
                      	//结构体坐标
	int x, y;
	struct Node *next;
} Node, *List;

List head; 								//全局变量
//num蛇身长度; x, y蛇身坐标; fx, fy食物坐标; garde玩家分数
int num = 5, x = 5, y = 5, fx = 5, fy = 5, garde = 0;
DWORD speed = 200;                       //speed移动速度



List Create() {
      						//创建结点
	List p = (List)malloc(sizeof(Node));
	if (!p) {
     
		puts("空间不足");
		exit(0);
	}
	p->next = NULL;
	return p;
}

void Insert() {
      						//录入结点
	List p = Create();
	p->x = x;
	p->y = y;
	p->next = head->next;
	head->next = p;
}

void Wall() {
     
	int i, j;
	gotoxy(0, 0);
	for (i = 0; i < 20; ++i) {
     
		for (j = 0; j < 40; ++j) {
     
			if (0 == i || 19 == i || 0 == j || 39 == j) {
     
				printf("*");
			} else {
     
				printf(" ");
			}
		}
		printf("\n");
	}
}

void GameOver() {
                            //游戏结束
	gotoxy(0, 0);                       //覆盖蛇身
	Wall();
	gotoxy(15, 9);
	puts("GAME OVER");
	system("pause");
	exit(0);
}

void EatOver() {
                         	//吃到自己结束;
	int i, j;
	List pa, pb;
	//比较是否存在坐标相同结点, 如果存在即撞到自身, 游戏结束
	for (i = 0, pa = head->next; i < num - 1 && pa->next; ++i, pa = pa->next) {
     
		for (j = 0, pb = pa->next; j < num && pb; ++j, pb = pb->next) {
     
			if (pa->x == pb->x && pa->y == pb->y) {
     
				GameOver();
			}
		}
	}
}

List Food() {
                          		//创建食物
	List p = Create();
	srand((unsigned)time(NULL));        //完全随机
	p->x = rand() % 17 + 1;
	p->y = rand() % 17 + 1;
	return p;
}

List FoodCreate() {
                          //打印食物
	List p = head->next, pf = Create();
	int i, judge = 0;
	while (1) {
     
		judge = 0;
		pf->x = Food()->x;
		pf->y = Food()->y;
		//食物坐标与蛇身坐标比较, 如果相同, 则重新得到食物
		for (i = 0, p = head->next; i < num && p->next; ++i, p = p->next) {
     
			if (pf->x == p->x && pf->y == p->y) {
     
				judge = 1;
				break;
			}
		}
		if (0 == judge) {
     
			return pf;
		}
	}
}

void Print() {
      							//打印蛇身
	int i;
	EatOver();                          //是否吃到自己
	List p = head->next;
	for (i = 0; i < num && p; ++i, p = p->next) {
     
		gotoxy(p->x, p->y);
		if (0 == i) {
                        //蛇头
			printf("@");
		} else if (1 == i) {
                 //蛇身
			printf("+");
		} else if (i + 1 == num) {
           //蛇尾覆盖
			printf(" ");
		}
	}
}

void WallDeath() {
                           //撞墙结束
	if (0 == x || 39 == x || 0 == y || 19 == y) {
     
		GameOver();
	}
}

void WallPass() {
                           //穿墙(未插入, 可替换WallDeath();)
	if (0 == x) {
     
		x = 38;
	}
	if (39 == x) {
     
		x = 1;
	}
	if (0 == y) {
     
		y = 18;
	}
	if (19 == y) {
     
		y = 1;
	}
}

void FoodEat() {
     						//吃到食物
	if (x == fx && y == fy) {
     
		if (0 == num % 5 && speed > 50) {
                    //速度变快
			speed -= 5;
		}
		gotoxy(41, 1);
		printf("速度: %.1f%%", 10000 / (float)speed);   //速度上限是200%
		garde += 10;                    //分数增加
		gotoxy(41, 3);
		printf("分数: %d", garde);
		++num;                          //蛇身加长
		gotoxy(41, 5);
		printf("长度: %d", num);
		fx = FoodCreate()->x;
		fy = FoodCreate()->y;
		gotoxy(fx, fy);                 //打印食物
		printf("$");
		gotoxy(41, 7);
		printf("食物: (%d, %d)  ", fx, fy);//注意细节, 加空格是为了覆盖
	}
}

void Menu() {
                                //开始界面
	gotoxy(0, 0);
	puts("****************************************");
	puts("*              ________                *");
	puts("*              --------                *");
	puts("*            //        \\\\              *");
	puts("*          //      @     \\\\            *");
	puts("*        //     ______     \\\\          *");
	puts("*               ------                 *");
	puts("*                    //                *");
	puts("*                   //                 *");
	puts("*                  //                  *");
	puts("*           ________________           *");
	puts("*           ----------------           *");
	puts("*          ||              ||          *");
	puts("*          ||      ||      ||          *");
	puts("*          ||      ||      ||          *");
	puts("*                //  \\\\                *");
	puts("*              //      \\\\              *");
	puts("*            //          \\\\            *");
	puts("*                                      *");
	puts("****************************************");
	Sleep(2000);                        //显示2秒
}

int main() {
     
	HideCursor();                       //隐藏光标
	Menu();                             //打印开始界面
	Wall();                             //打印墙体
	head = Create();
	gotoxy(fx, fy);                     //打印第一个食物
	printf("$");
	char ch;
	while (1) {
                               //有按键改变方向
		ch = (char)getch();
		while(!kbhit()) {
                 	//无按键向指定方向移动
			switch(ch) {
     
				case 'a': {
                  //向左
					--x;
					break;
				}
				case 'd': {
                  //向右
					++x;
					break;
				}
				case 'w': {
                  //向上
					--y;
					break;
				}
				case 's': {
                  //向下
					++y;
					break;
				}
				default: {
     
					break;
				}
			}
			FoodEat();                  //是否吃到食物
			WallDeath();            	//是否撞墙; 可替换为wallPass(x, y);
			Insert();                   //录入数据
			Print();                    //打印蛇身
			Sleep(speed);               //延迟; 与速度有关
		}
	}

	return 0;
}

希望各位看望之后给个免费的红心加关注, 之后我还会继续分享的>-<

你可能感兴趣的:(贪吃蛇,链表,自动2004郝金辉,其他)