c语言贪吃蛇

这周的实训作业,记录一下~

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include<time.h>
/* 游戏画面尺寸*/
#define High 20  
#define Width 30
/*全局变量*/
int canvas[High][Width] = { 0 }; // 二维数组存储游戏画布中对应的元素,0为空格,-1为边框#,-2为食物,1为蛇头@,大于1的正数为蛇身 *
char move_direction;
int count = 0;
int food_x, food_y;
int score;
int speed;
/*函数声明*/
void startup();
void show();
void updateWithoutInput();
void updateWithInput();
void gotoxy(int x, int y);
void HideCursor();
void moveSnakeByDirection();
void new_food();
void main()
{
	HideCursor();//隐藏光标
	srand(time(NULL));
	startup();   //数据的初始化
	while (1)     //游戏循环执行
	{
		show();  //显示画面
		updateWithoutInput();  //与用户输入无关的更新
		updateWithInput(); //与用户输入有关的更新
	}
}
/*游戏初始化*/
void startup()
{
	//设定边界
	for (int i = 0; i <= Width - 1; i++)
	{
		canvas[0][i] = -1;
		canvas[High - 1][i] = -1;
	}
	for (int i = 0; i <= High - 1; i++)
	{
		canvas[i][0] = -1;
		canvas[i][Width - 1] = -1;
	}
	//设定小蛇起始位置
	canvas[High / 2][Width / 2] = 1;
	for (int i = 1; i <= 2; i++)
		canvas[High / 2][Width / 2 - i] = i + 1;
	//规定初始状态下小蛇向右移动
	move_direction = 'd';
	//生成食物
	new_food();
	score = 0;
	speed = 25;
}
/*显示画面*/
void show()
{
	gotoxy(0, 0);
	for (int i = 0; i <= High - 1; i++)
	{
		for (int j = 0; j <= Width - 1; j++)
		{
			if (canvas[i][j] > 1)
				printf("*");
			if (canvas[i][j] == 1)
				printf("@");
			if (canvas[i][j] == 0)
				printf(" ");
			if (canvas[i][j] == -1)
				printf("#");
			if (canvas[i][j] == -2)
				printf("F");
		}
		printf("\n");
	}
	printf("得分:%d\n", score);
	printf("当前速度:%d\n", speed);
}
/*与用户输入无关的更新*/
void updateWithoutInput()
{
	if (count == speed)
	{
		moveSnakeByDirection();
		count = 0;
	}
	else
		count++;
}
/*与用户输入有关的更新*/
void updateWithInput()
{
	if (kbhit())
	{
		char input;
		input = getch();
		if (input == 'W' || input == 'w')
			move_direction = 'w';
		if (input == 'A' || input == 'a')
			move_direction = 'a';
		if (input == 'S' || input == 's')
			move_direction = 's';
		if (input == 'D' || input == 'd')
			move_direction = 'd';
	}
}
void moveSnakeByDirection()
{
	for (int i = 0; i <= High - 1; i++)
	{
		for (int j = 0; j <= Width - 1; j++)
		{
			if (canvas[i][j] > 0)
				canvas[i][j]++;
		}
	}
	int head_old_i = 0, head_old_j = 0, tail_old_i, tail_old_j, max = 0;
	for (int i = 1; i < High - 1; i++)
	{
		for (int j = 1; j < Width - 1; j++)
		{
			if (canvas[i][j] > 0)
			{
				//记录旧蛇头
				if (canvas[i][j] == 2)
				{
					head_old_i = i;
					head_old_j = j;
				}
				//记录旧蛇尾
				if (max < canvas[i][j])
				{
					max = canvas[i][j];
					tail_old_i = i;
					tail_old_j = j;
				}
			}
		}
	}
	//根据移动方向确定新蛇头位置
	int head_new_i, head_new_j;
	if (move_direction == 'w')
	{
		head_new_i = head_old_i - 1;
		head_new_j = head_old_j;
	}
	if (move_direction == 'a')
	{
		head_new_i = head_old_i;
		head_new_j = head_old_j - 1;
	}
	if (move_direction == 's')
	{
		head_new_i = head_old_i + 1;
		head_new_j = head_old_j;
	}
	if (move_direction == 'd')
	{
		head_new_i = head_old_i;
		head_new_j = head_old_j + 1;
	}
	//如果新蛇头吃到食物则保留旧蛇尾,否则裁剪掉
	if (canvas[head_new_i][head_new_j] == -2)
	{
		canvas[food_x][food_y] = 0;
		score++;
		new_food();
		if (score % 3 == 0 && score > 0)
			speed--;
	}
	else
		canvas[tail_old_i][tail_old_j] = 0;
	//若蛇头和墙体或自身相撞则结束游戏
	if (canvas[head_new_i][head_new_j] == -1)
	{
		printf("游戏结束!");
		exit(0);
	}
	else if (canvas[head_new_i][head_new_j] > 0)
	{
		printf("游戏结束!");
		exit(0);
	}
	else
		canvas[head_new_i][head_new_j] = 1;
}
void new_food()
{
loop:food_x = rand() % (High - 5) + 2;
	food_y = rand() % (Width - 5) + 2;
	//若食物位置和蛇身重合则重新生成
	if (canvas[food_x][food_y] > 0)
		goto loop;
	else
		canvas[food_x][food_y] = -2;
}
/* 光标移动到(x,y)位置*/
void gotoxy(int x, int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}
/*隐藏光标*/
void HideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };//第二个值为0表示隐藏光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值