基于控制台的C语言贪吃蛇项目

相信对很多人来说,学完C语言以后,都会找一些小程序来练练手。例如贪吃蛇、五子棋、俄罗斯方块等等。

今天给大家分享一个基于控制台的C语言贪吃蛇小程序。


基础知识要求:C语言基础。
知识点补充
这里写一些你可能没学到的知识点
  • system(“cls”):清屏函数
  • Sleep(300):等待函数,其中括号内的为毫秒。
  • _getch():获取一个键盘字符,不显示该字符就返回
  • kbhit():判断是否有键按下,是返回1,否返回0.

代码部分
  • 废话不多说,直接贴代码
#include <conio.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
struct node
{
	int x;
	int y;
	struct node *next;
};

node *init(int length);					//初始化蛇
void print(int a[15][30],node *head);	//输出函数
void food(node *head);					//食物产生函数
void move(node *head);					//移动函数
bool dead(node *head);					//判断死亡函数

int food_x=0,food_y=0;
int food_flag = 0;
int target = 2;


void main(){
	int a[15][30];
	node *head;
	head = init(2);
	while(1)
	{	
		system("cls");
		move(head);
		
		if(dead(head))
			break;
		print(a,head);
		Sleep(300);
	}
	system("cls");
	printf("Game Over!!!\n");
	
}
node *init(int length)
{
	int i = 2;
	node *head;
	head = (node*)malloc(sizeof(node));//分配地址
	node *p = head;
	head->x = 1;
	head->y = 1;
	while(i <= length)
	{
		node *s;
		s = (node*)malloc(sizeof(node));
		s->x = 1;
		s->y = i;
		s->next = NULL;
		p->next = s;
		p = p->next;
		i++;
	}
	food(head);
	return head;
}

void print(int a[15][30],node *head)
{
//0为空格,-1为墙壁#,1为蛇身*,2为蛇头@,3为食物$
	int i,j;
	node *p = head;
	for(i = 0; i < 15; i++)
	{
		for(j = 0; j < 30; j++)
		{
			if(i == 0 || j == 0 || i == 14 || j == 29)
				a[i][j] = -1;
			else
				a[i][j] = 0;
		}
	}
	while(p != NULL)
	{
		if(p->next == NULL)
			a[p->x][p->y] = 2;
		else
			a[p->x][p->y] = 1;
		p = p->next;
	}
	a[food_x][food_y] = 3;
	for(i = 0; i < 15; i++)
	{
		for(j = 0; j < 30; j++)
		{
			if(a[i][j] == -1)
				printf("#");
			if(a[i][j] == 0)
				printf(" ");
			if(a[i][j] == 1)
				printf("*");
			if(a[i][j] == 2)
				printf("@");
			if(a[i][j] == 3)
				printf("$");
		}
		printf("\n");
	}	
}

void food(node *head)
{
	node *p = head;
	srand((unsigned)time(NULL));
	food_x = rand()%12 + 1;
	food_y = rand()%27 + 1;
	while(p != NULL)
	{
		if(p->x == food_x && p->y == food_y)
		{
			food_x = rand()%12 + 1;
			food_y = rand()%27 + 1;
			p = head;
		}
		p = p->next;
	}
}

void move(node *head)
{

	char ch;
	if(kbhit())
	{
		ch = _getch();		//VS中getch()用_getch()代替。
		switch (ch)
		{
			case -32: 		 //上下左右占两个字节,低八位存ASCII码,高八位存按键扫描码
			ch = _getch(); //其中-32为我的电脑的按键扫描码
			switch (ch)
			{
				case 72:if(target != 1)target = 0; break;		//72为上的ASCII码
				case 80:if(target != 0)target = 1; break;		//80为下的ASCII码
				case 77:if(target != 3)target = 2; break;		//77为右的ASCII码
				case 75:if(target != 2)target = 3; break;		//75位左的ASCII码
				default:break;
			}
		}
	}
	node *p;
	node *q = head->next;
	while(q->next != NULL)
		q = q->next;
	switch(target)
	{
		case 0:if(q->x - 1 == food_x && q->y == food_y)food_flag = 1;break;
		case 1:if(q->x + 1 == food_x && q->y == food_y)food_flag = 1;break;
		case 2:if(q->x == food_x && q->y + 1 == food_y)food_flag = 1;break;
		case 3:if(q->x == food_x && q->y - 1 == food_y)food_flag = 1;break;
	}
	if(food_flag == 1)
	{
		node *s;
		s = (node*)malloc(sizeof(node));
		s->x = food_x;
		s->y = food_y;
		s->next = NULL;
		q->next = s;
		food(head);
		food_flag = 0;
	}
	else
	{
		p = head;
		q = head->next;
		while(q != NULL)
		{
			p->x = q->x;
			p->y = q->y;
			if(q->next == NULL)
			{
				switch(target)
				{
					case 0:q->x = q->x - 1;break;
					case 1:q->x = q->x + 1;break;
					case 2:q->y = q->y + 1;break;
					case 3:q->y = q->y - 1;break;
				}
			}
			p = p->next;
			q = q->next;
			
		}
	}	
}
bool dead(node *head)
{
	node *p = head;
	while(p->next != NULL)
		p = p->next;
	if(p->x >= 14 || p->x <= 0 || p->y >= 29 || p->y <= 0)
		return true;
	node *q = head;
	while(q->next != NULL)
	{
		if(q->x == p->x && q->y == p->y)
			return true;
		q = q->next;
	}
	return false;
}

以上就是全部内容。

下次再见!!!

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值