利用数组编写贪吃蛇小程序

博主原本打算使用链表实现贪吃蛇游戏,但转而采用数组来表示坐标进行编写。文中提到游戏存在一个BUG,即蛇碰到自身不会导致游戏结束,作者欢迎读者反馈并协助解决此问题。
摘要由CSDN通过智能技术生成

 本来是想用链表编写的,但是自己没想好怎么表示位置

所以后来发现可以用数组来表示坐标,就重新用数组来编写了一遍

就是其中有个BUG(蛇碰到自己不会结束游戏)不懂有没有改好,因为当时觉得很有意思

如果发现没有改好自己不会改的可以联系原作者

以下就是我第一篇博客的内容了

 

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<Windows.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
void gotoxy(int x, int y);
void start();                    //开始页面
void T();
void Map();                      //地图边框
void move();                     //移动
void Printf(int x, int y);       //输出■
void Bodyprintf();               //输出蛇身
void first();                    //初始化蛇身
void Deleted(int x, int y);                   //删除蛇身
void turn(char direct);                       //蛇的转向
void food();                     //食物的出现
bool eat();                       //食物的吃
void Bodyadd();                   //身体的增加
void play();                      //游戏进行
void end();                       //游戏结束
void speed();                     //控制蛇移动的速度
typedef struct
{
	int x;
	int y;
}Body;
Body SNAKE[1000];
int lenth = 4;                   //定义基本长度
int score = 0;                   //定义初始分数
int food_x;
int food_y;


int main()
{
	start();
	system("CLS");
	Map();
	first();
	play();
	end();
}

//定位
void gotoxy(int x,int y)
{
	COORD coord;                //坐标结构体
	coord.X = x;
	coord.Y = y;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//从控制台获取句柄
	SetConsoleCursorPosition(handle, coord);//输出位置
}

void Map()
{
	int i, j;
	for (i = 0; i <= 60; i +=2)                     //打印上下边框
	{
		gotoxy(i, 0);
		printf("■");
		gotoxy(i, 26);
		printf("■");
	}
	for (j = 1; j < 26; j ++)                      //打印左右边框
	{
		gotoxy(0, j);
		printf("■");
		gotoxy(60, j);
		printf("■");
	}
}

void start()
{
	gotoxy(33, 15);
	printf("欢迎来到贪吃蛇世界!");
	_getch();
}

void Printf(int x, int y)
{
	gotoxy(x, y);
	printf("■");
}

void Bodyprintf()
{
	int i;
	for (i = 0; i < lenth; i++)
		Printf(SNAKE[i].x, SNAKE[i].y);
}

void first()
{
	memset(SNAKE, -1, sizeof(SNAKE));               //初始化蛇身数据
	SNAKE[0].x = 10;
	SNAKE[0].y = 6;
	SNAKE[1].x = 12;
	SNAKE[1].y = 6;
	SNAKE[2].x = 14;
	SNAKE[2].y = 6;
	SNAKE[3].x = 16;
	SNAKE[3].y = 6;
	Bodyprintf();
	food();
}

void Deleted(int x,int y)
{
	gotoxy(x, y);//用输出空格的方法来消除蛇身
	printf(" ");
	gotoxy(x + 1, y);
	printf(" ");
}

void move()
{
	int i,j;
	for (i = 0; i < lenth; i++)
	{
		Deleted(SNAKE[i].x, SNAKE[i].y);
	}
	Body newbody[1000];
	for (j = 0; j < lenth; j++)
	{
		newbody[j] = SNAKE[j];
	}
	int x = SNAKE[0].x - SNAKE[1].x;
	int y = SNAKE[0].y - SNAKE[1].y;
	if (x > 0)
	{
		SNAKE[0].x += 2;
		for (i = 0; i < lenth - 1; i++)
			SNAKE[i + 1] = newbody[i];//后一节出现在上一节的位置
	}
	if (x < 0)
	{
		SNAKE[0].x -= 2;
		for (i = 0; i < lenth - 1; i++)
			SNAKE[i + 1] = newbody[i];
	}
	if (y > 0)
	{
		SNAKE[0].y += 1;
		for (i = 0; i < lenth - 1; i++)
		{
			SNAKE[i + 1] = newbody[i];
		}
	}
	if (y < 0)
	{
		SNAKE[0].y -= 1;
		for (i = 0; i < lenth - 1; i++)
		{
			SNAKE[i + 1] = newbody[i];
		}
	}
	Bodyprintf();
	speed();
}
void turn(char direct)
{
	int i, j;
	for (i = 0; i < lenth; i++)
	{
		Deleted(SNAKE[i].x, SNAKE[i].y);
	}
	Body newbody[1000];
	for (j = 0; j < lenth; j++)
	{
		newbody[j] = SNAKE[j];
	}
	int x = SNAKE[0].x - SNAKE[1].x;
	int y = SNAKE[0].y - SNAKE[1].y;
	switch (direct)
	{
	case 'w':
	case 'W': 
	{
		if (y > 0 || y < 0)
			break;
		else 
		{
			SNAKE[0].y -= 1;
			for (i = 0; i < lenth; i++)
				SNAKE[i + 1] = newbody[i];//后一节出现在上一节的位置
			break;
		}
	}
	case 's':
	case 'S':
	{
		if (y > 0 || y < 0)
			break;
		else
		{
			SNAKE[0].y += 1;
			for (i = 0; i < lenth; i++)
				SNAKE[i + 1] = newbody[i];
			break;
		}
	}
	case 'a':
	case 'A':
	{
		if (x > 0 || x < 0)
			break;
		else
		{
			SNAKE[0].x -= 2;
			for (i = 0; i < lenth; i++)
				SNAKE[i + 1] = newbody[i];
			break;
		}
	}
	case 'd':
	case 'D':
	{
		if (x > 0 || x < 0)
			break;
		else
		{
			SNAKE[0].x += 2;
			for (i = 0; i < lenth; i++)
				SNAKE[i + 1] = newbody[i];
			break;
		}
	}
	case 'P':                                    //按p暂停
	case 'p':
	{
		gotoxy(63, 14);
		printf("按任意键继续.....");
		Bodyprintf();
		_getch();
		break;
	}
	}
	Bodyprintf();
}

void food()
{
A:	srand((int)time(NULL));
	food_x = rand() % (58-2) + 2;//给定范围产生新的坐标产生食物
	food_y = rand() % (26-1) + 1;
	if (food_x % 2 != 0)
		food_x++;
	for (int i = 0; i < lenth; i++)
		if (food_x == SNAKE[i].x && food_y == SNAKE[i].y)//如果随机坐标在蛇身上就重新产生
			goto A;
	gotoxy(food_x, food_y);
	printf("▲");
}

bool eat()
{
	int result;
	if (food_x == SNAKE[0].x && food_y == SNAKE[0].y)
		result = false;
	else result = true;
	return(result);
}

void Bodyadd()
{
	int x = SNAKE[lenth - 1].x - SNAKE[lenth - 2].x;//判定最后一节在倒数第二节的哪个方向,在那个方向上添加新的节点
	int y = SNAKE[lenth - 1].y - SNAKE[lenth - 2].y;
	if (x > 0)
	{
		SNAKE[lenth].x = SNAKE[lenth - 1].x + 2;
		SNAKE[lenth].y = SNAKE[lenth].y;
	}
	if (x < 0)
	{
		SNAKE[lenth].x = SNAKE[lenth - 1].x - 2;
		SNAKE[lenth].y = SNAKE[lenth - 1].y;
	}
	if (y > 0)
	{
		SNAKE[lenth].x = SNAKE[lenth - 1].x;
		SNAKE[lenth].y = SNAKE[lenth - 1].y + 1;
	}
	if (y < 0)
	{
		SNAKE[lenth].x = SNAKE[lenth - 1].x;
		SNAKE[lenth].y = SNAKE[lenth - 1].y - 1;
	}
	lenth++;
	Bodyprintf();
}

void T()
{
	gotoxy(63, 5);
	printf("分数:%d", score);
	gotoxy(63, 15);
	printf("W,S,A,D分别控制蛇上下左右移动,按P暂停");
}

void end()
{
	system("CLS");
	gotoxy(55, 15);
	printf("您本局的得分为:%d\n", score);
}

void play()
{
	for (;;)
	{
		if (SNAKE[0].x <= 0 || SNAKE[0].x >= 60 || SNAKE[0].y <= 0 || SNAKE[0].y >= 26)//如果蛇碰界就结束游戏
			break;
		T();
		if (_kbhit())
		{
			char direct = _getch();
			turn(direct);
		}
		else
		{
			move();
		}
		if (eat() == false)
		{
			Deleted(food_x, food_y);
			Bodyadd();
			food();
			score += 10;
		}
	}
}

void speed()
{
	if (score > 600)
	{
		Sleep(50);
	}
	else if (score > 500)
	{
		Sleep(100);
	}
	else if (score > 400)
	{
		Sleep(150);
	}
	else if (score > 300)
	{
		Sleep(200);
	}
	else if (score > 200)
	{
		Sleep(250);
	}
	else
	{
		Sleep(300);
	}
}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值