贪吃蛇1111

#include<windows.h>        
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<math.h>
#include<time.h>
typedef struct lei        //蛇结点结构体
{
    int x;
    int y;
    struct lei *next;
}lei;
typedef struct record    //记录
{
    int fraction;        //分数
    int hour;
    int min;
    int sec;
    int year;
    int mon;
    int day;
}record;

int score,scoreup=2,speed;      //得分,单个食物分数,初始速度
int bool_=1;                    //用于判断是否自动加速
int nfood_1;                    //记录吃到的食物数,用于自动加速的判断
int nfood_2;                    //记录吃到的食物数,用于提示信息的显示条件                              

void Setpox(int x,int y);             //设置光标
void Setcolor(unsigned short color);  //设置文本颜色
void Homepage();                      //主页显示
void Frame();                         //边框
void Gamedescription();               //游戏说明
void Rankinglist();                   //排行榜显示
void Gamemodule();                    //方向控制及游戏运行
void Createmap();                     //地图页面输出函数
void Outsnake(lei *p);                //输出蛇
void Suspend(lei *q);                 //空格键暂停
void Inherit(lei *p);                 //蛇身传递  
lei* Createfood(lei *q);              //显示随机食物
void Speedhint(int _score);           //速度信息提示
void Setspeed_reduce();               //减速
void Setspeed_plus();                 //加速
int Collision(lei *q);                //失败判定
void Endprompt();                     //结束页面
void Destruction(lei *p);             //释放蛇结点空间
int Cmpfunc(const void *a, const void *b);//排序方式
void Recordeddata();                  //保存成绩

void Setpox(int x=0,int y=0)
{
    COORD pox={x,y};
    HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,pox);
}
void Setcolor(unsigned short color)
{
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hCon,color);
}
void Recordeddata()   //保存成绩
{
    time_t timep;
    struct tm *ti;
    time(&timep);
    ti=localtime(&timep);              //获取系统时间
    record *gdata=(record*)malloc(sizeof(record));
    gdata->year=ti->tm_year;//年
    gdata->mon=ti->tm_mon;  //月
    gdata->day=ti->tm_mday; //日
    gdata->hour=ti->tm_hour;//时
    gdata->min=ti->tm_min;  //分
    gdata->sec=ti->tm_sec;  //秒
    gdata->fraction=score;
    FILE *fp=fopen("out.txt","ab");
    if(fp==NULL)
        fp=fopen("out.txt","wb");
    fwrite(gdata,sizeof(record),1,fp);
    fclose(fp);         //删除文件指针
    free(gdata);
}

int Cmpfunc(const void *a,const void *b)
{
   return(*(int*)b-*(int*)a);//降序排序
}

void Rankinglist()   //排行榜显示
{
    system("cls");    
    int i=0;
    record gdata[1000];
    FILE *fp=fopen("out.txt","rb");
    if(fp==NULL)
    {
        Setpox(56,12);
        printf("暂无记录");
        Setpox();
        return;
    }
    rewind(fp);
    while(!feof(fp))                           //feof检查文件是否结束,遇到结束符,返回非零
    {
        fread(&gdata[i],sizeof(struct record),1,fp);
        i++;
    }
    qsort(gdata, i-1, sizeof(record), Cmpfunc);//按得分排序
    Setpox(52,3);
    Setcolor(12);
    printf("排行榜");
    Setpox(42,5);
    Setcolor(14);
    printf("得分\t\t\t时间\n");
    Setcolor(15);
    for(int j=0;j<i-1;j++)                     //总共有i-1条记录信息
    {
        Setpox(43,7+j*2);
        printf("%d\t\t",gdata[j].fraction);
        printf("%d/%02d/%02d ",gdata[j].year+1900,gdata[j].mon+1,gdata[j].day);
        printf("%02d:%02d:%02d\n",gdata[j].hour,gdata[j].min,gdata[j].sec );
    }
    fclose(fp);                               //删除文件指针
    Setpox();
}

void Gamedescription()       //游戏说明
{
    system("cls");
    Setpox(55,4);
    printf("游戏说明");
    Setcolor(12);
    Setpox(34,8);
    printf("1.由“A”“W”“D”“S”分别控制左、上、右、下的方向");
    Setpox(34,10);
    printf("2.由空格键控制暂停游戏和继续游戏");
    Setpox(34,12);
    printf("3.当蛇首撞墙或咬到蛇身时游戏结束");
    Setpox(34,14);
    printf("4.按Q键可加速,按E键可减速");
    Setpox(34,16);
    printf("5.速度自动增加到一定程度或按减速键后,将不再继续加速");
    Setpox(34,18);
    printf("6.小蛇每吃到一个食物,分数就会增加。初始分数为零");
    Setpox(34,20);
    printf("7.小蛇的初始长度为6,每吃到一个食物长度就会加一");
    Setpox(34,22);
    printf("8.小蛇的初始速度为300MS/格,速度会自动根据得分情况增加");
    Setpox(34,24);
    printf("9.以上按键皆不区分大小写");
}

void Setspeed_plus()   //加速可以用参数
{
    if(speed>100)
        speed-=100;
    else
        speed/=2;
    scoreup*=2;          //每个食物的分数翻倍
    nfood_1=0;
    nfood_2=0;
}

void Setspeed_reduce()//减速
{
    if(speed>=100)
        speed+=100;
    else
        speed*=2;
    scoreup/=2;          //每个食物的分数减半
    bool_=0;
}

void Speedhint()   //速度提示
{
    Setcolor(11);
    if(nfood_2<2)             //该速度阶段前两个食物才显示内容
    {
        switch(speed)
        {
        case 300:
            Setpox(86,15);
            printf("朋友,别嫌慢");
            Setpox(86,17);
            printf("这才刚刚开始");
            break;
        case 200:
            Setpox(86,15);
            printf("嗨,朋友,现在快一点了");
            Setpox(86,17);
            printf("是原来的1.5倍");
            break;
        case 100:
            Setpox(83,15);
            printf("我明白你已经厌倦了这龟速");
            Setpox(83,17);
            printf("所以我把速度变成刚才的两倍了");
            break;
        case 50:
            Setpox(86,15);
            printf("自动加速到此为止了");
            Setpox(86,17);
            printf("这是真正的挑战");
            break;
        }
    }
    else
    {
        if(nfood_2%12==0)//不自动加速(减速或自动加速结束)时做出提示
        {
            Setpox(86,15);
            printf("如果你想更快!");
             Setpox(86,17);
            printf("可以按Q键!!!");
        }
        else
        {
            Setpox(83,15);
            printf("                            ");
            Setpox(83,17);
            printf("                            ");
        }
    }

void Frame(int n)                      //画边框
{
    int i;
    Setpox(17,5);
    Setcolor(11);
    printf("⊙--------------------------");
    Setcolor(14);
    printf("oOOo");
    Setcolor(11);
    printf("----------");
    Setcolor(14);
    printf("(_)");
    Setcolor(11);
    printf("----------");
    Setcolor(14);
    printf("oOOo");
    Setcolor(11);
    printf("--------------------------⊙");
    for(i = 6;i<=19;i++)               //竖边框
    {
        Setpox(17,i);
        printf("§");
        Setpox(102,i);
        printf("§");
    }
    Setpox(17,20);
    printf("⊙---------------------------------------");
    Setcolor(14);
    printf("☆☆☆");
    Setcolor(11);
    printf("--------------------------------------⊙");
    Setpox(53,23);//56 24
    printf("∵ˇˇˇˇˇˇˇ∵");
    Setpox(53,26);
    printf("∴^^^^^^^∴");
    if(n==0)                       //主页面的字符图案
    {
        Setpox(57,2);
         Setcolor(6);
        printf("\\\\\\|///");
        Setpox(54,3);
        printf("\\\\");
        Setpox(58,3);
        Setcolor(15);
        printf(".-.-");
        Setpox(65,3);
        Setcolor(6);
        printf("//");
        Setpox(55,4);
        Setcolor(14);
        printf("(");
        Setpox(58,4);
        Setcolor(15);
        printf(".@.@");
           Setpox(65,4);
        Setcolor(14);
        printf(")");//
    }
    else                            //游戏结束页面的字符图案
    {
        Setpox(57,1);
         Setcolor(6);
        printf("∧    ∧");
        Setpox(55,2);
        printf(" /  \\  /  \\");
        Setpox(54,3);
        printf("( ︹ ˇ ︹ )");
        Setpox(54,4);
        printf("く ");
        Setcolor(15);
        printf("⊙    ⊙");
        Setcolor(14);
        printf(" / ");
        Setpox(55,5);
        printf("く   い   /");
        Setpox(57,6);
        printf("く 々 √");
        Setpox(60,7);
        printf("ˇ");
    }
}
void Createmap()        //地图页面输出函数
{
    int i;
    Setcolor(11);
    for(i=2;i<27;i++)
    {
        Setpox(2,i);
        printf("◆");
        Setcolor(3);
        for(int j=0;j<29;j++)
            printf("■");
        Setcolor(11);
        printf("◆");
    }
    Setpox(2,1);
    for(i=0;i<31;i++)//上边框
    {
        printf("◆");
    }
    Setpox(2,27);
    for(i=0;i<31;i++)//下边框
    {
        printf("◆");
    }
    Setpox(80,3);
    printf("方向键:");
    Setpox(88,4);
    printf("左 <———> A");
    Setpox(88,5);
    printf("上 <———> W");
    Setpox(88,6);
    printf("右 <———> D");
    Setpox(88,7);
    printf("下 <———> S");
    Setpox(80,9);
    printf("暂停键: 空格");
    Setpox(80,12);
    printf("得分");
    Setpox(80,22);
    printf("按Q键可加速,按E键可减速");

    Setcolor(10);
    for(i=0;i<30;i++)
    {
        Setpox(70,i);
        printf("§");
    }
    Setpox(82,14);
    printf("∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞");
    Setpox(82,19);
    printf("∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞");
    for(i=15;i<19;i++)
    {
        Setpox(81,i);
        printf("φ");
        Setpox(111,i);
        printf("φ");
    }
}

lei* Createfood(lei *q)   //显示随机食物
{
    lei *p,*k;
    k=(lei*)malloc(sizeof(lei));
    k->next=NULL;
    zhe:
    p=q->next;
    srand((unsigned)time(NULL));
//    srand(rand()+(unsigned int)time(NULL));
    while((k->x=rand()%57+4)%2!=0)  //确保食物显示在格子内
    {;}
    k->y=rand()%24+3;
    while(p!=NULL)
    {
        if((k->x==p->x&&k->y==p->y))//如果新食物与蛇身重合,则重新生成
            goto zhe;
        p=p->next;
    }
    Setcolor(12);
    Setpox(k->x,k->y);
    printf("●");
    return k;
}

void Inherit(lei *p)      //蛇身传递  
{
    lei *r=p->next;       //p为第一个结点,即蛇首 
    if(r->next!=NULL)
        Inherit(r);
    r->x=p->x;            //把前一个结点的坐标传递给后一个结点    跟随
    r->y=p->y;
}

void Outsnake(lei *p)     //输出蛇
{
    lei *r,*k=p->next;
    Setcolor(14);
    while(p->next!=NULL)
    {
        r=p->next;
        p=r;
        Setpox(r->x,r->y);
           printf("★");
    } 
    if(k->x!=p->x||k->y!=p->y)
    {
        Setpox(p->x,p->y);    //覆盖尾迹
        Setcolor(3);
        printf("■");
    }
    Setpox();
    Sleep(speed);
}

void Suspend(lei *q)      //空格键暂停
{
    Setpox();
    while(1)
    {
        if(kbhit()&&getch()==' ')//kbhit函数,非阻塞地响应键盘输入事件
            return;
    }
}

int Collision(lei *q)     //失败判定
{
    lei *p=q->next,*r=p->next;
    if(p->x==2||p->x==62||p->y==1||p->y==27)//撞墙
        return 1;
    while(r->next!=NULL)
    {
        if(p->x==r->x&&p->y==r->y)          //咬到自己
            return 1;
        r=r->next;
    }
    return 0;
}

void Destruction(lei *p) //结束后释放蛇结点空间
{
    lei *q=p,*r;
    while(q->next!=NULL)
    {
        r=q;
        q=q->next;
        free(r);
    }
    free(q);
}

void Gamemodule()           //方向控制及游戏运行
{
    lei *q,*r,*h;
    char str='d',str1='d';
    q=(lei*)malloc(sizeof(lei));
    q->next=NULL;
    score=0;                             //设置初始分数
    nfood_1=0;
    nfood_2=0;
    speed=300;                           //设置初始速度
    system("cls");
    for(int i=6;i<19;i=i+2)                  //q为头结点  初始化蛇,分配6个结点
    {
           r=(lei *)malloc(sizeof(lei));
          r->x=i;
           r->y=5;
           r->next=q->next;
           q->next=r;
    }
    Createmap();                //输出地图
       h=Createfood(q);
       while(1)
    {
           if(Collision(q))        //撞墙或咬到自己
        {
            Recordeddata();     //保存分数到本地文件夹
               Destruction(q);     //销毁蛇身结点,释放存储空间
            Endprompt();        //结束时的选择
               break;
        }
           Setpox(86,12);
        Setcolor(13);
           printf("%d",score);     //分数的输出
        Outsnake(q);            //输出蛇
        Setpox();
           Speedhint();            //速度的提示
           if(kbhit())             //按键了
        {
               str=getch();
               if(str==' ')        //如果是空格
            {
                   Suspend(q);     //暂停函数
                    str=str1;       //str1  记录暂停之前的方向
            }
        }
        if(str<91)              //兼容大写
            str+=32;
           if((str=='d'&&str1=='a')||(str=='s'&&str1=='w')||(str=='a'&&str1=='d')||(str=='w'&&str1=='s'))
               str=str1;
        if(str!='a'&&str!='d'&&str!='w'&&str!='s')
        {
            if(str=='q')          //按q加速
            {
                Setspeed_plus();
                //bool_=1;        可恢复自动加速
            }
            if(str=='e')          //按e减速
            {
                Setspeed_reduce();
                bool_=0;          //按减速之后就不再自动加速
            }
            str=str1;
        }
        if(str=='d'&&str1!='a')         //右
        {
               str1=str;
               if(q->next->x+2==h->x&&q->next->y==h->y)
            {
                h->next=q->next;                       //吃到食物
                  q->next=h;
                     h=Createfood(q);                       //生成新的食物
                   score+=scoreup;                        //分数增加
                nfood_2++;                             //记录吃到的食物数,用于提示信息的显示条件
                nfood_1++;                             //记录吃到的食物数,用于自动加速的判断
                   if(((nfood_1==5&&speed>100)||(nfood_1==10&&speed==100))&&bool_)//前两次吃5个自动加速,第三次吃10个自动加速
                {                                                          // bool_   减速之后不在进行加速
                    Setspeed_plus();
                }
            }
               else
            {
                   Inherit(q->next);
                   q->next->x+=2;
            }
        }
           else
        {
            if(str=='s'&&str1!='w')      //下
            {
                   str1=str;
                   if(q->next->x==h->x&&q->next->y+1==h->y)
                {
                       h->next=q->next;
                       q->next=h;
                       h=Createfood(q);
                       score+=scoreup; 
                    nfood_2++;
                    nfood_1++;
                       if(((nfood_1==5&&speed>100)||(nfood_1==10&&speed==100))&&bool_)
                    {
                          Setspeed_plus();
                    }
                }
                   else
                {
                       Inherit(q->next);
                       q->next->y+=1;
                }
            }
               else
            {
                   if(str=='a'&&str1!='d')   //左
                {
                       str1=str;
                    if(q->next->x-2==h->x&&q->next->y==h->y)
                    {
                           h->next=q->next;
                           q->next=h;
                        h=Createfood(q);
                           score+=scoreup; 
                        nfood_2++; 
                        nfood_1++;
                           if(((nfood_1==5&&speed>100)||(nfood_1==10&&speed==100))&&bool_)
                        {
                               Setspeed_plus();
                        }
                    }
                    else
                    {
                           Inherit(q->next);
                        q->next->x-=2;
                    }
                }
                   else
                {
                       if(str=='w'&&str1!='s')//上
                    {
                          str1=str;
                         if(q->next->x==h->x&&q->next->y-1==h->y)//吃到食物,插入新节点,创建新食物
                        {
                               h->next=q->next;
                               q->next=h;
                            h=Createfood(q);
                            score+=scoreup; 
                            nfood_2++; 
                            nfood_1++;
                              if(((nfood_1==5&&speed>100)||(nfood_1==10&&speed==100))&&bool_)
                            {
                                   Setspeed_plus();
                            }
                        }
                           else                                    //没吃到,蛇身结点传递
                        {
                               Inherit(q->next);
                               q->next->y-=1;
                        }
                    }
                }
            }
        }
    }
}

void Endprompt()            //结束页面
{
    int n;
    zhe:
    system("cls");
    Setcolor(12);
    Setpox(54,8);
      printf("游戏结束了朋友\n");
    Setpox(54,10);
    Setcolor(14);
    printf("你的得分是:%d",score);
    Setpox(53,12);
    Setcolor(12);
    printf("接下来你有三个选择");
    Setcolor(14);
    Setpox(22,16);
    printf("1.你是想重新开始");
    Setpox(44,16);
    printf("2.还是想去主页看看");
    Setpox(68,16);
    printf("3.难道你想退出游戏? 不!你不想!!!");
    Frame(1);
    Setpox(56,24);
    printf("前往:");
    scanf("%d",&n);
    switch(n)
    {
    case 1:
            system("cls");
         Gamemodule();
         break;
    case 2:return;
    case 3:
        system("cls");
        Setpox(56,10);
        printf("再见喽");
        Setpox();
        exit(0);
    default:
        printf("你输入错了,再给你次机会,朋友\n");
        printf("按任意键继续");
        getch();
        goto zhe;
    }
}

int main()
{
    int number;
    zhe:
    system("cls");
    Setpox(53,8);
    Setcolor(14);
       printf("贪 吃 蛇 大 作 战");
       Setpox(26,14);
       printf("1.开始游戏");
    Setpox(46,14);
       printf("2.游戏说明");
    Setpox(66,14);
    printf("3.得分排行");
    Setpox(86,14);
    printf("4.退出游戏");
    Frame(0);
       Setpox(56,24);
    Setcolor(14);
       printf("前往:"); 
    scanf("%d",&number);
    switch(number)
    {
        case 1:
             Gamemodule();
            goto zhe;
        case 2:
               Gamedescription();
            Setpox();
            getch();
            goto zhe;
         case 3:
            Rankinglist();
            getch();
            goto zhe;
         case 4:
            system("cls");
            Setpox(56,10);
            printf("再见喽");
            Setpox();
            exit(0);
        default:
            printf("朋友,请输入上面有的数字!\n");
            printf("任意键继续");
            getch();
            goto zhe;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值