c语言贪吃蛇小游戏的简易实现

命令行界面通过打印字符实现了贪吃蛇游戏的基本功能    

代码仅130行

实现原理为,采用链式单调数列在矩阵地图中储存为蛇的坐标信息。

//贪吃蛇的实现原理在于,将蛇在矩阵中的点表示为正数,并且由蛇尾到蛇头是有向的,从1逐个递增的数列。
//每次移动时,将蛇头下一格的数据填入当前蛇头的数据+1,再使得地图矩阵的所有正数-1,即可实现整体蛇的移动。 如(01234500 -》 01234560 -》00123450)
//若吃到食物,则不执行整体-1,即可实现长度+1;
//移动例子   如  0 1 2 3 4 5 0 0     -》 
//              0 1 2 3 4 5 6 0     -》  (若吃到食物,执行到这一步结束就是蛇的边长。)
//              0 0 1 2 3 4 5 0 

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#define M 20        //可调节地图的宽高
#define N 40
#define SL 5
int G=1;
int l=SL;
int boundary_x,boundary_y;
int frame[M][N]={0};
int turn=4; 
void initialization()
{
	boundary_x=M;
	boundary_y=N;
}
void refresh()
{
	int i,j;
	system("cls");
	for(i=0;i<M;i++)
		{for(j=0;j<N;j++)
		if(frame[i][j]==-1) printf("*");
		else if(frame[i][j]==0) printf(" ");
		else if(frame[i][j]==1) printf("@");
		else if(frame[i][j]>1) printf("#"); 
		else if(frame[i][j]==-2) printf("X"); 
		//printf("%3d",frame[i][j]);
		printf("\n");
		}
	printf("得分:%d",l-SL);
}
void withinput()
{
	int i,j;
	char c;
	if(kbhit())
	{
		c=getch();
	if(turn!=3&&(c=='w'||c=='W')) turn=1;
	else if(turn!=4&&(c=='a'||c=='A')) turn=2;
	else if(turn!=1&&(c=='s'||c=='S')) turn=3;
	else if(turn!=2&&(c=='d'||c=='D')) turn=4;  
	}
}
void withoutinput()
{
	int i,j,p=0;
	int x=-1,y=-1;
	for(i=0;i<M;i++)
		for(j=0;j<N;j++)
		{	
			if(frame[i][j]>0)		//蛇身整体++ 
		frame[i][j]++;
			
		}
	for(i=0;i<M;i++)
		for(j=0;j<N;j++)
		{if(frame[i][j]==2)
			{
				if(turn==2) {if(frame[i][j-1]==0||frame[i][j-1]==-2) frame[i][j-1]=1;
							else if(frame[i][j-1]>0||frame[i][j-1]==-2) G=0;
							else if(frame[i][j-1]==-1) frame[i][N-2]=1;}
				else if(turn==4){if(frame[i][j+1]==0||frame[i][j+1]==-2) frame[i][j+1]=1;
							else if(frame[i][j+1]>0||frame[i][j+1]==-2) G=0;
							else if(frame[i][j+1]==-1) frame[i][1]=1;}
				else if(turn==1){if(frame[i-1][j]==0||frame[i-1][j]==-2) frame[i-1][j]=1;
							else if(frame[i-1][j]>0||frame[i-1][j]==-2) G=0;
							else if(frame[i-1][j]==-1) frame[M-2][j]=1;}
				else if(turn==3){if(frame[i+1][j]==0||frame[i+1][j]==-2) frame[i+1][j]=1;
							else if(frame[i+1][j]>0||frame[i+1][j]==-2) G=0;
							else if(frame[i+1][j]==-1) frame[1][j]=1;}
			}
		}
	for(i=0;i<M;i++)      
		for(j=0;j<N;j++){ 
			if(frame[i][j]==l+1)				//除尾操作 
				frame[i][j]=0;
			if(frame[i][j]==-2)				//判断场上是否存在目标 
			p=1;                     //p=1为判断存在 
		}
		
	if(p==0)      //取模随机生成; 
	{
		l++;
		do{
		x=rand()%(M-2)+1;
		y=rand()%(N-2)+1;
		if(frame[x][y]==0)
		frame[x][y]=-2;
		}
		while(frame[x][y]!=-2);
	}
	if(G==0)
	exit(0);
}
int main()
{
	int x,y;
	int i,j;
	i=M/2;
	for(j=M/2;j<M/2+SL;j++)
	frame[i][j]=M/2+SL-j;
	x=rand()%(M-2)+1;
		y=rand()%(N-2)+1;
		frame[x][y]=-2;
	for(i=0;i<M;i++)
		{for(j=0;j<N;j++)
		if(i==0||i==M-1||j==0||j==N-1)
		frame[i][j]=-1;}
		while(1)
		{	
			refresh();
			withinput();
			withoutinput();
			Sleep(50);
	 }
}

运行截图:

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CJds_snakeView类 Struct list { int x; int y; }; 点结构,x表示横坐标,y表示纵坐标。 成员变量: int start;start=1开始游戏,start=0停止游戏。 int difficulty;表示游戏难度,等于10表示容易,等于6表示普通,等于3表示困难,等于2表示特困。 int last_aspect;表示蛇之前前进的方向,用于判断防止蛇逆行的。 int can_new;表示是否添加新食物。等于1表示产生新的食物,等于0表示产生之后不不要再产生食物。 int count;表示蛇的节数; CRect rct;表示矩形方格; list a[100];保存蛇的长度; list b;用来保存蛇头的坐标位置; int aspect;表示蛇前进的方向 等于0表示蛇向右前进; 等于1表示蛇向下前进; 等于2表示蛇向左前进; 等于3表示蛇向上前进; int xx;表示食物的x坐标; int yy;表示食物的y坐标; 成员函数: void Init();初始化蛇的节数,并确定了节数的坐标位置。首先初始化蛇的前进方向aspect=0是向右前进的,last_aspect=0用来保存蛇当前前进的方向。并且初始化蛇的节数为4节,并指明了它们的坐标位置。can_new=1表示产生一个新的食物。 void aliveordie();判断蛇是死还是活着。有两种情况,一种是蛇自己撞到自己,表示死了,start=0从新开始游戏,另一种是超出了界面(20,20,420,420)撞到了墙start=0也从新开始游戏。 double random(double start,double end);在start和end坐标之间产生随即数; 消息处理事件: (1)void onTimer(UINT nIDEvent);在OnCreate()创建计时器SetTimer(),来触发OnTimer事件,所以要首先销毁时间计时器,然后调用aliveordie()函数判断蛇的生死情况,CString str_count; str_count.Format("分数:%d",count-4)显示蛇的节数,TextOut()指出坐标输出文本,创建设备上下文,和创建位图。然后把位图选择到设备上下文上,填充颜色为白色。 在位图上绘制两个矩形线框: Rectangle(CRect(10,10,440,440)); Rectangle(CRect(20,20,430,430)); 显示位图(BitBlt(0,0,1000,1000,&MenDC,0,0,SRCCOPY)); 判断如果游戏开始(start==1),b.x=a[0].x用b.x来保存蛇头的横坐标;b.y=a[0].y用b.y来保存蛇头的纵坐标。如果aspect==0表示蛇向右前进,aspect=1表示蛇向下前进,aspect==2表示蛇向左前进,aspect==3表示蛇向上前进,a[1].x=b.x;a[1].y=b.y;把蛇头的坐标付给了a[1],说明蛇头改变了前进的方向。绘制蛇头矩形方格,并且设置蛇头的颜色为红色,蛇身是三个黄色的矩形方格。if (a[0].x==xx && a[0].y==yy)判断蛇头的位置与食物的关系,现在的情况说明蛇吃了食物,蛇的节数加一,各个节数的坐标向前进一位。调用random()函数产生随即的食物,然后判断食物随即产生的位置与蛇的位置,如果产生的食物在蛇身体上,要从新调用random()函数随即再产生食物。产生的食物颜色为绿色。int m_timer=SetTimer(1,difficulty*30,NULL);计时间隔,计时间隔的快慢是根据难易程度的不而确定的。销毁位图、销毁设备上下文。 (2)OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);判断蛇当前前进的方向,当aspect返回0,表示蛇前进的方向是向右,当aspect返回1,表示蛇前进的方向是下,当aspect返回2,表示蛇前进的方向是向左,当aspect返回3,表示蛇前进的方向是向上。 (3)点击菜单按钮调用以下函数: OnDifficultyEasy();OnDifficultyHard();OnDifficultyNormal();OnDifficultyVeryhard();OnButtonStart();

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值