贪吃蛇大战

前言

提示:数据结构课程设计,基于c语言,中间涉及到一些指针的使用,用到一些数据结构里面的算法


提示:以下是本篇文章正文内容,下面案例可供参考

一、内容展示

主界面:
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

1.开始游戏
在这里插入图片描述
2.游戏说明
在这里插入图片描述
3.开发人员
在这里插入图片描述
4.退出游戏
在这里插入图片描述

二、代码

//----------------贪吃蛇大作战----------------- 
//*******************头文件区 ********************* 
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#include <graphics.h>
#include <Mmsystem.h>
#pragma comment ( lib, "Winmm.lib" )

//*******************宏定义区 ********************* 
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define N 1000
//#define _CRT_SECURE_NO_WARNINGS

//*******************结构体区 ********************* 
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;

//*******************函数声明区 *********************  
void printMap(void);//游戏界面的范围框 
void showScoreTips(void);//游戏界面得分框 
void printSnake(void);  //绘制上边蛇身开始界面 

int welcomeGame(void);//绘制下面开始界面 
int aboutGame(void);//游戏说明 
int kaifarenyuan(void);//开发人员 
int initSnake(void);//游戏中吃食物蛇的变化和蛇的外貌 
int randFood(void);//随机生成食物 
int moveSnake(void);//控制蛇身体的移弄 
int moveKeyControl(void);//确定用户当前是否按下了键盘上的一个键
int speedUp(void);//升级难度 
int speedDown(void);//降低难度 
int isHitWall(void);//判断是否撞墙 
int isBiteSelf(void);//判断是否咬到自己 
int failGameUi(void);//结束死亡界面 上边的模型 
int endGame(void);//结束界面,结束操作的实现 
int readFile(void);//读取文件 
int writeFile(int score);//写入文件 
int snakeDestroy(void);//销毁蛇节点,初始化蛇数据 

//*******************控制输出的颜色和位置 获取光标位置 ********************* 
int setColor(int c);
int gotoXY(int x, int y);

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 main()
{
	//显示控制台宽高 
	system("mode con cols=100 lines=30"); 
	//initgraph( 1200, 800 );
	//IMAGE img;
	//loadimage(&img,"D:\\贪吃蛇大作战\\深海.jpg",100,30);
	//putimage(0,0,&img);
	
	int n;
	while(1)
	{
		system("cls");
		
		n = welcomeGame();
		switch(n)
		{
		case 1:
			mciSendString("open D://贪吃蛇大作战//背景音乐.wav alias music1",0,0,0);
			mciSendString("play music1",0,0,0);
			printMap();
			showScoreTips();
			initSnake();
			randFood();
			moveKeyControl();
			break;
			
		case 2:
			aboutGame();
			break;
		case 3:
			kaifarenyuan();
			break;	
		case 4:
			exit(0);
			break;
			
		default:
			;
		}
		getchar();
	}
	system("pause"); 
	return 0; 
}

void 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 input;
	 
	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.开发人员"); 
	gotoXY(55, 24);
	printf("4.退出游戏"); 
	
	setColor(3);
	gotoXY(27, 27);
	printf("\n\t\t\t\t\t   从键盘输入:→ ");
	
	scanf("%d", &input);
	getchar(); 

	//input=getch();
	
	return input;
}

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 kaifarenyuan(void)
{
	int i, j;
	
	system("cls");
	setColor(13);
	gotoXY(44, 3);
	printf("My Team");
	
	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(39, 9);
	printf("201805080128 毛自怀");
	
	setColor(10);
	gotoXY(39, 13);
	printf("201805080147 杨兆有");
	
	setColor(14);
	gotoXY(39, 17);
	printf("201805080159 朱世超");

	gotoXY(20, 24);
	setColor(12);
	printf("请按下回车键返回主界面"); 
	
	return 0;
}

void 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(3);
				printf("■");				
			}
			else
			{
				setColor(0);
				printf(" ");
			}
		}
	} 

}

void 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 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 = new 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(14);
            printf("●");
            
            food = new2;
            break;
        }
        else
        {
            continue;
        }
    }
	
	
	return 0;
}

int moveSnake(void)
{
	snake *q = NULL;
	snake *tmp = NULL;
	snake *save = NULL; 	//保存上一个节点 
	
	//分配空间 
	q =new snake;
	if(NULL == q)
	{
		printf("malloc failed...\n");
		return -1;		
	}	
	memset(q, 0, sizeof(snake));
	
	//向上 
	if(direction == UP)
	{
		q->x = head->x;
		q->y = head->y-1;	
	}
	
	//向下 
	if(direction == DOWN) 
	{
		q->x = head->x;
		q->y = head->y+1;	
	}
	
	//向左 
	if(direction == LEFT)
	{
		q->x = head->x-2;
		q->y = head->y;	
	}
	
	//向右 
	if(direction == RIGHT)
	{
		q->x = head->x+2;
		q->y = head->y;	
	}
	
	//头插法
	q->next = head;
	head = q;
	
	//使用临时节点指向链表第一个节点
	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(0);
		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("\n\t\t\t\t\t   从键盘输入:→ ");
		
		scanf("%d", &n);
		getchar();
		//n=getch();
		 
		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 readFile(void)
{
	int zj[N],n=0,max; 
	FILE *fp = NULL;
	//打开文件 
	fp = fopen("D://贪吃蛇大作战//战绩.txt", "r");
	if(0 == fp)
	{
		printf("打开文件失败、、、\n");
		return -1; 
	}

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

int writeFile(int score)
{
	FILE *fp = NULL;
	fp = fopen("D://贪吃蛇大作战//战绩.txt", "w");
	if(0 == fp)
	{
		printf("打开文件失败...\n");
		return -1;			
	}		
	fprintf(fp,"%d,",score);
	
	fclose(fp);
	
	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;	
}
	

总结

此为借鉴的某位大佬的,进行更改界面,和其中的一些功能,取得对方的同意,得以发布。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

maosql

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值