命令行之贪吃蛇

命令行之贪吃蛇  

 

 (可能有BUG,时间有限,只能写成这样了)

游戏截图 :

 

 

 

 

 

 

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <cstdlib>
#define Coord_x 15
#define Coord_y 15
#define Height  20
#define Width  18

using namespace std;

enum dir{u,d,l,r};

class Snake{

    public:
        int x;
        int y;
        int score;
        int level;
        int snake_speed;
        Snake *prior, *next;
        int vis[100][100];
        char map[100][100];
        int food_x;
        int food_y;
        int init_x;
        int init_y;
        dir point;

    public:
        Snake(int s = 0, int l = 1, int ss = 200);
        void init_snake();
        void add_head(int x, int y);
        void delete_tail();
        bool make_food();
        void change_point(char);
        void move();
        void Display();
}S, *head = NULL, *tail = NULL;


class Console{

    public:
        void gotoxy(HANDLE hOut, int x, int y);
        void enter_game();
        void initialize_window();
        void start_game();
        void end_game();

        friend class Snake;
}C;

void Console::gotoxy(HANDLE hOut, int x, int y)
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOut, pos);
}


void Console::enter_game()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    system("title 贪吃蛇 by Tc");
    gotoxy(hOut,Coord_x+Width+1,Coord_y-11);
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
    cout << "欢迎进入贪吃蛇";
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
    gotoxy(hOut,Coord_x+Width-25,Coord_y-8);
    cout << "      * *      *      *          *          *    *     * * * * *    " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-7);
    cout << "    *     *    **     *         * *         *   *      *            " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-6);
    cout << "    *          * *    *        *   *        *  *       *            " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-5);
    cout << "      *        *  *   *       *     *       * *        * * * * *    " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-4);
    cout << "        *      *   *  *      * * * * *      *  *       *            " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-3);
    cout << "          *    *    * *     *         *     *   *      *            " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-2);
    cout << "    *     *    *     **    *           *    *    *     *            " << endl;
    gotoxy(hOut,Coord_x+Width-25,Coord_y-1);
    cout << "      * *      *      *   *             *   *     *    * * * * *    " << endl;
    gotoxy(hOut,Coord_x+Width,Coord_y+3);
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED);
    cout << "按回车键进入游戏\n"<< endl;;
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
    while(1)
    {
        char c;
        if(kbhit())
        {
            c = getch();
            if(c == 13)
            {
                system("CLS");
                C.initialize_window();
                C.start_game();
            }
        }
        cout << "O" ;
        Sleep(200);
    }
    if(getch() == 27)
    {
        C.end_game();
    }
    else
    {
        C.enter_game();
    }

}


void Console::end_game()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    system("CLS");
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
    gotoxy(hOut,Coord_x+Width+5,Coord_y-10);
    cout << "游戏结束";
    gotoxy(hOut,Coord_x+Width+5,Coord_y-7);
    cout << "最终得分 : " << S.score << endl;
    gotoxy(hOut,Coord_x+Width+5,Coord_y-5);
    exit(0);
}



void Console::initialize_window()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    system("title 贪吃蛇 by Tc");
    system("color 0C");
    gotoxy(hOut,Coord_x+Width-4,Coord_y-2);
    cout << "********";
    gotoxy(hOut,Coord_x+Width-3,Coord_y-3);
    cout << "贪吃蛇";
    gotoxy(hOut,Coord_x+Width-4,Coord_y-4);
    cout << "********";
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y-2);
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18);
    cout << "得分 : " << S.score << "   等级 : " << S.level;
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-12);
    cout << "w键 : 上  " << "s键 : 下";
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-10);
    cout << "a键 : 左  " << "d键 : 右";
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-8);
    cout << "空格键 :暂停";
    gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-6);
    cout << "Esc :退出";
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
    for(int i = 0;i < 2 * Width - 1; i++)
    {
        S.vis[Coord_x + i][Coord_y - 1] = 2;
    }
    for(int i = 0;i < 2 * Width - 1; i++)
    {
        S.vis[Coord_x + i][Coord_y + Height] = 2;
    }
    for(int i = 0;i < 2 * Width-1; i += 2)
    {
        gotoxy(hOut,Coord_x + i,Coord_y - 1);
        cout << "*";
    }
    for(int i = 0;i < 2 * Width-1; i += 2)
    {
        gotoxy(hOut,Coord_x + i,Coord_y + Height);
        cout << "*";
    }
    for(int i = 0;i < Height;i++)
    {
        gotoxy(hOut,Coord_x,Coord_y+i);
        cout << "*";
        S.vis[Coord_x][Coord_y+i] = 2;
    }
    for(int i = 0;i < Height;i++)
    {
        gotoxy(hOut,Coord_x+2*Width-2,Coord_y+i);
        cout << "*";
        S.vis[Coord_x+2*Width-2][Coord_y+i] = 2;
    }
 }


Snake::Snake(int s, int l, int ss)
{
    score = s;
    level = l;
    snake_speed = ss;
}


void Snake::add_head(int x, int y)
{
    Snake *node = new Snake;
    node -> x = x;
    node -> y = y;
    node -> next = head;
    node -> prior = NULL;
    if(head)
        head -> prior = node;
    head = node;
    if(!tail)
        tail = head;
    S.map[x][y] = 'O';
    S.vis[x][y] = 1;
}


void Snake::delete_tail()
{
    Snake *t = tail;
    S.map[ tail -> x ][ tail -> y ]= ' ';
    S.vis[ tail -> x ][ tail -> y ] = 0;
    if(tail == head)
        tail = head = NULL;
    else
    {
        tail = tail -> prior;
        tail -> next = NULL;
    }
    delete t;
}


void Snake:: init_snake()
{
    srand((unsigned) time(NULL));
    S.init_x = Coord_x + 2 + rand() % 20;
    S.init_y = Coord_y + 2 + rand() % 15;
}

void Snake::move()
{
    int a, b;
    a = head -> x;
    b = head -> y;
    switch(point)
    {
        case u: --b; break;
        case d: ++b; break;
        case l: --a; break;
        case r: ++a; break;
    }
    if(S.vis[a][b] == 1 || S.vis[a][b] == 2)
    {
        C.end_game();
    }
    if(vis[a][b] == 3)
    {
        head -> add_head(a,b);
        S.vis[a][b] = 1;
        score += 10;
        if(score % 50 == 0)
        {
            level++;
            snake_speed -= 20;
        }
        while(!S.make_food());
    }
    else
    {
        head -> add_head(a,b);
        head -> delete_tail();
    }
}

void Snake::change_point(char keydown)
{
    switch(keydown)
    {
        case 'w': point = u; break;
        case 's': point = d; break;
        case 'a': point = l; break;
        case 'd': point = r; break;
    }
}

bool Snake::make_food()
{
    srand((unsigned int) time(NULL));
    food_x = Coord_x + 1 + rand() % 34;
    food_y = Coord_y + 1 + rand() % 18;
    if(S.vis[food_x][food_y] == 0)
    {
        S.map[food_x][food_y] = 'O';
        S.vis[food_x][food_y] = 3;
        return true;
    }
    return false;
}


void Snake:: Display()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    for(int i = Coord_x + 1; i < Coord_x + 2 * Width - 2; i++)
    {
        for(int j = Coord_y; j < Coord_y + Height; j++)
        {
            C.gotoxy(hOut,i,j);
            if(i == head -> x && j == head -> y)
            {
                SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED);
                cout << S.map[i][j];
            }
            else
            {
                SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
                cout << S.map[i][j];
            }
        }
    }
    SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
    C.gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18);
    cout << "得分 : " << score << "   等级 : " << level;
}



void Console::start_game()
{
    S.init_snake();
    head -> add_head(S.init_x,S.init_y);
    head -> add_head(S.init_x+1,S.init_y);
    head -> add_head(S.init_x+2,S.init_y);
    while(!S.make_food());
    S.Display();
    char keydown = '\0';
    while(true)
    {
        char temp = keydown;
        keydown = getch();
        if(keydown == 27)
        {
            C.end_game();
        }
        S.change_point(keydown);
        if(keydown == ' ')
        {
            S.Display();
            while(true)
            {
                if(kbhit())
                {
                    char ch = getch();
                    if(ch == ' ')
                    {
                        goto Loop;
                    }
                }
            }
        }
        if(temp == 'w' && keydown == 's')
        {
            S.point = u;
            keydown = 'w';
        }
        else if(temp == 's' && keydown == 'w')
        {
            S.point = d;
            keydown = 's';
        }
        else if(temp == 'a' && keydown == 'd')
        {
            S.point = l;
            keydown = 'a';
        }
        else if(temp == 'd' && keydown == 'a')
        {
            S.point = r;
            keydown = 'd';
        }
        Loop:
        while(!kbhit())
        {
            S.move();
            S.Display();
            Sleep(S.snake_speed);
        }
    }
}


int main()
{
    memset(S.vis,0,sizeof(S.vis));
    memset(S.map,0,sizeof(S.map));
    C.enter_game();
	return 0;
}



 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值