C++:贪吃蛇

来源:互联网 发布:pm2.5数据网 编辑:程序博客网 时间:2024/04/29 16:31

1100多行实现贪吃蛇,带颜色,有速度选择,有难度选择,有分数保存和读取等。

#include <iostream>#include <windows.h>#include <conio.h>#include <cstdio>#include <ctime>#include <cstdlib>#include <istream>#include <fstream>using namespace std;void hide_cursor(){CONSOLE_CURSOR_INFO cci = {1, 0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);}//enum Direction{UP,LEFT,DOWN,RIGHT}D,D_temp;//int i,j;//int speed;//空格键ASCII 32 回车 13 Esc 27//int diff;void gotoxy(int x,int y){COORD loc={x,y};HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(hOutput,loc);}class Interface{public:void Display();//开始界面void Empty();//清空界面void Dis_Help();//帮助界面int Move();//移动箭头int Speed_();//速度选择界面int Difficulty();//难度选择界面void Colour(int c);//颜色int R_Speed();//返回速度数值int R_Diff();//返回难度数值private:int r,l;char ch;int Speed,Diff;};int Interface::R_Speed(){    return Speed;}int Interface::R_Diff(){    return Diff;}void Interface::Colour(int c){    switch(c)    {    case 1:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);//红色        break;    case 2:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);//绿色        break;    case 3:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);//蓝色        break;    case 4:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);//设置红色和绿色相加        break;    case 5:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);//设置红色和蓝色相加        break;    case 6:        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);//设置绿色和蓝色相加        break;    default:        break;    }}void Interface::Empty(){    for(int i=1;i<24;i++)    {        for(int j=1;j<79;j++)        {                gotoxy(j,i);                cout << " ";        }    }}void Interface::Display(){    Empty();    Colour(4);    gotoxy(37,6);    cout << "贪 吃 蛇 ";r = 10;Sleep(100);gotoxy(36,r);cout << "开 始 游 戏 " ;Sleep(100);r = r + 2 ;gotoxy(36,r);cout << "游 戏 记 录 " ;Sleep(100);r = r + 2 ;gotoxy(36,r);cout << "游 戏 帮 助 " ;Sleep(100);r = r + 2;gotoxy(36,r);cout << "退 出 游 戏 " ;}void Interface::Dis_Help(){    Empty();    Colour(5);    gotoxy(20,8);    cout << "W(w)S(s)A(a)D(d)来控制上下左右\n";    gotoxy(20,10);    cout << "空格(Space)来进行开始游戏或者暂停游戏\n";    gotoxy(20,12);    cout << "回车(Enter)来开始进行所选择的选项\n";    gotoxy(28,14);    cout << "按下Esc返回上层界面!";    ch = getch();    while(ch!=27)    {        ch = getch();    }    Empty();}int Interface::Move(){r = r - 6 ;Colour(4);gotoxy(34,r);cout << ">" ;gotoxy(48,r);cout << "<" ;ch = getch();while(ch!=13){switch(ch){case 'w':case 'W':if(r==12 || r==14 || r==16){gotoxy(34,r);cout << " ";gotoxy(48,r);cout << " ";r = r - 2 ;gotoxy(34,r);cout << ">";gotoxy(48,r);cout << "<";break;}elsebreak;case 's':case 'S':if(r==10 || r==12 || r==14){gotoxy(34,r);cout << " ";gotoxy(48,r);cout << " ";r = r + 2;gotoxy(34,r);cout << ">";gotoxy(48,r);cout << "<";break;}elsebreak;        default:            break;}ch = getch();}if(ch == 13){return r;}}int Interface::Speed_(){    Empty();    int s;    Sleep(100);    gotoxy(33,5);    cout << "选 择 速 度";    r = 8;    Sleep(100);gotoxy(36,r);cout << "入 门 " ;r = r + 2 ;Sleep(100);gotoxy(36,r);cout << "初 级 " ;r = r + 2 ;Sleep(100);gotoxy(36,r);cout << "中 级 " ;r = r + 2;Sleep(100);gotoxy(36,r);cout << "高 级 " ;r = r - 6 ;gotoxy(34,r);cout << ">" ;gotoxy(42,r);cout << "<" ;ch = getch();while(ch!=27 && ch!=13)    {        switch(ch)        {        case 'W':        case 'w':            if(r==10 || r==12 || r==14)            {                gotoxy(34,r);cout << " ";gotoxy(42,r);cout << " ";r = r - 2 ;gotoxy(34,r);cout << ">";gotoxy(42,r);cout << "<";break;            }            else                break;        case 'S':        case 's':            if(r==8 || r==10 || r==12)            {                gotoxy(34,r);cout << " ";gotoxy(42,r);cout << " ";r = r + 2;gotoxy(34,r);cout << ">";gotoxy(42,r);cout << "<";break;            }            else                break;        default:            break;        }        ch = getch();    }    if(ch==27)    {        return 2;    }    if(ch==13)    {        switch(r)        {        case 8:            Speed = 200;            return 1;            break;        case 10:            Speed = 150;            return 1;            break;        case 12:            Speed = 100;            return 1;            break;        case 14:            Speed = 50;            return 1;            break;        }    }}int Interface::Difficulty(){    Empty();    int s;    Sleep(100);    gotoxy(33,5);    cout << "选 择 难 度";    r = 8;    Sleep(100);gotoxy(36,r);cout << "入 门 " ;r = r + 2 ;Sleep(100);gotoxy(36,r);cout << "初 级 " ;r = r + 2 ;Sleep(100);gotoxy(36,r);cout << "中 级 " ;r = r + 2;Sleep(100);gotoxy(36,r);cout << "高 级 " ;r = r - 6 ;gotoxy(34,r);cout << ">" ;gotoxy(42,r);cout << "<" ;ch = getch();while(ch!=27 && ch!=13)    {        switch(ch)        {        case 'W':        case 'w':            if(r==10 || r==12 || r==14)            {                gotoxy(34,r);cout << " ";gotoxy(42,r);cout << " ";r = r - 2 ;gotoxy(34,r);cout << ">";gotoxy(42,r);cout << "<";break;            }            else                break;        case 'S':        case 's':            if(r==8 || r==10 || r==12)            {                gotoxy(34,r);cout << " ";gotoxy(42,r);cout << " ";r = r + 2;gotoxy(34,r);cout << ">";gotoxy(42,r);cout << "<";break;            }            else                break;        default:            break;        }        ch = getch();    }    if(ch==27)    {        return 2;    }    if(ch==13)    {        switch(r)        {        case 8:            Diff = 1;            return 1;            break;        case 10:            Diff = 2;            return 1;            break;        case 12:            Diff = 3;            return 1;            break;        case 14:            Diff = 4;            return 1;            break;        }    }}class Wall{public:    friend class Snake;    friend class Food;void Display(Interface &I);//开始时界面int Dis_(Interface &I);//进入游戏分割分数与游戏void Dis_W(Interface &I);//按照各种难度输出墙void Display1(Interface &I);//结束时界面private:    int w[100][2];    int q;//不同难度数组个数不一样};int Wall::Dis_(Interface &I){    I.Empty();    for(int i=1;i<40;i++)    {        I.Colour(2);        gotoxy(i,4);        cout << "#";        gotoxy(79-i,4);        cout << "#";        Sleep(50);    }}void Wall::Display(Interface &I){    int i,j;for(i=0;i<13;i++)//高0-24,宽0-79空白范围是1到23 1 到77    {        if(i==0 || i==12)            I.Colour(2);        if(i==1 || i==11)            I.Colour(5);        if(i==2 || i==10)            I.Colour(4);        if(i==3 || i==9)            I.Colour(3);        if(i==4 || i==8)            I.Colour(6);        if(i==5 || i==7)            I.Colour(1);        for(j=0;j<80;j++)        {            if(i%2==0 && i!=12)            {                gotoxy(j,i);                cout << "#";                gotoxy(79-j,24-i);                cout << "#";            }            if(i%2==1)            {                gotoxy(79-j,i);                cout << "#";                gotoxy(j,24-i);                cout << "#";            }            if(i == 12)            {                gotoxy(j,i);                cout << "#";                gotoxy(79-j,i);                cout << "#";            }            Sleep(5);        }    }    for(i=39;i>=1;i--)//39 40 为最中间    {        if(i == 39)        {            for(j=12;j>=1;j--)            {                gotoxy(39,j);                cout << " ";                gotoxy(39,24-j);                cout << " ";                gotoxy(40,j);                cout << " ";                gotoxy(40,24-j);                cout << " ";                Sleep(200);            }        }        else        {            for(j=1;j<=23;j++)            {                gotoxy(i,j);                cout << " ";                gotoxy(79-i,j);                cout << " ";            }            Sleep(100);        }    }    for(i=1;i<24;i++)    {        I.Colour(2);        gotoxy(0,i);        cout << "#";        gotoxy(79,24-i);        cout << "#";        Sleep(50);    }}void Wall::Dis_W(Interface &I){    int i,j,D;    D = I.R_Diff();    int a=1,b=78,c=5,d=23;    if(D == 1)    {        q=0;    }    if(D == 2)    {        I.Colour(2);        for(i=0;i<40;i++)        {            if(i<15)            {                w[i][0] = a++;                w[i][1] = 10;            }            if(i>=15 && i<20)            {                w[i][0] = 42;                w[i][1] = c++;            }            if(i>=20 && i<30)            {                w[i][0] = b--;                w[i][1] = 15;            }            if(i>=30)            {                w[i][0] = 30;                w[i][1] = d--;            }        }    }    if(D == 3)    {        I.Colour(2);        for(i=0;i<75;i++)        {            if(i<31)            {                w[i][0] = a++;                w[i][1] = 14;            }            if(i>=31 && i<38)            {                w[i][0] = 40;                w[i][1] = c++;            }            if(i>=38 && i<68)            {                w[i][0] = b--;                w[i][1] = 14;            }            if(i>=68)            {                w[i][0] = 40;                w[i][1] = d--;            }        }    }    if(D == 4)    {        I.Colour(2);        int c1=c,c2=c,d1=d,d2=d;        for(i=0;i<60;i++)        {            if(i<9)            {                w[i][0] = a++;                w[i][1] = 14;            }            if(i>=9 && i<18)            {                w[i][0] = b--;                w[i][1] = 14;            }            if(i>=18 && i<25)            {                w[i][0] = 40;                w[i][1] = c++;            }            if(i>=25 && i<32)            {                w[i][0] = 40;                w[i][1] = d--;            }            if(i>=32 && i<39)            {                w[i][0] = 20;                w[i][1] = c1++;            }            if(i>=39 && i<46)            {                w[i][0] = 20;                w[i][1] = d1--;            }            if(i>=46 && i<53)            {                w[i][0] = 60;                w[i][1] = c2++;            }            if(i>=53)            {                w[i][0] = 60;                w[i][1] = d2--;            }        }    }    if(D != 1)    {        if(D==2)            q = 40;        if(D==3)            q = 75;        if(D==4)            q = 60;        for(i=0;i<q;i++)        {            gotoxy(w[i][0],w[i][1]);            cout << "#";        }    }}void Wall::Display1(Interface &I){    int i,j;    for(i=1;i<=39;i++)//39 40 为最中间    {        I.Colour(2);        if(i == 39)        {            for(j=1;j<=12;j++)            {                gotoxy(39,j);                cout << "#";                gotoxy(39,24-j);                cout << "#";                gotoxy(40,j);                cout << "#";                gotoxy(40,24-j);                cout << "#";                Sleep(200);            }        }        else        {            for(j=1;j<=23;j++)            {                gotoxy(i,j);                cout << "#";                gotoxy(79-i,j);                cout << "#";            }            Sleep(100);        }    }}class Snake{public:    friend class Food;    void Grade();//游戏进行时动态输出成绩    void Init(Interface &I);//初始化信息,以及输出难度和速度    void Draw(Interface &I);//画出蛇    int Control();//控制    void Move_Snake();//根据指令移动蛇    int Death_Grow(const Wall &W);//判断蛇死亡    void Grade_S1(Interface &I);//死亡后输出成绩以及判断上榜    void Armory(Interface &I);//英雄榜    void R_File();    void W_File();private:    int s[100][2];//0列 1行    int size_Snake,grade_Snake;    int G[3];    enum Direction{UP,LEFT,DOWN,RIGHT}D,D_temp;};void Snake::Grade_S1(Interface &I){    for(int i=8;i<18;i++)    {        for(int j=30;j<49;j++)        {            gotoxy(j,i);            cout << " ";        }    }    for(int i=8;i<18;i++)    {        I.Colour(1);        for(int j=30;j<49;j++)        {            if(i==8 || i==17 || j==30 || j==48)            {                gotoxy(j,i);                cout << "#";            }        }    }    int c=0,v=0;    if(grade_Snake>G[0])    {        v++;        G[2] = G[1];        G[1] = G[0];        G[0] = grade_Snake;        gotoxy(35,10);        cout << "新 纪 录 ";        gotoxy(35,12);        cout << "第 一 名 ";        gotoxy(32,14);        cout << "您 的 成 绩 :";        cout << grade_Snake;        c++;    }    if(grade_Snake>G[1] && grade_Snake<=G[0] && v==0)    {        v++;        G[1] = grade_Snake;        gotoxy(35,10);        cout << "新 纪 录 ";        gotoxy(35,12);        cout << "第 二 名 ";        gotoxy(32,14);        cout << "您 的 成 绩 :";        cout << grade_Snake;        c++;    }    if(grade_Snake>G[2] && grade_Snake<=G[1]  && v==0)    {        G[2] = grade_Snake;        gotoxy(35,10);        cout << "新 纪 录 ";        gotoxy(35,12);        cout << "第 三 名 ";        gotoxy(32,14);        cout << "您 的 成 绩 :";        cout << grade_Snake;        c++;    }    if(c==0)    {        gotoxy(35,10);        cout << "GANE OVER!";        gotoxy(32,13);        cout << "您 的 成 绩 :";        cout << grade_Snake;    }}void Snake::Grade(){    gotoxy(55,2);    cout << size_Snake;    gotoxy(72,2);    cout << grade_Snake;}void Snake::Init(Interface &I){    size_Snake = 3;    grade_Snake = 0;    D = RIGHT;    D_temp = RIGHT;    s[0][0] = 10;    s[0][1] = 8;    for(int i=1;i<size_Snake;i++)    {        s[i][0] = s[i-1][0] - 1;        s[i][1] = s[i-1][1];    }    s[3][0] = 0;    Draw(I);    gotoxy(28,2);    cout << "                                  ";    I.Colour(5);    gotoxy(6,2);    cout << "速 度:";    int D,S;    D = I.R_Diff();    switch(D)    {    case 1:        cout << "入 门";        break;    case 2:        cout << "初 级";        break;    case 3:        cout << "中 级";        break;    case 4:        cout << "高 级";        break;    }    gotoxy(25,2);    cout << "难 度:";    S = I.R_Speed();    switch(S)    {    case 200:        cout << "入 门";        break;    case 150:        cout << "初 级";        break;    case 100:        cout << "中 级";        break;    case 50:        cout << "高 级";        break;    }    gotoxy(46,2);    cout << "蛇 长:" ;    gotoxy(64,2);    cout << "分 数:" ;}void Snake::Draw(Interface &I){    int i,c;    srand((unsigned)time(NULL));    c = 1 + rand() % 6;    I.Colour(c);    gotoxy(s[0][0],s[0][1]);//画出蛇头    cout << "@";    for(i=1;i<size_Snake;i++)//画出其他部分    {        gotoxy(s[i][0],s[i][1]);        cout << "*";    }    if(s[i][0] != 0)//将最后一节输出空格,不等于0是因为防止第二次游戏输出多余空格    {        gotoxy(s[i][0],s[i][1]);        cout << " ";    }}int Snake::Control(){    char ch;    if(!_kbhit())return 1;    ch = getch();switch(ch){case 'w':case 'W':    D_temp = UP;                break;case 's':case 'S':    D_temp = DOWN;    break;case 'a':case 'A':    D_temp = LEFT;    break;case 'd':case 'D':    D_temp = RIGHT;                break;            case 32:                return 0;                break;}}void Snake::Move_Snake(){    for(int i=size_Snake-1;i>=0;i--)//记录没有移动前的位置    {        s[i+1][0] = s[i][0];s[i+1][1] = s[i][1];    }    if(D != (D_temp+2)%4)//判断是否反向运动    {        D = D_temp;//改变方向    }    switch(D)//根据移动方向改变蛇头的位置        {        case UP:            s[0][1]--;            break;        case DOWN:            s[0][1]++;            break;        case LEFT:            s[0][0]--;            break;        case RIGHT:            s[0][0]++;            break;        }}int Snake::Death_Grow(const Wall &W){    //int q = W.R_q();    //int (*p)[2];    //p = W.R_w();    //int w[100][2];    if(s[0][0] >= 79 || s[0][0] <=0 || s[0][1] >=24 || s[0][1]<=4)    {        return 1;    }    for(int i=1;i<size_Snake;i++)    {        if(s[0][0]==s[i][0] && s[0][1]==s[i][1])            return 1;    }    for(int j=0;j<W.q;j++)    {        if(s[0][0]==W.w[j][0] && s[0][1]==W.w[j][1])            return 1;    }}void Snake::Armory(Interface &I){    char ch;    I.Empty();    I.Colour(6);    gotoxy(36,5);    cout << "英 雄 榜 ";    for(int i=0;i<3;i++)    {        gotoxy(36,8+3*i);        cout << "第" << i+1 << "名:";        cout << G[i];    }    ch = getch();    while(ch!=27)    {        ch = getch();    }    I.Empty();}void Snake::R_File(){    ifstream infile("Armory.txt",ios::in);    if(!infile)    {        ofstream outfile("Armory.txt",ios::trunc);        for(int i=0;i<3;i++)             G[i] = 0;        for(int i=0;i<3;i++)            outfile << G[i] << " ";    }    else    {        for(int i=0;i<3;i++)            infile >> G[i];    }}void Snake::W_File(){    ofstream outfile("Armory.txt",ios::out);    if(!outfile)    {        cout << "error!";    }    else    {        for(int i=0;i<3;i++)            outfile << G[i] << " ";    }    outfile.close();}class Food{public:    void Init_Food();//初始化    void Create_Food(const Snake &s,const Wall &w);//产生食物    void Judge_Food(Snake &s,Interface &I);//判断吃食物    void Draw_Food(Interface &I);//画出食物private:    int f[1][2];};void Food::Init_Food(){    f[0][0] = 0;    f[0][1] = 0;}void Food::Judge_Food(Snake &s,Interface &I){    int S,D;    S = I.R_Speed();    D = I.R_Diff();    if(f[0][0]==s.s[0][0] && f[0][1]==s.s[0][1])    {        s.size_Snake++;        switch(S)        {        case 200:            s.grade_Snake = s.grade_Snake + 1*D;            break;        case 150:            s.grade_Snake = s.grade_Snake + 2*D;            break;        case 100:            s.grade_Snake = s.grade_Snake + 3*D;            break;        case 50:            s.grade_Snake = s.grade_Snake + 4*D;        }        f[0][0] = 0;        f[0][1] = 0;    }}void Food::Create_Food(const Snake &s,const Wall &w){    int x=0;    srand((unsigned)time(NULL));    if(f[0][0]==0)    {        while(1)        {            f[0][0] = 1 + rand() % 78;            f[0][1] = 5 + rand() % 19;            for(int i=0;i<s.size_Snake;i++)            {                if(f[0][0]==s.s[i][0] && f[0][1]==s.s[i][1])                {                    x = 1;                }            }            for(int i=0;i<w.q;i++)            {                if(f[0][0]==w.w[i][0] && f[0][1]==w.w[i][1])                {                    x = 1;                }            }            if(x == 0)                break;        }    }}void Food::Draw_Food(Interface &I){    I.Colour(6);    gotoxy(f[0][0],f[0][1]);    cout << "&";}int main(){    hide_cursor();int c,s,m,n;char ch;Wall W;Snake S;S.R_File();Food F;Interface I;W.Display(I);while(1){I.Display();c = I.Move();if(c == 10)//开始游戏{    while(1)//选择难度            {             m = I.Difficulty();             if(m==2)                break;    while(1)            {                s = I.Speed_();//速度选择界面                if(s == 1)//选择速度后                {                    W.Dis_(I);                    S.Init(I);                    F.Init_Food();                    S.Grade();                    ch = 1;                    while(ch!=32 || ch!=27)                    {                        ch = getch();                        if(ch==27)                        {                            break;                        }                        if(ch==32)                        {                            s = 3;                            break;                        }                    }                }                if(s == 2)//返回                {                    break;                }                if(s == 3)//选择开始                {                    while(1)//游戏进行界面                    {                        if(s == 1)//游戏运行一次后                        {                            S.Grade_S1(I);                            while(1)//能能按下Esc或者Space                            {                                ch = getch();                                if(ch == 27 || ch==32)                                    break;                            }                        }                        if(ch==27)//返回                            break;                        if(ch==32&&s==1)//再次进入游戏界面                        {                            W.Dis_(I);                            S.Init(I);                            F.Init_Food();                            S.Grade();                            while(1)//开始或者返回                            {                                ch = getch();                                if(ch == 27 || ch==32)                                    break;                            }                        }                        if(ch==27)                            break;                        while(1)//游戏运行                        {                            W.Dis_W(I);                            F.Create_Food(S,W);//创建食物                            F.Draw_Food(I);//画出食物                            F.Judge_Food(S,I);//判断食物来增加蛇长度和分数                            n = S.Control();//用户下达指令                            if(n == 0)//暂停后                            {                                while(1)                                {                                    ch = getch();                                    if(ch ==27 || ch ==32)                                        break;                                }                                if(ch == 27)                                    break;                            }                            S.Move_Snake();//根据指令移动蛇                            s = S.Death_Grow(W);//判断蛇是否死亡                            if(s==1)//死亡返回1 并推出                            {                                break;                            }                            S.Grade();//显示成绩                            S.Draw(I);//画蛇                            Sleep(I.R_Speed());//速度                        }                    }                }            }            }}if(c == 12){    S.Armory(I);}if(c == 14){            I.Dis_Help();}if(c == 16)        {            S.W_File();            W.Display1(I);            gotoxy(0,25);            exit(0);        }}return 0;}


0 0