贪吃蛇大作战游戏——C语言

是你想要的贪吃蛇吗?
快来看看吧~
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#include <time.h>

//宏定义
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4

typedef struct snake	//链表,存放蛇身坐标 
{
	int x;
	int y;
	struct snake *next; //蛇身的下一个节点 
}snake;
snake *head = NULL;
snake *food = NULL;

int score;
int add = 1;
int direction = RIGHT;
int sleepTime = 300;
int endStatus = 0;

int setColor(int c);
int gotoXY(int x, int y);
int printSnake(void);
int welcomeGame(void);
int aboutGame(void);
int printMap(void);
int showScoreTips(void);
int readFile(void);
int initSnake(void);
int randFood(void);
int moveSnake(void);
int moveKeyControl(void);
int speedUp(void);
int isHitWall(void);
int isBiteSelf(void);
int failGameUi(void);
int endGame(void);
int writeFile(int score);
int snakeDestroy(void);

int setColor(int c)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);

	return 0;
} 

int gotoXY(int x, int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	
	return 0; 
} 

int printSnake(void)
{
 	//清屏
    system("cls");

    gotoXY(35, 1);
    setColor(6);
    printf("/^\\/^\\");      //蛇眼睛

    gotoXY(34, 2);
    printf("|__|  O|");      //蛇眼睛

    gotoXY(33, 2);
    setColor(2);
    printf("_");

    gotoXY(25, 3);
    setColor(12);
    printf("\\/");          //蛇信

    gotoXY(31, 3);
    setColor(2);
    printf("/");

    gotoXY(37, 3);
    setColor(6);
    printf(" \\_/");        //蛇眼睛

    gotoXY(41, 3);
    setColor(10);
    printf(" \\");

    gotoXY(26, 4);
    setColor(12);
    printf("\\____");       //舌头

    gotoXY(32, 4);
    printf("_________/");

    gotoXY(31, 4);
    setColor(2);
    printf("|");

    gotoXY(43, 4);
    setColor(10);
    printf("\\");

    gotoXY(32, 5);
    setColor(2);
    printf("\\_______");    //蛇嘴

    gotoXY(44, 5);
    setColor(10);
    printf("\\");

    gotoXY(39, 6);
    printf("|     |                  \\");  //下面都是画蛇身

    gotoXY(38, 7);
    printf("/      /                   \\");

    gotoXY(37, 8);
    printf("/      /                    \\ \\");

    gotoXY(35, 9);
    printf("/      /                       \\ \\");

    gotoXY(34, 10);
    printf("/     /                          \\  \\");

    gotoXY(33, 11);
    printf("/     /             _----_         \\   \\");

    gotoXY(32, 12);
    printf("/     /           _-~      ~-_         |  |");

    gotoXY(31, 13);
    printf("(      (        _-~    _--_    ~-_     _/  |");

    gotoXY(32, 14);
    printf("\\     ~-____-~    _-~    ~-_    ~-_-~    /");

    gotoXY(33, 15);
    printf("~-_           _-~          ~-_       _-~");

    gotoXY(35, 16);
    printf("~--______-~                ~-___-~");
	
}

int welcomeGame(void)
{
	int i;
	int j;
	int n;
	 
	printSnake();
	
	setColor(11);
	gotoXY(45, 18);
	printf("贪 吃 蛇 游 戏");
	 
	setColor(14); 
	for(i = 20; i <= 26; i++){
		for (j = 27; j <= 74; j++)
		{
			gotoXY(j, i);
			if(i == 20 || i == 26)
			{
				printf("-");
			}
			else if (j == 27 || j == 74)
			{
				printf("|");
			}		
			else
			{
				printf(" "); 
			}	
		}
	} 
	
	//输出菜单 
	setColor(12);
	gotoXY(35, 22);
	printf("1.开始游戏");
	gotoXY(55, 22);
	printf("2.游戏说明");
	gotoXY(35, 24);
	printf("3.退出游戏"); 
	
	setColor(3);
	gotoXY(27, 27);
	printf("请选择[1 2 3]: [   ]\b\b\b");
	
	scanf("%d", &n);
	getchar(); 
	
	return n;	
}

int aboutGame(void)
{
	int i, j;
	
	system("cls");
	setColor(13);
	gotoXY(44, 3);
	printf("游戏说明");
	
	setColor(2);
	for(i=6; i <= 22; i++)
	{
		for(j = 20; j<=75; j++)
		{
			gotoXY(j, i);
			if(i == 6 || i == 22)
			{
				printf("=");		
			}
			else if(j == 20 || j == 75)
			{
				printf("||");	
			}	
			else 
			{
				printf(" ");
			}
		}	
	}
	
	//输出游戏说明界面 
	setColor(3);
	gotoXY(30, 8);
	printf("☆1: 不能穿墙,不能咬到自己");
	
	setColor(10);
	gotoXY(30, 11);
	printf("☆2: 用↑、↓、←、→控制蛇的移动方向");
	
	setColor(14);
	gotoXY(30, 14);
	printf("☆3: F1加速,F2减速");
	
	setColor(11);
	gotoXY(30, 17);
	printf("☆4: 按空格键暂停游戏,再按空格键继续");
	
	setColor(4);
	gotoXY(30, 20);
	printf("☆5: ESC退出游戏,spece暂停游戏");	
	
	gotoXY(20, 24);
	setColor(12);
	printf("请按下回车键返回主界面"); 
	
	return 0;
}

int printMap(void)
{
	int i=0, j=0;
	
	system("cls");
	
	//一个方块占两列 
	for(i=0; i<27; i++)
	{
		for(j=0; j<57; j+=2)	
		{
			gotoXY(j, i);
			if(i == 0 || i == 26 || j == 0 || j == 56)
			{
				setColor(5);
				printf("□");				
			}
			else
			{
				setColor(3);
				printf("■");
			}
		}
	} 

}

int showScoreTips(void)
{
	int highScore = 0;
	
	setColor(11);
	gotoXY(64, 4);
	highScore = readFile(); 
	printf("☆最高记录☆: %d", highScore);
	
	setColor(14);
	gotoXY(64, 8);
	printf("得分: %d", score    );
	
	setColor(12);
	gotoXY(72, 11);
	printf("温 馨 提 示");
	
	setColor(6);
	gotoXY(60, 13);
	printf("==============================");
	gotoXY(60, 25);
	printf("==============================");
	
	setColor(3);
	gotoXY(61, 14);
	printf("每个食物得分:%d", score);
	gotoXY(61, 16);
	printf("不能穿墙,不能咬到自己");
	gotoXY(61, 18);
	printf("用↑↓←→分别控制蛇移动方向");
	gotoXY(61, 20);
	printf("tip3: F1加速,F2减速");
	gotoXY(61, 22);
	printf("space: 暂停游戏");
	gotoXY(61, 24);
	printf("ESC: 退出游戏"); 
}

int readFile(void)
{
	int n = 0; 
	FILE *fp = NULL;
	//打开文件 
	fp = fopen("save.txt", "a+");
	if(NULL == fp)
	{
		printf("打开文件失败、、、\n");
		return -1; 
	}

	fscanf(fp, "%d", &n);
	
	fclose(fp);
	
	return n;
	  
}

int initSnake(void)
{
	int i= 0;
	
	snake *new1 = NULL;
	snake *tmp = NULL;
	
	//创建四个蛇节点 
	for (i = 0; i < 4; i++)
    {  
    	//分配空间		        
		new1 = (snake*)malloc(sizeof(snake));
		if(NULL == new1)
		{
			printf("malloc failes...\n");
			break;
		}
		//清零 
		memset(new1, 0, sizeof(snake));
		
		//初始化列为偶数 
        new1->x = 24 + i * 2;
        new1->y = 5;
        
		//头插法 
	    new1->next = head;
        head = new1;
    }
    
	tmp = head;
    while (NULL != tmp)
    {
        setColor(14);
        gotoXY(tmp->x, tmp->y);
        
        if (head == tmp)
        {
            printf("◆");
        }
        else
        {
            printf("★");
        }
		//指向下一个节点 
        tmp = tmp->next;
    }
   return 0; 
}

int randFood(void)
{
	snake *new2 = NULL;
    snake *tmp = NULL;
    
    //分配空间 
    new2 = malloc(sizeof(snake));
    if (NULL == new2)
    {
        gotoXY(1, 28);
        printf("malloc failed...\n");
        return -1;
    }   
	 
    while (1)
    {        
    	//清零 
    	memset(new2, 0, sizeof(snake));
    	
    	//随机X值 
        while (1)
        {
        	//随机X值,为偶数 
            new2->x = rand() % 53 + 2;
            if (new2->x % 2 == 0)
            {
                break;
            }
        }
        //1-25
        new2->y = rand() % 25 + 1;
        
		//判断食物不能在蛇身上
        tmp = head;
        while (NULL != tmp)
        {
            if ((tmp->x == new2->x) && ( tmp->y == new2->y))
            {
                break;
            }
			tmp = tmp->next;
        }
        
        //食物不在蛇身上 
        if (NULL == tmp)
        {
            gotoXY(new2->x, new2->y);
            setColor(12);
            printf("●");
            
            food = new2;
            break;
        }
        else
        {
            continue;
        }
    }
	
	
	return 0;
}

int moveSnake(void)
{
	snake *new = NULL;
	snake *tmp = NULL;
	snake *save = NULL; 	//保存上一个节点 
	
	//分配空间 
	new = malloc(sizeof(snake));
	if(NULL == new)
	{
		printf("malloc failed...\n");
		return -1;		
	}	
	memset(new, 0, sizeof(snake));
	
	//向上 
	if(direction == UP)
	{
		new->x = head->x;
		new->y = head->y-1;	
	}
	
	//向下 
	if(direction == DOWN) 
	{
		new->x = head->x;
		new->y = head->y+1;	
	}
	
	//向左 
	if(direction == LEFT)
	{
		new->x = head->x-2;
		new->y = head->y;	
	}
	
	//向右 
	if(direction == RIGHT)
	{
		new->x = head->x+2;
		new->y = head->y;	
	}
	
	//头插法
	new->next = head;
	head = new;
	
	//使用临时节点指向链表第一个节点
	tmp = head;
	//前面是否为食物
	if(head->x == food->x && head->y == food->y) 
	{
		while (NULL != tmp)
  	    {
		setColor(14);
        gotoXY(tmp->x, tmp->y);
        
        if (tmp == head)
        {
        	printf("◆");
        }
        else
        {
            printf("★");
        }
		//指向下一个节点 
        	tmp = tmp->next;
		}
		
		//吃掉食物后,分数增加
		score += add;
		
		//随机食物
		randFood(); 
	}
	else
	{
		//删除最后一个节点 
		while (NULL != tmp->next)
		{
			setColor(14);
        	gotoXY(tmp->x, tmp->y);
        
	        if (tmp == head)
	        {
	        	printf("◆");
	        }
	        else
	        {
	            printf("★");
	        }
	        
	        //保存tmp节点
			save = tmp; 
			//指向下一个节点 
        	tmp = tmp->next;
		}
	
		gotoXY(tmp->x, tmp->y);
		setColor(3);
		printf("■");
		
		save->next = NULL;
		free(tmp);
		tmp = NULL;		
	}	
	
	return 0; 
	
}

int moveKeyControl(void)
{
	//默认向右 
	direction = RIGHT;
	
	while(1)
	{
		showScoreTips();
		
		if(GetAsyncKeyState(VK_UP) && direction != DOWN)
		{
			direction = UP;
		}
		 
		if(GetAsyncKeyState(VK_DOWN) && direction != UP)
		{
			direction = DOWN;
		} 
	
		if(GetAsyncKeyState(VK_LEFT) && direction != RIGHT)
		{
			direction = LEFT;
		}
		
		if(GetAsyncKeyState(VK_RIGHT) && direction != LEFT)
		{
			direction = RIGHT;
		}
		
		if(GetAsyncKeyState(VK_SPACE))
		{
			while(1)
			{
				if(GetAsyncKeyState(VK_SPACE))
				{
					break;
				}
				Sleep(200);
			}
		}		
		
		if(GetAsyncKeyState(VK_F1))
		{
			speedUp();
		}
		
		if(GetAsyncKeyState(VK_F2))
		{
			speedDown();
		}
		
		//ESC结束游戏 
		if(GetAsyncKeyState(VK_ESCAPE))
		{
			endStatus = 3;
			endGame();
			break;
		}
		
		moveSnake();
		
		if(isHitWall() == 1)
		{
			endStatus = 1;
			endGame();
			break;
		}
		if(isBiteSelf())
		{
			endStatus = 2;
			endGame();
			break;
		}
		Sleep(sleepTime);	
	}	
	return 0;
} 

int speedUp(void)
{
	if(sleepTime > 50)
	{
		sleepTime -= 50;
		add +=2; 
	}
	return 0;
}

int speedDown(void)
{
	if(sleepTime <300)
	{
		sleepTime += 10;
		add -=2; 
	}
	if(sleepTime > 250)
	{
		add =1; 
	}
	return 0;
}

int isHitWall(void)
{
	if(head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
	{
		return 1;
	}
	
	return 0;
}

int isBiteSelf(void)
{
	snake *tmp = NULL;
	
	tmp = head->next;
	while(tmp != NULL)
	{
		if(head->x == tmp->x && head->y == tmp->y)
		{
			return 1;
		}
		tmp = tmp->next; 
	}
	return 0;
}

int failGameUi(void)
{
	system("cls");
	 
	int i;
	
	gotoXY(46, 2);
	setColor(6);
	printf("\\\\\\|///");
	gotoXY(44, 3);
	printf("\\\\");
	
	setColor(15);
	gotoXY(47, 3);
	printf(".-.-");
	
	setColor(6);
	gotoXY(53, 3);
	printf("//");
	
	setColor(14);
	gotoXY(44, 4);
	printf("(");	//左耳朵
	
	setColor(15);
	gotoXY(47, 4);
	printf(".@.@");
	
	setColor(14);
	gotoXY(53, 4);
	printf(")");	//右耳朵 
	
	//边框	
	setColor(11);
	gotoXY(17, 5);
	printf("+-----------------");
	
	gotoXY(35, 5);
	setColor(14);
	printf("o00o");
	
	gotoXY(39, 5);
	setColor(11);
	printf("----------");
	
	gotoXY(48, 5);
	setColor(14);
	printf("(_)");
	
	gotoXY(51, 5);
	setColor(11);
	printf("----------");
	
	gotoXY(61, 5);
	setColor(14);
	printf("o00o");
	
	gotoXY(65, 5);
	setColor(11);
	printf("-----------------+");
	
	for(i=6; i<20; i++)
	{
		gotoXY(17, i);
		printf("|");
		gotoXY(82, i);
		printf("|");
	}
	
	gotoXY(17, 20);
	printf("+----------------------------------");
	
	gotoXY(52, 20);
	setColor(14);
	printf("☆☆☆");
	
	gotoXY(60, 20);
	setColor(11);
	printf("----------------------+"); 

	return 0;
} 

int endGame(void)
{
		
	system("cls");
	
	//显示失败界面边框 
	failGameUi(); 
	
	int highScore=0;
	int n=0;

	
	while(1)
	{
		gotoXY(38, 9);
		setColor(12);
		
		switch(endStatus)
		{
			case 1:
				printf("对不起,您已撞墙,游戏结束!");
				break;
			
			case 2:
				printf("对不起,您咬到自己,游戏结束!");
				break;
				
			case 3:
				printf("您已经结束了游戏!");
				break;
				
			default:
				break;		
		}
		
		//显示得分 
		setColor(13);
		gotoXY(43, 12);
		printf("您的得分是:%d", score);
		
		//显示最高记录 
		highScore = readFile();
		
		if(score > highScore)
		{
			setColor(10); 
			gotoXY(38, 16);
			printf("您已创造新的最高记录!"); 
			writeFile(score);
		} 
		else
		{
			setColor(10);
			gotoXY(38, 16);
			printf("继续努力,离最高分还差:%d", highScore - score); 	 	
		}
		
		//显示选择菜单
		setColor(12);
		gotoXY(25, 23);
		printf("我要再玩一局----1");
		gotoXY(52, 23);
		printf("不玩了,退出----2");
		
		setColor(11);
		gotoXY(46, 25);
		printf("请选择:[   ]\b\b\b");
		
		scanf("%d", &n);
		getchar();
		
		if(n == 1)
		{
			//回到初始状态 
			sleepTime = 250;
			score = 0;
			add = 1;
			
			//销毁蛇节点 
			snakeDestroy();
			
			//初始化头指针 
			head = NULL;
			break;
		}
		else if(n == 2)
		{
			exit(0);	
		} 
		else
		{
			setColor(12);
			gotoXY(30, 27);
			printf("您的输入有误,请重新输入,按下任意键继续");
			getchar();
			continue; 
		}
	}
	return 0;
}

int writeFile(int score)
{
	FILE *fp = NULL;
	fp = fopen("save.txt", "w");
	if(NULL == fp)
	{
		printf("打开文件失败...\n");
		return -1;			
	}	
	
	fprintf(fp, "%d", score);
	
	return 0;
}

int snakeDestroy(void)
{
	snake *tmp = NULL;
	snake *save = NULL;
	
	tmp = head;
	while(NULL != tmp)
	{
		save = tmp->next;
		free(tmp);
		tmp = save;	
	}	
	head = NULL;
	
	return 0;	
}
	

 
int main()
{
	//显示控制台宽高 
	system("mode con cols=100 lines=30");
	
	int n;
	
	while(1)
	{
		system("cls");
		
		n = welcomeGame();
		switch(n)
		{
		case 1:
			printMap();
			showScoreTips();
			initSnake();
			randFood();
			moveKeyControl();
		
			break;
			
		case 2:
			aboutGame();
			break;
			
		case 3:
			exit(0);
			break;
			
		default:
			;
		}
		getchar();
	}
	system("pause"); 
	return 0; 
}
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页