简易版贪吃蛇

分析:

想要写出贪吃蛇,就要知道里面的规则,规则很简单就是移动的蛇吃到食物蛇身增加1,撞到墙或撞到自己(也可以设置成可以通过蛇身)失败。

1.首先要在屏幕上显示蛇框,蛇框中包含蛇身、果实,代码如下(这里是使用颜色显示):

void map(int maps[20][20], int looks[4], int move[20][20])
{
	int i;
	int j;
	int x;
	int y;
	for(i = 0; i <= 16; i++)
	{
		for(j = 0; j <= 16; j++)
		{
			if(i == 0 || i == 16 || j == 0 || j == 16)
			{
				maps[i][j] = 1;
			}else
			{
				maps[i][j] = 0;
			}
			move[i][j] = 0;
		}
		
	}
	maps[8][8] = 3;
	move[8][8] = 1;
	move[0][0] = 1;
	x = rand() % 15 + 1;//范围是1-15
	y = rand() % 15 + 1;
	maps[x][y] = 2;//有果实
	looks[0] = 1;//表示朝向,向上
	looks[1] = 1;//长度
	looks[2] = 0;//分数 
	looks[3] = 0;//1失败 
	for(i = 0; i <= 16; i++)
	{
		for(j = 0; j <= 16; j++)
		{
			gotoxy(i * 2, j);
		switch (maps[i][j]) {
			case 0:
				BackGround(0, 0);
				break;//如果没有东西打印黑色
			case 1:
				BackGround(0, 1);
				break;//墙打印蓝色
			case 2:
				BackGround(0, 2);
				break;//果实打印绿色
			case 3:
				BackGround(0, 3);
				break;//蛇打印湖蓝色
			default:
				break;
			}
			printf("  ");
		}
	}
	gotoxy(35, 0);
	BackGround(7, 0);
}

其中已经包含初始化,不使用颜色来显示是可以的,只需要将有关颜色部分换成你设定的东西。0黑色  1蓝色 2 绿色 3湖蓝色

这里要强调一下:上面的look[4]数组,其中的元素实际上是状态,比如look[3] = 0,0就表示成功,当在这种状态时会执行相应的事件,第一次写的时候使用的是标记,但这种写法有点混乱,使用状态的写法让代码更简便。

2.规则和移动,代码如下:

void rule(int maps[20][20], int looks[4], int xy[2], int move[20][20])
{
	int ctr;
	int x;
	int y;
	int i;
	int j;
	x = y = 0;
	if(kbhit())
	{
		ctr = getch();
		if(ctr == 224)	
		{
		ctr = getch();
		} 
		if(ctr == 72 && looks[0] != 2)
		{
			looks[0] = 1;
		}
		if(ctr == 80 && looks[0] != 1)
		{
			looks[0] = 2;
		}
		if(ctr == 75 && looks[0] != 4)
		{
			looks[0] = 3;
		}
		if(ctr == 77 && looks[0] != 3)
		{
			looks[0] = 4;
		}
	}
	switch(looks[0])
	{
	case 1:
		xy[1]--;
		break;
	case 2:
		xy[1]++;
		break;
	case 3:
		xy[0]--;
		break;
	case 4:
		xy[0]++;
		break;
    }
    move[0][0]++;
    move[xy[0]][xy[1]] = move[0][0];
   	gotoxy(35, 2);
	BackGround(7, 0);
	gotoxy(xy[0] * 2, xy[1]);//这里蛇头就往前移动了
	BackGround(0, 3);//与蛇体一个颜色
	printf("  ");
	if(maps[xy[0]][xy[1]] == 2)
	{
		looks[2]++;
		looks[1]++;
		gotoxy(35, 0);
		BackGround(7, 0);
		printf("现在得分是:%d", looks[2]);
		while (maps[x][y] != 0) {
			x = rand() % 15 + 1;
			y = rand() % 15 + 1;
		}
		maps[x][y] = 2;//将这个地方变为果实
		gotoxy(x * 2, y);
		BackGround(0, 2);
		printf("  ");
	}
	if(maps[xy[0]][xy[1]] == 1 || maps[xy[0]][xy[1]] == 3)
	{
		looks[3] = 1;
		gotoxy(0, 24);
		BackGround(7, 0);
		printf("游戏结束,最后得分:%d", looks[2]);
		return;
	}
	maps[xy[0]][xy[1]] = 3;
	for(i = 0;i <= 16; i++)
	{
	for ( j = 0; j <= 16; j++) 
	{
	if (move[i][j] == move[xy[0]][xy[1]] - looks[1])
	{
		maps[i][j] = 0;
		gotoxy(i * 2, j);
		BackGround(0, 0);
		printf("  ");
		gotoxy(47,0);
		break;
	}
}
}
}

这里需要注意,方向键的ASCLL值:上72,左75,右77,下80,1表示状态上,2表示状态下,3表示状态左,4表示状态右。

xy[1]表示行坐标,xy[0]表示列坐标,这里的i*2是在屏幕上打印一个矩形的颜色,maps[20][20]表示地图信息,move[20][20]表示蛇移动的信息,蛇移动一次,其中move[0][0]步数就加1,并把步数赋给当前的蛇头,以便判断蛇为,蛇尾的判断方法是用步数减蛇身。

3.逻辑规则(代码如下):

int main()
{
	int maps[20][20];
	int looks[4];
	int move[20][20];
	int xy[2];
	int i;
	int j;
	xy[0] = xy[1] = 8;
	srand((unsigned) time(NULL));
	system("pause");
	map(maps, looks, move);
    while(looks[3] == 0)
    {
    	Sleep(300); 
    	rule(maps, looks, xy, move);
	}
	system("pause");
	gotoxy(0,25);
	printf("游戏结束,任意键退出!");
	return 0;
}

look[3]中保存的就是失败和成功的状态。

总结:写贪吃蛇,首先要知道其规则,接下来分析,将问题拆分,每个问题采用合适的方法解决,我这种方式只是一种,还会有更简练的算法。

全部代码:

#include <stdio.h>
#include <windows.h> 
#include <time.h>
#include <conio.h>
#include <stdlib.h>
//方向键的ASCLL值:上72,左75,右77,下80
//背景颜色的代码: 0=黑色  1蓝色 2 绿色 3湖蓝色 7白色 
void BackGround(unsigned int ForeColor , unsigned int BackGroundColor );
void BackGround(unsigned int ForeColor , unsigned int BackGroundColor ) {

	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);  //获取控制台的句柄

	SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色

}
void gotoxy(int x, int y);
void gotoxy(int x, int y)
{
	HANDLE handle;
	COORD coord;
	coord.X = x;
	coord.Y = y;
	handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(handle, coord);
}
void map(int maps[20][20], int looks[4], int move[20][20]);
void rule(int maps[20][20], int looks[4], int xy[2], int move[20][20]);
void map(int maps[20][20], int looks[4], int move[20][20])
{
	int i;
	int j;
	int x;
	int y;
	for(i = 0; i <= 16; i++)
	{
		for(j = 0; j <= 16; j++)
		{
			if(i == 0 || i == 16 || j == 0 || j == 16)
			{
				maps[i][j] = 1;
			}else
			{
				maps[i][j] = 0;
			}
			move[i][j] = 0;
		}
		
	}
	maps[8][8] = 3;
	move[8][8] = 1;
	move[0][0] = 1;
	x = rand() % 15 + 1;//范围是1-15
	y = rand() % 15 + 1;
	maps[x][y] = 2;//有果实
	looks[0] = 1;//表示朝向,向上
	looks[1] = 1;//长度
	looks[2] = 0;//分数 
	looks[3] = 0;//1失败 
	for(i = 0; i <= 16; i++)
	{
		for(j = 0; j <= 16; j++)
		{
			gotoxy(i * 2, j);
		switch (maps[i][j]) {
			case 0:
				BackGround(0, 0);
				break;//如果没有东西打印黑色
			case 1:
				BackGround(0, 1);
				break;//墙打印蓝色
			case 2:
				BackGround(0, 2);
				break;//果实打印绿色
			case 3:
				BackGround(0, 3);
				break;//蛇打印湖蓝色
			default:
				break;
			}
			printf("  ");//地图中直接就是涂空格符
		}
	}
	gotoxy(35, 0);
	BackGround(7, 0);
}
void rule(int maps[20][20], int looks[4], int xy[2], int move[20][20])
{
	int ctr;
	int x;
	int y;
	int i;
	int j;
	x = y = 0;
	if(kbhit())
	{
		ctr = getch();
		if(ctr == 224)	
		{
		ctr = getch();
		} 
		if(ctr == 72 && looks[0] != 2)
		{
			looks[0] = 1;
		}
		if(ctr == 80 && looks[0] != 1)
		{
			looks[0] = 2;
		}
		if(ctr == 75 && looks[0] != 4)
		{
			looks[0] = 3;
		}
		if(ctr == 77 && looks[0] != 3)
		{
			looks[0] = 4;
		}
	}
	switch(looks[0])
	{
	case 1:
		xy[1]--;
		break;
	case 2:
		xy[1]++;
		break;
	case 3:
		xy[0]--;
		break;
	case 4:
		xy[0]++;
		break;
    }
    move[0][0]++;
    move[xy[0]][xy[1]] = move[0][0];
   	gotoxy(35, 2);
	BackGround(7, 0);
	gotoxy(xy[0] * 2, xy[1]);//这里蛇头就往前移动了
	BackGround(0, 3);//与蛇体一个颜色
	printf("  ");
	if(maps[xy[0]][xy[1]] == 2)
	{
		looks[2]++;
		looks[1]++;
		gotoxy(35, 0);
		BackGround(7, 0);
		printf("现在得分是:%d", looks[2]);
		while (maps[x][y] != 0) {
			x = rand() % 15 + 1;
			y = rand() % 15 + 1;
		}
		maps[x][y] = 2;//将这个地方变为果实
		gotoxy(x * 2, y);
		BackGround(0, 2);
		printf("  ");
	}
	if(maps[xy[0]][xy[1]] == 1 || maps[xy[0]][xy[1]] == 3)
	{
		looks[3] = 1;
		gotoxy(0, 24);
		BackGround(7, 0);
		printf("你输了,最后得分:%d", looks[2]);
		return;
	}
	maps[xy[0]][xy[1]] = 3;
	for(i = 0;i <= 16; i++)
	{
	for ( j = 0; j <= 16; j++) 
	{
	if (move[i][j] == move[xy[0]][xy[1]] - looks[1])
	{
		maps[i][j] = 0;
		gotoxy(i * 2, j);
		BackGround(0, 0);
		printf("  ");
		gotoxy(47,0);
		break;
	}
}
}
} 
int main()
{
	int maps[20][20];
	int looks[4];
	int move[20][20];
	int xy[2];
	int i;
	int j;
	xy[0] = xy[1] = 8;
	srand((unsigned) time(NULL));
	system("pause");
	map(maps, looks, move);
    while(looks[3] == 0)
    {
    	Sleep(300); 
    	rule(maps, looks, xy, move);
	}
	system("pause");
	gotoxy(0,25);
	printf("游戏结束,按任意键退出!");
	return 0;
}

其中使用光标定位和背景颜色函数,这2个函数也是参考别人的,这里就不做讲解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值