c写的贪吃蛇

vs 2017下,编写的程序,一个pch.h头文件,这个是项目开始就自带的。一个pch.cpp和snake.cpp。

snake.cpp代码如下:

// snake.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include"pch.h"
#include<time.h>
int main()
{
	startgame();
	return 0;
}

pch.cpp,代码如下:

#include "pch.h"
#include<windows.h>
#include<conio.h>
#include<time.h>
void startgame() {
	//欢迎
	welcome();
	//打印地图
	printfmap();
	//初始化蛇
	initsnake();
	//移动并控制方向
	move_controldirection();
}
void welcome() {
	printf("\n\n\n\n\n\n\n\n\n");
	printf("\t\t\t\t\t\t欢迎来到贪吃蛇游戏");
	printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
	printf("\t\t\t\t\t\t");
	system("pause");   //暂停
	system("cls");     //清屏
	printf("\n\n\n\n\n\n\n\n\n\n");
	printf("\t\t\t\t\t     用↑.↓.←.→分别控制蛇的移动.\n");
	printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t");
	system("pause");
	system("cls");
}
void printfmap() {
	for (int i = 0; i < 60; i += 2) //这里为什么加2呢,因为这个方块呢是unicode字符集,占两个字节,所以加2
	{
		setcursorpos(i, 0);
		printf("■");
		setcursorpos(i, 29);
		printf("■");
	}
	for (int i = 1; i < 30; i++)
	{
		setcursorpos(0, i);
		printf("■");
		setcursorpos(58, i);
		printf("■");
	}
}
//可以调节光标出现的位置
void setcursorpos(int x, int y) {
	HANDLE a = GetStdHandle(STD_OUTPUT_HANDLE);  //获得我们现在这个控制台窗口的句柄
	COORD b = { x,y };
	SetConsoleCursorPosition(a, b);
}
void initsnake() {
	setcursorpos(22, 10);
	printf("■");	
}//打印蛇
void printfsnake(snake* a) {
	snake* b = a;
	while (a!= NULL) {
		setcursorpos(a->x, a->y);
		printf("■");
		a = a->next;
	}
	///隐藏光标
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);
	CursorInfo.bVisible = false;
	SetConsoleCursorInfo(handle, &CursorInfo);
}
void overgame() {
	system("cls");
	printf("\n\n\n\n\n\n\n\n\n");
	printf("\t\t\t\t\t\t    游戏结束");
	printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
	printf("\t\t\t\t\t\t");
	system("pause");   
	
}
//判断是否有键盘敲击并且判断是否碰触边界
void kbhit(const snake* b,char& ch) {
	if (b->x == 0 || b->x == 58 || b->y == 0 || b->y == 29) {
		overgame();
	}
	if (_kbhit()) {
		ch = _getch();
	}
	
}
//随机产生食物
food random_produce_food() {
	food b;
	srand((unsigned int)time(NULL));
	b.x = rand() % 56+2;
	b.y = rand() % 28+1;
	return b;
}
//显示相应数据信息
void printfdata() {
	setcursorpos(80, 10);
	printf("have ate food number:%d", eat_food_number);
	setcursorpos(80, 11);
	printf("snake length is:%d", eat_food_number + 1);
	setcursorpos(80, 12);
	printf("spend time:%d s", clock()/1000);
}


void judegeeatfood_increasesnake(snake* b, food& c, char& ch, snake& a) {
	//判断是否吃到了食物
	if (((b->x) == (c.x) || (b->x) == (c.x - 1)) && (b->y) == (c.y)) {
		++eat_food_number;
		printfdata();
		//蛇身子变长一
		snake* y = (snake*)malloc(sizeof(snake));//不然的话,出了这个if之后空间就没了
		y->next = NULL;
		//1.只有一个蛇节点时
		if (b->next == NULL) {
			b->next = y;
			y->front = b;
			switch (ch) {
			case 'w': {
				y->x = b->x;
				y->y = b->y + 1;
				break;
			}
			case 's': {
				y->x = b->x;
				y->y = b->y - 1;
				break;
			}
			case 'a': {
				y->x = b->x + 2;
				y->y = b->y;
				break;
			}
			case 'd': {
				y->x = b->x - 2;
				y->y = b->y;
				break;
			}
			}
		}
		//2.超过一个蛇的节点时
		else {
			while (b->next->next != NULL) {
				b = b->next;
			}
			snake* z = b->next;
		    z->next = y;         //将新节点绑到最后
			y->front = z;
			if ((b->x) < (z->x) && (b->y) == (z->y)) {
				y->x = z->x + 2;
				y->y = z->y;
			}
			else if ((b->x) > (z->x) && (b->y) == (z->y)) {
				y->x = z->x - 2;
				y->y = z->y;
			}
			else if ((b->x) == (z->x) && (b->y) > (z->y)) {
				y->x = z->x;
				y->y = z->y - 1;
			}
			else {
				y->x = z->x;
				y->y = z->y + 1;
			}
			b = &a;
		}
		//重现刷新食物
		c = random_produce_food();
		setcursorpos(c.x, c.y);
		printf("*");
	}
}


void move_controldirection() {
	//产生蛇头
	snake a;
	a.x = 22;
	a.y = 10;
	a.next = NULL;
	a.front = NULL;
	snake* b = &a;
	//显示初始信息
	setcursorpos(80, 10);
	printf("have ate food number:0");
	setcursorpos(80, 11);
	printf("snake length is:1");
	setcursorpos(80, 12);
	printf("spend time:%d s", clock() / 1000);
	//最开始的食物
	food c;
	c = random_produce_food();
	setcursorpos(c.x, c.y);
	printf("*");
	//用来接受用户键盘敲击,默认向右移动
	char ch = 'd';
	while (1) {
		Sleep(250);
		//判断是否有键盘输入
		kbhit(b, ch);
		//判断是否吃到了食物
		judegeeatfood_increasesnake(b, c, ch, a);
		//这里每次循环打印一遍food是因为如果蛇正好在食物的位置,food会被覆盖,显示不出来的
		setcursorpos(c.x, c.y);
		printf("*");

		switch (ch) {
		case 'd':
		{//清掉最后一个的显示
			while (b->next != NULL) { b = b->next; }
			setcursorpos(b->x, b->y);
			printf(" ");

			//开始时的定向移动
			snake* g = b;
			while (g->front != NULL) {
				g->x = g->front->x;
				g->y = g->front->y;
				g = g->front;
			}
			b = &a;
			(b->x) += 2;
			printfsnake(b);
			break;
		}
		case 'w': {
			while (b->next != NULL) { b = b->next; }
			setcursorpos(b->x, b->y);
			printf(" ");
			//开始时的定向移动
			snake* g = b;
			while (g->front != NULL) {
				g->x = g->front->x;
				g->y = g->front->y;
				g = g->front;
			}
			b = &a;
			--(b->y);
			printfsnake(b);
			break;
		}
		case 'a': {
			while (b->next != NULL) { b = b->next; }
			setcursorpos(b->x, b->y);
			printf(" ");
			//开始时的定向移动
			snake* g = b;
			while (g->front != NULL) {
				g->x = g->front->x;
				g->y = g->front->y;
				g = g->front;
			}
				b = &a;
				(b->x) -= 2;
				printfsnake(b);
				break;
			
		}
		case 's': {
			while (b->next != NULL) { b = b->next; }
			setcursorpos(b->x, b->y);
			printf(" ");
			//开始时的定向移动
			snake* g = b;
			while (g->front != NULL) {
				g->x = g->front->x;
				g->y = g->front->y;
				g = g->front;
			}
			b = &a;
			++(b->y);
			printfsnake(b);
			break;
		}
		default:
			break;


		}
		}
	}

 

pch.h头文件中的代码如下:

#ifndef PCH_H
#define PCH_H

#include<stdio.h>
#include<windows.h>
//定义蛇的节点
typedef struct _snake {
	int x;
	int y;
	struct _snake *next;
	struct _snake* front;

}snake;
struct food {
	int x;
	int y;
};
int eat_food_number = 0;
void startgame();
void welcome();
void printfmap();
void setcursorpos(int x, int y);
void initsnake();
void move_controldirection();
void printfsnake(struct _snake*);
void overgame();
void kbhit(const struct _snake*,char&);
food random_produce_food();
void judegeeatfood_increasesnake(snake* b, food& c, char& ch, snake& a);
void printfdata();
#endif //PCH_H

写的稍微有点乱,不过慢慢看还是可以看懂得。里面涉及到了一些 Windows API函数,看不懂可以去百度。然后,就是关于蛇身子链表的设计了,其他的都没有什么东西。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值