好久不見啊同志們?。?!

寫了個《貪吃蛇》的代碼,本來想早點作的結果忘了………………

上代碼:


#include#include 
#include#include#include#include 
#define clear() cout << "\\033c" << flush
using namespace std;

struct node

{

    int x, y;

};

int num[15][15];

int x, y;

node head, food;

bool Food = false;

listsnake;

char ch = 0;

int score = 0;

static struct termios initial_settings, new_settings;

static int peek_character = -1;

void init_keyboard();

void close_keyboard();

bool kbhit();

char readch();

void changeNum();

void drawBoard();

void move();

int scanKeyboard();

void init_snake();

void fullFood();

bool getFood();

void longer();

bool gameOver();

void intro();

int getch(); // 不回顯函數

//主函數

int main()

{

    init_snake();  //初始化蛇

    init_keyboard();  //初始化鍵盤

    x = 0, y = 0;     //初始化移動方向

    

    intro();          //介紹游戲規則

    char a = getch();

    fullFood();       //填充食物

    drawBoard();      //繪制游戲界面

    while(ch != 'n') {

        usleep(200000);

        if(kbhit())  //如果按下按鍵

        {

             ch = readch(); //讀取按鍵值

        }

        int nx = x, ny = y;

        if (ch == 'w') nx = -1,ny = 0;  //預設移動方向

        if (ch == 's') nx = 1, ny = 0;

        if (ch == 'a') nx = 0, ny = -1;

        if (ch == 'd') nx = 0, ny = 1;

        if (ch == 'n') return 0;

        if (nx != -x || ny != -y)

            x = nx, y = ny;

        if (getFood())

        {

            score++;

            longer();

            fullFood();

        }

        else move();


        if (gameOver()) 

        {

            drawBoard();

            cout << "GameOver!!" << endl;

            return 0;

        }

        drawBoard();

    }

    close_keyboard();

    return 0;

}


bool gameOver()

{

    head = snake.front();

    if (head.x  <= 0 || head.x > 12)

        return true;

    if (head.y <= 0 || head.y > 12)

        return true;

    if (num[head.x][head.y] == 1)

        return true;

    return false;

}


void init_keyboard()

{

    tcgetattr(0,&initial_settings);

    new_settings = initial_settings;

    new_settings.c_lflag &= ~ICANON;

    new_settings.c_lflag &= ~ECHO;

    new_settings.c_lflag &= ~ISIG;

    new_settings.c_cc[VMIN] = 1;

    new_settings.c_cc[VTIME] = 0;

    tcsetattr(0, TCSANOW, &new_settings);

}

void close_keyboard()

{

    tcsetattr(0, TCSANOW, &initial_settings);

}

bool kbhit()

{

    char ch;

    int nread;

    if(peek_character != -1)

        return 1;

    new_settings.c_cc[VMIN]=0;

    tcsetattr(0, TCSANOW, &new_settings);

    nread = read(0,&ch,1);

    new_settings.c_cc[VMIN]=1;

    tcsetattr(0, TCSANOW, &new_settings);

    if(nread == 1) {

          peek_character = ch;

          return 1;

    }

    return 0;

}

char readch()

{

    char ch;

    if(peek_character != -1) {

        ch = peek_character;

        peek_character = -1;

        return ch;

    }

    read(0,&ch,1);

    return ch;

}

void fullFood() // 填充數據

{

    int x[200] = {}, y[200] = {}, cur = 0;

    for (int i = 1; i <= 12; i++)

    {

        for (int j = 1; j <= 12; j++)

        {

            if (num[i][j] == 0)

            {

                cur++;

                x[cur] = i;

                y[cur] = j;

            }

        }

    }

    if (cur > 0) // 還有空位

    {

        srand(time(0));

        int cc = rand() % cur + 1; // 隨機從空位中取出一個

        food.x = x[cc];

        food.y = y[cc];

    }

}

void changeNum()

{

    if(snake.empty()) return;

    memset(num, 0, sizeof(num));

    for (auto pos = snake.begin(); pos != snake.end(); pos++)

    {

        num[(*pos).x][(*pos).y] = 1;

    }

    num[food.x][food.y] = 3;

    auto pos = snake.begin();

    num[(*pos).x][(*pos).y] = 2;

}

void drawBoard() // 打印當前表格

{

    changeNum();

    clear();

    cout << "    ╔";

    for (int i = 1; i <= 6; i++) cout << "════";

    cout << "═╗\n";

    // 輸出中間部分

    for (int i = 1; i <= 12; i++) // 行

    {

        cout << "    ║";

        for (int j = 1; j <= 12; j++) // 列

        {

            if (num[i][j] == 1)

                cout << "\033[41m  \033[0m";

            else if (num[i][j] == 2)

                cout << "\033[42m  \033[0m";

            else if (num[i][j] == 3)

                cout << "\033[43m  \033[0m";

            else

                cout << "  ";

        }

        cout << " ║" << endl;

    }

    cout << "    ╚";

    for (int i = 1; i <= 6; i++) cout << "════";

    cout << "═╝\n";

    cout << "score:" << score << endl;

}

void move()

{

    clear();

    if (x == 0 && y == 0)

    {

        drawBoard();

        return;

    }

    node next = snake.front();

    next.y += y;

    next.x += x;

    snake.pop_back();

    snake.push_front(next);

}

int scanKeyboard()

{

    int in;

    struct termios new_settings;

    struct termios stored_settings;

    tcgetattr(0,&stored_settings);

    new_settings = stored_settings;

    new_settings.c_lflag &= (~ICANON);

    new_settings.c_cc[VTIME] = 0;

    tcgetattr(0,&stored_settings);

    new_settings.c_cc[VMIN] = 1;

    tcsetattr(0,TCSANOW,&new_settings);

    in = getchar();

    tcsetattr(0,TCSANOW,&stored_settings);

    return in;

}

void init_snake()

{

    head.x = 1, head.y = 1;

    snake.push_back(head);

    for (int i = 2; i <= 4; i++)

    {

        node a;

        a.x = 1, a.y = i;

        snake.push_back(a);

    }

    changeNum();

}

bool getFood()

{

    head = snake.front();

    if(num[head.x + x][head.y + y] == 3) return true;

    else return false;

}

void longer()

{

    node temp = snake.front();

    temp.x += x;

    temp.y += y;

    snake.push_front(temp);

}

void intro()

{

    cout << "歡迎來到貪吃蛇小游戲" << endl;

    cout << "游戲規則介紹:" << endl;

    cout << "你可以使用w,a,s,d來控制貪吃蛇進行上下左右的移動"  << endl;

    cout << "在移動過程中,每吃到一個果子,你就能增加1分,同時你也會變長 1 格" << endl;

    cout << "但,如果你在移動過程中碰到了自己或者墻壁,那么你就GAMEOVER了!" << endl;

    cout << "當然,你也可以按下 n 鍵提前結束游戲。好了,現在按下任意鍵開始游戲吧!" << endl;

}

int getch()

{

    struct termios nts, ots;

    // 得到當前終端(0表示標準輸入)的設置

    if (tcgetattr(0, &ots) < 0) return EOF;

    // 設置終端為Raw原始模式,該模式下所有的輸入數據以字節為單位被處理

    nts = ots;

    cfmakeraw(&nts); 

    // 設置上更改之后的設置

    if (tcsetattr(0, TCSANOW, &nts) < 0) return EOF;

    // 設置還原成老的模式

    int cr;

    cr = getchar();

    if (tcsetattr(0, TCSANOW, &ots) < 0)  return EOF;

    return cr;

}


小猴編程(5954425750781871)
好啦,代碼上完了,呢么本期文章就結束了,拜拜?。?!

本站作者已申明原創,禁止轉載!

文章內容屬作者個人觀點,不代表本站立場,如有侵權立刪。