⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game5.c

📁 再来一个贪吃蛇游戏【c语言】
💻 C
字号:
#include <stdio.h>
#include "graphics.h"
#include "math.h"
#include "time.h"
#include "ctype.h"
#include "bios.h"
#include "conio.h"
#include "dos.h"
#include "stdlib.h"
#include "alloc.h"
#include "string.h" 


#define closegr closegraph
/* direction key */
#define UP 0x4800
#define DOWN 0x5000
#define RIGHT 0x4b00
#define LEFT 0x4d00
/* control key */
#define ESC 0x11b
#define ENTER 0x1c0d
#define SPACE 0x3920
#define F2 0x3c00
/* ridge of game */
#define UPEST 1
#define DOWNEST 29
#define LEFTEST 1
#define RIGHTEST 42
#define head 0

void initgr(void);            /* 图形初始化 */
void game(long speed);        /* 游戏核心 */
long chooselevel(void);       /* 开始控制菜单 */
void newfruit(int);           /* 生成新目标 */
void mark(int);               /* 分数管理 */
void end(int);                /* 游戏结束 */
void high(void);              /* 最高成绩 */
void grgets(int x,int y,int size,int color,char s[]);  /* 图形下的gets */
void welcome(void);           /* 欢迎画面 */
void clean(void);             /* 清除记录 */

typedef struct Point{                                     /* the points in snake and target */
        int x;
        int y;
    } point;
point snake[100]={{1,1}},fruit={6,6};
long speed;
int record[3];
char *name[3];
FILE *fp;

int main(void)
{
  int i;
  char *s;
  initgr();            /* 图形初始化 */
  welcome();           /* 欢迎画面 */
  do{                  /* 提取记录 */
      fp=fopen("mark.dat","r");
      fscanf(fp,"%d%d%d",&record[0],&record[1],&record[2]);
      fgets(s,10,fp);
      for(i=0;i<=2;i++){
          name[i]=(char *)malloc(100);
          fscanf(fp,"%s",name[i]);
      }
      fclose(fp);
      speed=chooselevel(); /* 选择速度 */
      setcolor(YELLOW);
      rectangle(0,0,631,436);
      game(speed);
  }while(1);
}

void initgr(void)    /* 图形初始化 */
{
  int gd=DETECT, gm=0;
  registerbgidriver(EGAVGA_driver);
  initgraph(&gd, &gm, "c:\turboc2");
}

void game(long speed)
{
    int top=0;                                            /* length of snake */
    int key;
    int direction=3;
    int a=1,b=1,c,d;
    int i,j,k;
    mark(top);
    setfillstyle(SOLID_FILL,2);
    bar((fruit.x-1)*15+1,(fruit.y-1)*15+1,
           fruit.x*15,fruit.y*15);
    while(1){
        delay(speed);                                     /* delay */
        if(kbhit()!=0){                                   /* is there a pressure on keyboard */
            key=bioskey(0);
            switch(key){
                case UP:direction=(direction==2?2:1);     /* decide the dirction */
                        break;
                case DOWN:direction=(direction==1?1:2);
                          break;
                case LEFT:direction=(direction==4?4:3);
                          break;
                case RIGHT:direction=(direction==3?3:4);
                           break;
                case SPACE:bioskey(0);                    /* pause */
            }
        }
        switch(direction){
            case 1:b--;                                   /* go up */
                   break;
            case 2:b++;                                   /* go down */
                   break;
            case 3:a++;                                   /* go left */
                   break;
            case 4:a--;                                   /* go right */
        }
        if(b<UPEST||b>DOWNEST||                           /* if the snake out of the ridge */
           a<LEFTEST||a>RIGHTEST)
           break;                                         /* end game */
        if(a==fruit.x&&b==fruit.y){                       /* if the snake ate the fruit */
           top++;                                         /* add 1 to length of snake */
           newfruit(top);/* new fruit */
           mark(top);
        }
        else{
            c=snake[top].x;
            d=snake[top].y;
        }
        for(i=top-1;i>=head;i--){                         /* move the snake */
            if(snake[i].x==a&&snake[i].y==b)              /* if the head hit itself */
                goto fail;                                /* end game */
            snake[i+1].x=snake[i].x;
            snake[i+1].y=snake[i].y;
        }
        snake[head].x=a;
        snake[head].y=b;
        setfillstyle(SOLID_FILL,2);                            /* draw fruit */
        bar((fruit.x-1)*15+1,(fruit.y-1)*15+1,
        fruit.x*15,fruit.y*15);                                  /* draw the snake */
        if(a==fruit.x&&b==fruit.y){                       /* have eaten,draw head */
            setfillstyle(SOLID_FILL,YELLOW);
            bar((snake[head].x-1)*15+1,(snake[head].y-1)*15+1,
                 snake[head].x*15,snake[head].y*15);
        }
        else{                                             /* haven't eaten,draw head;clean tail */
            setfillstyle(SOLID_FILL,0);
            bar((c-1)*15+1,(d-1)*15+1,c*15,d*15);
            setfillstyle(SOLID_FILL,YELLOW);
            bar((snake[head].x-1)*15+1,(snake[head].y-1)*15+1,
                 snake[head].x*15,snake[head].y*15);
            }
    }
    fail:end(top);
}

void newfruit(int top)
{
    int flag,i;
    int seed;
    srand(time(0));
    do{
        flag=0;                                            /* 获取一个位置 */
        fruit.x=(int)(rand())%41+1;
        fruit.y=(int)(rand())%28+1;
        for(i=top;i>=0;i--)                              /* 不与蛇身重复 */
            if(snake[i].x==fruit.x&&snake[i].y==fruit.y)
                flag++;
    }while(flag);
}

long chooselevel(void)             /* 开始控制菜单 */
{
    int j=0,k=3;
    int key,flag=0;
    long speed;
    setcolor(LIGHTBLUE);            /* 绘制菜单 */
    settextstyle(0,0,3);
    outtextxy(250,150,"SNAKE");
    settextstyle(0,0,2);
    outtextxy(200,190,"Choose a level:");
    outtextxy(200,280,"<-,->  to choose");
    outtextxy(200,300,"ENTER  to play");
    outtextxy(200,320,"F2     to check record");
    outtextxy(200,340,"DELETE to reset record");
    outtextxy(200,360,"ESC    to exit");
    setfillstyle(SOLID_FILL,CYAN);
    bar(197,227,444,253);
    setfillstyle(SOLID_FILL,BLACK);
    bar(200,230,441,250);
    do{                                 /* 选择界面 */
        setfillstyle(SOLID_FILL,YELLOW);
        bar(201+110*j,231,220+110*j,249);
        setfillstyle(SOLID_FILL,BLACK);
        bar(201+110*k,231,220+110*k,249);
        key=bioskey(0);
        switch (key){
            case LEFT:if(j!=2){
                          k=j;
                          j++;
                      }
                      break;
            case RIGHT:if(j!=0){
                           k=j;
                           j--;
                       }
                       break;
            case ENTER:flag=1;       /* 准备跳出 */
                       break;
            case F2:high();          /* 显示最高记录 */
                    setcolor(LIGHTBLUE); /* 重绘界面 */
                    settextstyle(0,0,3);
                    outtextxy(250,150,"SNAKE");
                    settextstyle(0,0,2);
                    outtextxy(200,190,"Choose a level:");
                    outtextxy(200,280,"<-,->  to choose");
                    outtextxy(200,300,"ENTER  to play");
                    outtextxy(200,320,"F2     to check record");
                    outtextxy(200,340,"DELETE to reset record");
                    outtextxy(200,360,"ESC    to exit");
                    setfillstyle(SOLID_FILL,CYAN);
                    bar(197,227,444,253);
                    setfillstyle(SOLID_FILL,BLACK);
                    bar(200,230,441,250);
                    break;
            case 0x5300:         /* 清除记录 */
            case 0x532e:clean();
                        break;
            case ESC:closegr();  /* 退出 */
                     exit(0);
        }
    }while(flag!=1);
    switch (j){                  /* 决定速度 */
        case 2:speed=15000;break;
        case 1:speed=25000;break;
        case 0:speed=40000;break;
    }
    cleardevice();               /* 清屏 */
    return speed;
}

void mark(int top)                 /* 分数管理 */
{
    char s[5],c[5];
    setcolor(RED);
    itoa(top,s,10);
    itoa(record[(speed-15000)/10000],c,10);
    setfillstyle(SOLID_FILL,GREEN);  /* 绘制分数栏 */
    bar(1,438,631,480);
    settextstyle(0,0,3);
    outtextxy(30,450,"RECORD:");
    outtextxy(200,450,c);
    outtextxy(410,450,"SCORE:");
    outtextxy(560,450,s);
}

void end(int top)                          /*游戏结束*/
{
    char *t;
    settextstyle(0,0,1);
    setcolor(BLACK);
    setfillstyle(SOLID_FILL,LIGHTGRAY);
    bar(200,180,440,300);
    setfillstyle(SOLID_FILL,BLACK);
    rectangle(205,185,435,295);
    if(top>record[(speed-15000)/10000]){        /* 如果蛇长比记录大 */
        outtextxy(250,220,"congratulations!");      /* 庆祝一下 */
        outtextxy(230,240,"You broke the record!");
        sprintf(t,"Your score is %d",top);
        outtextxy(255,260,t);
        sleep(2);
        while(kbhit()!=0)
            bioskey(0);                                   /* 等一会儿 */
        record[(speed-15000)/10000]=top;            /* 蛇长变成记录 */
        setfillstyle(SOLID_FILL,LIGHTGRAY);         /* 绘制姓名输入窗口 */
        bar(160,228,480,268);
        setfillstyle(SOLID_FILL,BLACK);
        rectangle(165,233,475,263);
        outtextxy(175,246,"Your name:");
        grgets(260,246,1,BLACK,name[(speed-15000)/10000]); /* 输入姓名 */
        fp=fopen("mark.dat","w");                          /* 存入新数据 */
        fprintf(fp,"%d\n%d\n%d\n",record[0],record[1],record[2]);
        fprintf(fp,"%s\n%s\n%s\n",name[0],name[1],name[2]);
        fclose(fp);

    }
    else{
        outtextxy(275,230,"You failed");                  /* 分数比记录小 */
        sprintf(t,"Your score is %d",top);                /* 失败了 */
        outtextxy(255,260,t);
        sleep(1);
        bioskey(0);
    }
    cleardevice();
}

void high(void)                               /* 最高成绩 */
{
    int i;
    char *s;
    cleardevice();
    settextstyle(0,0,2);                                   /* 显示记录 */
    for(i=0;i<=2;i++){
        sprintf(s,"LEVEL %d: %10s %5d",i+1,name[2-i],record[2-i]);
        outtextxy(130,200+i*50,s);
    }
    bioskey(0);
    cleardevice();
}

void grgets(int x,int y,int size,int color,char s[])    /* 图形下的gets */
{
    int i=-1,j;
    char c;
    settextstyle(0,0,size);
    setcolor(color);
    setfillstyle(SOLID_FILL,LIGHTGRAY);
    strcpy(s,"                ");           /* 清空姓名 */
    do{
        i++;
        c=getch();                          /* 获取字符 */

        if(c==8&&i!=0){                     /* 是退格键,退格 */
            s[i-1]=0;
            i-=2;
        }
        else
            s[i]=c;                          /* 加入字符 */
        bar(x,y,x+8*(i+3)*size,y+10);
        outtextxy(x,y,s);                    /* 显示姓名 */
    }while(s[i]!=13);                        /* 直到字符为回车 */
    s[i]='\0';
    if(strlen(s)==0)                         /* 如果没有输入 */
        strcpy(s,"NONAME");                  /* 新姓名为NONAME */
}

void welcome(void)
{
    int colors[5]={9,10,11,12,13};           /* 五种颜色 */
    int i;
    settextstyle(0,0,2);
    setcolor(YELLOW);
    outtextxy(170,390,"Designer:SUN");        /* 设计者 */
    outtextxy(170,420,"Program:SUN");         /* 程序编制者 */
    rectangle(170,150,460,350);
    settextstyle(0,0,6);
    while(kbhit()==0){                        /* 如果没有按键 */
        setcolor(colors[1]);
        outtextxy(196,160,"S");               /* 显示SNAKE EAT BEAN(蛇吃豆)*/
        setcolor(colors[2]);
        outtextxy(246,160,"N");
        setcolor(colors[3]);
        outtextxy(296,160,"A");
        setcolor(colors[4]);
        outtextxy(346,160,"K");
        setcolor(colors[5]);
        outtextxy(396,160,"E");
        setcolor(colors[3]);
        outtextxy(246,230,"EAT");
        setcolor(colors[2]);
        outtextxy(220,300,"BEAN");
        for(i=0;i<=5;i++){                   /* 换种颜色 */
            colors[i]++;
            if(colors[i]==16)
                colors[i]=9;
        }
        delay(55000);                         /* 等一会儿 */
    }
    bioskey(0);
    cleardevice();
}

void clean(void)                              /* 清除记录 */
{
    int i;
    fp=fopen("mark.dat","w");                 /* 清文件 */
    fprintf(fp,"%d\n%d\n%d\n%s\n%s\n%s\n",0,0,0,"NONAME","NONAME","NONAME");
    fclose(fp);
    for(i=0;i<=2;i++){                        /* 清记录 */
        record[i]=0;
        strcpy(name[i],"NONAME");
    }
    outtextxy(10,10,"OK!");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -