控制台贪吃蛇

/*
 * 原理很简单,只要懂队列跟_kbhit() 这个函数
 * 用队列保存蛇身,_kbhit()相应键盘,printf绘图
 * 剩下的就是完善一下逻辑就行
 * 注意上下左右键是双键值,getch() 要连续读取两次 
 * Sleep() 控制速度 
 */

#include <bits/stdc++.h>
#include <conio.h>
#include <windows.h>
using namespace std;

int const x_max = 25;
int const y_max = 70;
int const snake_speed = 200;
const char FOODchar = '+';
const char SNAKEchar = '*';
const char MAZEchar = '*';
const int SNAKEleight = 3;
const int start_x = 5;
const int start_y = 5;

COORD ST_CD;
/// w s a d;
const int d = 4;
const int s = 2;
const int w = 1;
const int a = 3;
int Maze[x_max+10][y_max+10]= {0};
queue <COORD> CD;
int score = 0;

void gotoXY(int a,int b);
void HideConsole();
void clearXY(COORD cd);
void printXY(COORD cd);
void flagXY(const COORD &cd);
int  RandomNumble(int a,int b);
void makeFood();
void printMaze();
void STARTmaze(int len = SNAKEleight);
int  getdec();
void Next_cd(int dec,COORD & cd);
void SNAKE_step(const COORD & now_cd,queue<COORD> & CD,int & isNothavefood);
void SNAKE_move();
void PrintFail();
int  contrary_dec(int const &dec);
void printScore();


int main(){
    srand((int)time(NULL));
    ST_CD.X = start_y;
    ST_CD.Y = start_x;

    HideConsole();
    printMaze();
    STARTmaze();
    SNAKE_move();
    PrintFail();
    return 0;
}

void SNAKE_step(const COORD &now_cd,queue<COORD>&CD,bool &isNothavefood){
    COORD clear_cd;
    printXY(now_cd);
    if ( Maze[now_cd.Y][now_cd.X] == 2){
        score ++;
        printScore();
        Maze[now_cd.Y][now_cd.X] = 1;
        CD.push(now_cd);
        isNothavefood = 1;
    }else {
        Maze[now_cd.Y][now_cd.X] = 1;
        CD.push(now_cd);

        clear_cd = CD.front();
        CD.pop();
        Maze[clear_cd.Y][clear_cd.X] = 0;
        clearXY(clear_cd);
    }
}
void SNAKE_move(){

    int now_dec = d;
    COORD now_cd = ST_CD ;
    bool isNothavefood = 1;

    while (1){

        if (isNothavefood){
            makeFood();
            isNothavefood = 0;
        }
        while( _kbhit() ){
            int cpy_dec = now_dec;
            cpy_dec = getdec();
            if ( cpy_dec == contrary_dec(now_dec) ) continue;
            now_dec = cpy_dec;

            Next_cd(now_dec,now_cd);
            if (  Maze[now_cd.Y][now_cd.X] == 1 ) break;
            SNAKE_step(now_cd,CD,isNothavefood);
            Sleep(70);
        }
        Sleep(snake_speed);
        Next_cd(now_dec,now_cd);
        if ( Maze[now_cd.Y][now_cd.X] == 1 ) break;
        SNAKE_step(now_cd,CD,isNothavefood);
    }
}
void Next_cd(int dec,COORD & cd){
    switch(dec){
        case a: cd.X--;return;
        case s: cd.Y++;return;
        case w: cd.Y--;return;
        case d: cd.X++;return;
    }
}
int getdec(){
    int b;
    b = getch();
    while(b == 'p') b = getch();
    b = getch();
    switch (b){
        case 72:return w;
        case 80:return s;
        case 75:return a;
        case 77:return d;
    }
    return 0;
}
void STARTmaze(int len){
    printXY(ST_CD);
    flagXY(ST_CD);
    CD.push(ST_CD);
    len--;
    while(len--){
        ST_CD.X++;
        CD.push(ST_CD);
        printXY(ST_CD);
        flagXY(ST_CD);
    }
}
void HideConsole(){
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cci;
    GetConsoleCursorInfo(hOut,&cci);
    cci.bVisible = false;
    SetConsoleCursorInfo(hOut,&cci);
}
void gotoXY( int a,int b){
    COORD cd;
    cd.X = a;
    cd.Y = b;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut , cd);
}
void clearXY(COORD cd){
    gotoXY(cd.X,cd.Y);
    printf(" ");
}
void printXY(COORD cd){
    gotoXY(cd.X,cd.Y);
    printf("%c",SNAKEchar);
}
void printMaze(){
    for (int i = 0;i <= x_max; ++i){
        for (int j = 0;j <= y_max; ++j){
            if (i == 0 || i == x_max || j == 0 || j == y_max ){
                Maze[i][j] = 1;
                printf("%c",MAZEchar);
            }else printf(" ");
        }
        printf("\n");
    }
    gotoXY(2,x_max + 2);
    printf("your score is : %d\n\n",score);
    printf("  please press p to pause");
}
void printScore(){
    gotoXY(17,x_max + 2);
    printf("%d",score);
}
int RandomNumble(int a,int b){
    return  ( rand() % (b-a+1) )+a;
}
void flagXY(const COORD &cd){
    Maze[cd.Y][cd.X] = 1;
}
void makeFood(){

    int y = RandomNumble(1,y_max-1);
    int x = RandomNumble(1,x_max-1);
    while( Maze[x][y] ){
        y = RandomNumble(1,y_max-1);
        x = RandomNumble(1,x_max-1);
    }
    Maze[x][y] = 2;
    gotoXY(y,x);
    printf("%c",FOODchar);
}
void PrintFail(){
    gotoXY(20,10);
    printf("you are failed!");
    gotoXY(0,x_max+1);
}
int contrary_dec(int const &dec){
    switch(dec){
        case 1:return 2;
        case 2:return 1;
        case 3:return 4;
        case 4:return 3;
    }
    printf("please call LQM");
    exit(1);
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值