蒟蒻的控制台贪吃蛇(新手实验)

学了这么久的C语言,决定写个比较有趣的玩意——贪吃蛇

在大学刷题感到疲累,被学校的大佬碾压,我的学习兴趣逐渐低迷,于是想出了写贪吃蛇的欲望,这其实也是比较有效的化知识为力量的方法吧。虽然本人专业不归属计算机,也没有学计算机,也是大一新生没多久,但是还是希望在计算机方面比他们出众。写个贪吃蛇来巩固一下自己的实力:
关于一些注解和逻辑都写在代码块里,也希望能帮助其他人
这是自己封装的头文件,便于开发,和主体代码更简洁

#define HEAD_H
#define SnakeMaxLength 20
typedef int booleen;
#define true 1
#define false -1
// 不要问我问什么写这个头文件,因为显得我很吊
//背景布置
//一个特殊字符实线格子在横列是占两格
//所以空白格子在圈中要以两倍的间隔空格隔开
char MyBackGround[22][80]={  "■■■■■■■■■■■■■■■■■■■■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t欢乐时光就要开始了\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\tW A S D控制操作\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t碰到墙壁死亡\n",
							 "■                                    ■\n",
							 "■                                    ■\t\t\t祝好运\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■■■■■■■■■■■■■■■■■■■■\n"};
//这里使用了枚举 为什么这里go_ease = -2 因为这里特殊字符在横向占两格 
//列只占一个格子
enum Direction{go_east = -2,go_west = 2,go_north = -1,go_south = 1};//上北下南左西右东好记又好用
int ArrSnake[SnakeMaxLength][3]={{0,0,0}};//前两个是蛇坐标,最后一个判断蛇的方向,最长20.
//判断蛇默认开始方向
int SnakeDirection = go_east;
//判断食物是否还存在
booleen OptionFoodAlive = false;
int x,y;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"one.h"//自己编头文件的快乐 ,里面有蛇的方向还有默认方向等等(利用枚举)
#include<conio.h>//里面有个随机函数
#include<windows.h>
//#include<mmsystem.h>
//#pragma comment (lib, "winmm.lib")//音乐所使用的动态链接库弄不了,唉
#include<time.h>
#define false -1
#define true 1
typedef int booleen;//驼峰命名法显得我很吊
void FirstPage();// 首页
//void MyMusic();(由于winmm.dll在vscode上加载不了,废弃)// 音乐
void EnterGame();// 按回车进入游戏
//void StopMusic();(同上)QAQ....)// 停止音乐
void CleanScreen();// 清空页面
void BackGround();// 背景基础
void SetSnakePos();// 蛇的起始位置
void GiveSnake();// 画蛇
void MoveSnake();// 给蛇的位置赋值,也就是移动蛇。
void DeleteSnake();// 删除蛇
void ControlSnake();// 控制蛇
booleen IsSnakeAlive();// 判断蛇是否死亡
void ProduceFood();// 制造食物(用到随机函数)
void LengthenSnake();// 蛇变长
int main(){
    FirstPage();
    //MyMusic();
    EnterGame();
    //StopMusic();
    CleanScreen();
    SetSnakePos();//设置蛇的初始坐标
    while (1)
    {
        ProduceFood();
        DeleteSnake();
        ControlSnake();
        MoveSnake();
        if(IsSnakeAlive()==false)
        {
            printf("emmm,你果然还是适合刷题!!");
            break;
        }
        LengthenSnake();
        GiveSnake();
        BackGround();
        Sleep(500);//Sleep以毫秒为单位,sleep好像是秒
        system("cls");
    }
    
    getchar();
}
void FirstPage()
{
    printf("\n\n\n\n\n\n");
    printf("\t\t\t\t\t  欢迎来到贪吃蛇的世界,\n\n\n");
    printf("\t\t\t\t\t 还行的    果然还是可以的\n\n\n");
    printf("\t\t\t\t\t       狗蛋菜    \n\n\n" );
    printf("\t\t\t\t\t W A S D 控制蛇前进后退\n\n\n");
    printf("\t\t\t\t\t 按下ENTER键开始新游戏\n\n\n\n");
}
//void MyMusic(){
    //PlaySound("1.wav",NULL,SND_FILENAME|SND_ASYNC);//实在不懂,百度词条学习法(第一次尝试,我是这么学的)
    //使用PlaySound函数时需要在#include<windows.h>后面加上(注意:不能加在前面)
    //#include <mmsystem.h>
    //#pragma comment(lib, "WINMM.LIB")
//}
void EnterGame()
{
    while ('\r'!=_getch());//这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车
}
void CleanScreen(){
    system("cls");
}
void BackGround(){
    
    for (int i = 0; i < 20; i++)
    {
        printf("%s",MyBackGround[i]);//我的头文件里的背景二维字符串
    }
}
void SetSnakePos(){
    int x=-1;//行数
    int y=-1;//列数
    srand(time(NULL));
    // srand函数是随机数发生器的初始化函数。原型:void srand(unsigned int seed);srand和rand()配合使用产生伪随机数序列。
    //time() 函数返回当前系统时间 如果是空指针,直接返回当前时间
    y = rand()%16+1;//用时间自己换算一下.伪随机的
    x= rand()%16+1;//默认蛇是有三个格子
    //特殊符号横向是两个,所以y向是变幻时都得乘二
    ArrSnake[0][0]=x;
    ArrSnake[0][1]=y*2;
    ArrSnake[0][2]=go_east;

    ArrSnake[1][0]=x;
    ArrSnake[1][1]=y*2+2;
    ArrSnake[1][2]=go_east;

    ArrSnake[2][0]=x;
    ArrSnake[2][1]=y*2+4;
    ArrSnake[2][2]=go_east;
}
void GiveSnake(){
    int i;
    for (i = 0; ArrSnake[i][0]!=0; i++)//等于零就是碰到边界
    {
        strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]],"■",2);
        //用这个就是能最后限定长度,就很nice
    }
}
//蛇的移动依赖于赋值,删除,赋值删除
//删除掉原来的蛇,保存现在的蛇
void DeleteSnake(){
    int i;
    for (i = 0; ArrSnake[i][0]!=0; i++)
    {
        strncpy(&MyBackGround[ArrSnake[i][0]][ArrSnake[i][1]],"  ",2);
    }
}
void MoveSnake(){
    int i=SnakeMaxLength-1;
    ArrSnake[0][2]=SnakeDirection;
    for ( ; i > 0; i--)//过滤零
    {
        if(ArrSnake[i][0]==0)continue;
        ArrSnake[i][0]=ArrSnake[i-1][0];
        ArrSnake[i][1]=ArrSnake[i-1][1];
        ArrSnake[i][2]=ArrSnake[i-1][2];
    }
    //蛇头
    if(go_east==ArrSnake[0][2]||go_west==ArrSnake[0][2])ArrSnake[0][1]+=ArrSnake[0][2];
    else ArrSnake[0][0]+=ArrSnake[0][2];
}
//控制蛇的方向
//Asyn的函数块,异步的意思,老规矩,可以百度百科学习法
//如 果 每次 都要 回车 太没意思 或者其他函数 还是有 一定延迟 这个函数非常银杏
void ControlSnake(){
    if(GetAsyncKeyState('W'))
    {
        if(SnakeDirection!=go_south)
        SnakeDirection=go_north;
    }
    else if (GetAsyncKeyState('S'))
    {
        if(SnakeDirection!=go_north)
        SnakeDirection=go_south;
    }
    else if (GetAsyncKeyState('A'))
    {
        if(SnakeDirection!=go_west)
        SnakeDirection=go_east;
    }
    else if (GetAsyncKeyState('D'))
    {
        if(SnakeDirection!=go_east)
        SnakeDirection=go_west;
    }
}
booleen IsSnakeAlive(){
    if(strncmp(&MyBackGround[ArrSnake[0][0]][ArrSnake[0][1]],"■",2)==0)return false;
    /*strncmp函数的功能比较
        (1)strncmp函数
        用来比较s1和s2字符串的前n个字符。如果两个字符串相等的话,strncmp将返回0(可以用来判断蛇是否还活着)。如果s1是s2的一个子串的话,s1小于s2。可以限定长度
        (2)strcmp函数
        同样用于比较两个字符串 ,设这两个字符串为str1,str2。若str1==str2,则返回零;若str1 > str2,则返回正数;若str1< str2,则返回负数。
        参考资料来源:搜狗百科—strncm*/
    else return true;
    //蛇头撞墙和自身的情况
}
void ProduceFood()
{
    //蛇的坐标
    int i;
    srand(time(NULL));
    //给蛇坐标
    if(OptionFoodAlive==true) return;//如果食物还存在不生成食物
    while(1)
    {
        booleen tempbool =true;
        x=rand()%18+1;
        y=rand()%18+1;
        for(i=1;i<ArrSnake[i][0];i++){
            if (x==ArrSnake[i][0]&&2*y==ArrSnake[i][1])
            {
                tempbool = false;
                break;//生成在蛇身上的情况
            }
        }
        if(true==tempbool)
        {
                break;
        }
    }
    strncpy(&MyBackGround[x][y*2],"※",2);
    OptionFoodAlive = true;
}
//吃了就长(身高矮的goudan表示很淦)
void LengthenSnake(){
    int i=0;
    if (ArrSnake[0][0]==x&&ArrSnake[0][1]==y*2)
    {
        OptionFoodAlive = false;
        for ( ; ; i++)
        {
            if (ArrSnake[i][0]==0)
            {
                if(ArrSnake[i][2]==go_north||ArrSnake[i][2]==go_north)
                {
                    ArrSnake[i][0]=ArrSnake[i-1][0]-ArrSnake[i-1][2];
                    ArrSnake[i][1]=ArrSnake[i-1][1];
                    ArrSnake[i][2]=ArrSnake[i-1][2];
                }
                else
                {
                    ArrSnake[i][0]=ArrSnake[i-1][0];
                    ArrSnake[i][1]=ArrSnake[i][1]-ArrSnake[i][2];
                    ArrSnake[i][2]=ArrSnake[i][2];
                }
                break;
            }
        }
    }
}

关于我在这之间的一些困难:1.音乐导入问题(因为我用的vscode,导入不了winmm.lib所以暂时性废弃)2.控制台显示乱码问题,这是因为编码格式写的不对utf-8改成gb2312,vscode就是右下角有个这样的:
在这里插入图片描述
改成这样子就行

接下来是运行实况:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

大概如此

我这蒟蒻就写这么多了,我还会继续优化,这个界面我并不是很满意,我会用EasyX写个图形化的贪吃蛇。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值