c语言控制台贪吃蛇

main.c

#include <stdio.h>
#include "snake.h"

char * s_gets(char *st, int n);

void start(snake *ps, food *pd, score *ft);	//开始游戏 
void open(FILE *pf,score *ps,score *pt);	// 打开记录文件 
void show(FILE *sp,score *ps);			//打印排行 
void Interface(void);	//游戏界面 
int number(void);		//游戏选项
int wasd = 'a';		//控制方向 
int flag = 1;		//控制食物生成 

int main(int argc, char *argv[]) {
	
	FILE *sp;			// 指向保存数据的二进制文本 
	int i;
	snake snakes; //蛇 分数 
	score scores[SCORE];	//记录分数,姓名
	score ft; 				//单局的分数,姓名 
	food pd;		//食物
	
	srand((unsigned int) time(0));
	
	Interface();//游戏界面 
	i = number();//游戏选项 
	while(i != '3')
	{
		switch(i)
		{
			case '1':
				start(&snakes,&pd,&ft);		//开始游戏 
				open(sp,scores,&ft);		//记录分数 
			break;
			case '2':
				show(sp,scores);			//查看记录的分数 
			break;
		}
		
		Interface();//游戏界面 
		i = number();
		
	} 
	gotoxy(0,0);
	printf("帅哥在来玩啊!");

	return 0;
}

void show(FILE *sp,score *ps)   //打印排行
{
	int i,m;
	space(); 
	int x, y;
	sp = fopen("123.txt","rb");
	rewind(sp);
	i=0;
	while(fread(&ps[i],sizeof(score),1,sp)>0)
		i++;
	fclose(sp);	
	for(x=MOVE;x<WRID+MOVE;x+=2)
	{
		gotoxy(x, 0);
			printf(WALL);
		gotoxy(x,HIGH);
			printf(WALL);
	}
	for(y=1;y<HIGH;++y)
	{
		gotoxy(MOVE,y);
			printf(WALL);
		gotoxy(WRID+MOVE-2,y);	
			printf(WALL);
	}
	
	if(i == SCORE)
	{
		for(m=0;m<i;m++)
		{
			gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
			printf("%d:姓名:%-6s 分数: %d ",m+1,ps[m].name,ps[m].count);
		}
	}
	else if(i < SCORE && i >0)
	{
		for(m=0;m<i;m++)
		{
			gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
			printf("%d:姓名:%-6s 分数: %d ",m+1,ps[m].name,ps[m].count);
		}
		for(m=i;m<SCORE;++m)
		{
			gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
				printf("%d:姓名:----   分数:---- ",m+1);
		}
	}
	else
	{
		for(m=0;m<SCORE;++m)
		{
			gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
				printf("%d:姓名:----   分数:---- ",m+1);
		}
	}
	gotoxy((WRID+MOVE)/2-2,HIGH/2-2+m+3);
	printf("按任意键继续");
	getch();
	space();	//清屏 
}

void open(FILE *pf,score *ps,score *pt)		// 打开记录文件 
{
	int i=0;
	int n, m;
	bool fun = false;
	score temp;
	pf=fopen("123.txt","a+b");		//读打开 

	rewind(pf);
	
	while(fread(&ps[i],sizeof(score),1,pf) > 0)
		i++;
	fclose(pf);	
	
	if(i==0)
	{
		ps[i++] = *pt;
	}
	else						
	{
		for(n=0;n<i;n++)						//排序 
		{
			if(ps[n].count <= pt->count)
				break;
		}
		if(n <= i-1)
		{			
			if(i==SCORE)
			{
				if(n == i-1)
					ps[n] = *pt;
				if(n < i-1)
				{
					for(m=i-2;m>=n;m--)
						ps[m+1] = ps[m];
					ps[n] = *pt;
				}
			}
			if(i < SCORE)
			{
				for(m=i-1;m>=n;m--)
					ps[m+1] = ps[m];
				ps[n] = *pt;
				i++;
			}
		}
	
	}
	
	pf = fopen("123.txt","wb");
	rewind(pf);
	n=0;
	while(n<i)
	{
		fwrite(&ps[n],sizeof(score),1,pf);
		n++;
	}
	fclose(pf);
	
}


void start(snake *ps, food *pd, score *ft)		//开始游戏 
{
	int i=1;
	char name[NAME];
	int fast = 300;
	wall(ps);
	gotoxy((MOVE+WRID)/2-8,3);
	printf("输入姓名:");
	s_gets(name,NAME);
	strcpy(ft->name,name);
	gotoxy((MOVE+WRID)/2-8,3);
	printf("                   ");
	
	while(i)
	{				
		Sleep(fast);//在标准C中是sleep(S不要大写),下面使用大写的来说明,具体
						//用什么看你用什么编译器。简单的说VC用Sleep,别的一律使用sleep
		if(flag)
		{
			foods(pd,ps);	//生成随机食物 
			if(fast > 100)
				fast -=2;
		}
		snakemove(ps,pd,ft);	//移动蛇 
		
		gotoxy(MOVE+WRID+4,7);
			printf("玩家: %s", ft->name);
		gotoxy(MOVE+WRID+4,9);	
			printf("得分: %d", ft->count);
		gotoxy(MOVE+WRID+4,21);
			printf("游戏规则: wsad移动蛇.吃方块得1分.");
		gotoxy(MOVE+WRID+4,22);
			printf("          撞墙或吃到身体游戏结束.");		
		if(gameover(ps))	//判断游戏是否结束 
		{
			gotoxy((MOVE+WRID)/2-6,HIGH/2);
				printf("玩家:%s 得分:%d",ft->name,ft->count); 
			gotoxy((MOVE+WRID)/2-6,HIGH/2+1);
				printf("按任意键返回主菜单");
			if(getch());
				space();	//清屏 
			i = 0;
		}
		
	}
	
}

int number(void)	//游戏选项
{
	int i;
	
	i = getch();
	while(strchr("123", i) == NULL)
		i = getch();
	

	space();		
	return i;
}

void Interface(void)
{
	int x, y;
	
	for(x=MOVE;x<WRID+MOVE;x+=2)
	{
		gotoxy(x, 0);
			printf(WALL);
		gotoxy(x,HIGH);
			printf(WALL);
	}
	for(y=1;y<HIGH;++y)
	{
		gotoxy(MOVE,y);
			printf(WALL);
		gotoxy(WRID+MOVE-2,y);	
			printf(WALL);
	}
	
	gotoxy((WRID+MOVE)/2-2, HIGH/2-5);
		fputs("贪  吃  蛇",stdout); 
		
	gotoxy(MOVE+20, HIGH-3);
		printf("[1]开始  [2]排行榜  [3]退出");
	
}

char* s_gets(char *st, int n)
{
	char *val;
	char *find;
	
	val = fgets(st,n,stdin);
	if(val)
	{
		find = strchr(st, '\n');
		if(find)
			*find = '\0';
		else
			while(getchar() != '\n')
				continue;	
	}
	
	return val;
}

snake.c

#include <stdio.h>
#include "snake.h"


static void insnake(snake *head);	//初始化蛇 
static void eatfood(snake *ph,food *pd, score *ft);	//吃食物 

void gotoxy(int x, int y)
{
    COORD pos = {x,y};
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
    SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}

bool gameover(snake *ph)
{
	node *temp = ph->front->next;	
	node *pf = ph->front; 
	if(ph->front->x == MOVE || ph->front->x == (WRID+MOVE)-2 ||	//判断蛇头是否撞墙 
					 ph->front->y == 0 ||ph->front->y == HIGH)
	{
		while(pf != NULL)			//释放动态内存 
		{
			ph->front = ph->front->next;
			free(pf);
			pf = ph->front;
		}
		ph->rear = NULL;
		flag = 1;
		wasd = 'a';
		return true;
	}	 
	while(temp != NULL)
	{
	 	if(ph->front->x == temp->x && ph->front->y == temp->y)	//判断蛇头是否吃到蛇身 
	 	{
	 		while(pf != NULL)		//释放动态内存
			{
				ph->front = ph->front->next;
				free(pf);
				pf = ph->front;
			}
				ph->rear = NULL;
				flag = 1;
				wasd = 'a';	
	 		return true;
		}
	 	temp = temp->next;
	}
	 	
	 return false;	
	  
}


void snakemove(snake *ph,food *pd,score *ft)
{
	node * temp;
	if(kbhit())
		wasd = tolower(getch());
	
	temp = ph->rear;
	gotoxy(ph->rear->x, ph->rear->y);	// 消除蛇尾 
		printf("  ");
	
	while(temp != ph->front)		//打印移动中的 蛇身 
	{
		temp->x = temp->upper->x;
		temp->y = temp->upper->y;
		gotoxy(temp->x, temp->y);
		printf(SE);
		
		temp = temp->upper;		
	}	
	
	switch(wasd)
	{
		case 'w':
			(ph->front->y)--;
			break;
		case 's':
			(ph->front->y)++;
			break;
		case 'a':
			ph->front->x -= 2;
			break;
		case 'd':
			ph->front->x += 2;
			break;
	}
	
	gotoxy(ph->front->x, ph->front->y);	// 打印蛇头 
		printf(TU);
	eatfood(ph,pd,ft);
	
	gotoxy(100,0);
}

static void eatfood(snake *ph,food *pd, score *ft)	//吃食物 
{
	node *pnew;
	if(ph->front->x==pd->x && ph->front->y==pd->y)
	{
		pnew = (node *)malloc(sizeof(node));
		pnew->next = pnew->upper = NULL;
		ph->rear->next = pnew;
		pnew->upper = ph->rear;
		ph->rear = pnew;
		
		ph->item++;
		flag = 1;
	}
	ft->count = ph->item-LEN;
}


void wall(snake *head)		//墙体 
{
	int x, y;
	
	for(x=MOVE;x<WRID+MOVE;x+=2)
	{
		gotoxy(x, 0);
			printf(WALL);
		gotoxy(x,HIGH);
			printf(WALL);
	}
	for(y=1;y<HIGH;++y)
	{
		gotoxy(MOVE,y);
			printf(WALL);
		gotoxy(WRID+MOVE-2,y);	
			printf(WALL);
	}
	
	gotoxy(100,0);
	
	insnake(head);
}

void foods(food *pd, snake *head )	//生成食物 
{
	int xy=1;
	node * ps = head->front;
	pd->x = rand() %(WRID-4)+1+MOVE;
	pd->y = rand() %(HIGH-1) +1;

	if(pd->x %2 == 0)	
	{
		while(ps != NULL)
		{
			if(ps->x == pd->x && ps->y == pd->y)
				xy = 0;
			ps = ps->next;
		}
		if(xy)
		{
			gotoxy(pd->x,pd->y);
			printf(WALL);
			flag = 0;
		}
		
	}
	
}


static void insnake(snake *head)		//初始化蛇 
{
	int i = 0;
	int x, y;
	head->item = LEN;	
	node *ps;
	
	for(i=0;i< head->item;i++)	//生成双向链表 
	{
		ps = (node *)malloc(sizeof(node));
		ps->next = NULL;
		ps->upper = NULL;
		
		if(i==0)
			head->front = head->rear = ps;
		else
		{
			ps->upper = head->rear;
			head->rear->next = ps;
			head->rear = ps;
		}
	}
	
	head->front->x = (MOVE+WRID) / 2;
	if(head->front->x%2 != 0)
		(head->front->x)++;
	head->front->y = HIGH / 2;
	
	gotoxy(head->front->x, head->front->y);	//打印蛇头 
		printf(TU);
	
	ps = head->front->next;		
	
	while(ps != NULL)		// 打印蛇身 
	{
		ps->x = ps->upper->x + 2;
		ps->y = ps->upper->y;
		
		gotoxy(ps->x, ps->y);
		printf(SE);
		ps = ps->next;
	}
	gotoxy(100,0);
}

void space(void)
{
	int y,i;
	y = HIGH;
	
	for(i=0;i<=y;++i)
	{
		gotoxy(MOVE,i);
		printf("                              " 
			   "                              "  
			   "                              "                              
		       "                              ");
	}
	
}

snake.h

#ifndef __SNAKE_H
#define __SNAKE_H
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>			// ■⊙● 
#include <time.h>
#include <stdbool.h>
#define SCORE 5		//记录长度 
#define NAME 30		//名字长度 
#define WALL "■"	//墙 
#define	TU	"⊙"
#define SE	"●"
#define WRID 70		//墙宽 
#define HIGH 26		//墙高 
#define MOVE 10		//墙体平移 
#define LEN 3      //初始化长度 

typedef struct Score{	//记录分数 
	char name[NAME];	//姓名 
	int count;			//分数 
}score;

typedef struct Node{	//蛇 
	int x;
	int y;
	struct Node *next;
	struct Node *upper;
}node;

typedef struct Snake{	//蛇的头指针 和 分数 
	node * front;		//头指针
	node * rear; 		//尾指针 
	int item;			//分数 
}snake;

typedef struct Food{	//食物 
	int x;
	int y;
}food;


extern int wasd;	//控制方向 
extern int flag;	//控制食物生成 

void gotoxy(int x, int y); //光标坐标 
void wall(snake *head);	//初始化墙 和 蛇身 
void snakemove(snake *ph,food *pd,score *ft); //移动蛇	
void foods(food *pd, snake *head);	//生成食物 
bool gameover(snake *ph);		//结束游戏 
void space(void);		//清除 


#endif
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值