小言_互联网的博客

C++版贪吃蛇代码

542人阅读  评论(0)

虽然之前因为某些繁琐的小事耽误了一年,然后后来断断续续有开始写博文,但是毕竟之前的老底是在的,于是就寻思着自己打一个贪吃蛇游戏玩一玩,没想到还真就操作出来了(v1.1)。虽然有一点成就感,但是不至于太过兴奋(毕竟是单机的)。所以我从五六月的时候就去创作了一个人机对战版本(v1.2)的,然后陆续增加了双人对战和双机对战,稍加修饰了一下。
如果你喜欢的话就请点个关注吧。
废话不多说了,上代码。

(头文件 all.h)

#include <cstdio>
#include <conio.h>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <windows.h>
#include <algorithm>
#include <ctime>
#define REP(i,a,b) for (int i=(a);i<=(b);i++)
#define PER(i,a,b) for (int i=(a);i>=(b);i--)
#define max(x,y) ((x)<(y)?(y):(x))
#define min(y,x) ((x)<(y)?(x):(y))
#define MEM(a,b) memset(a,(b),sizeof(a))
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//判断这个键是否按下
#define KEY_UP(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 0 : 1)//判断这个键是否弹起
#define KEY_EVERY(lpkeyState) GetKeyboardState(lpKeyState)//获得所有的256个键(键盘按键、鼠标按键等等)的状态,lpKeyState是指向一个256bit的数组,存放所有键的状态。
#define KEY_NOW(nVirtKey) GetKeyState(nVirtKey)//用于判断nVirtKey的状态。用返回值的最高位表示,最高位为1表示当前键处于down的状态;最高位为0当前键处于up状态。此函数从消息队列中读取消息进行处理。
#define setcolor(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x)//设置颜色
#define getkey(x) GetAsyncKeyState(x)
#define GetWindow() GetForegroundWindow();//得到窗口信息
/*
鼠标左键 : MOUSE_MOVED 
鼠标右键 :MOUSE_EVENT
鼠标滚轮 : MOUSE_WHEELED
MK_CONTROL当CTRL键按下时。
MK_LBUTTON当鼠标左键按下时。
MK_MBUTTON当鼠标中键按下时。
MK_RBUTTON当鼠标右键按下时.
MK_SHIFT当SHIFT按下时。
*/
using std::cin;
using std::cout;
using std::endl;
int brand();
void GOTO(int x,int y);
int brand(){return (rand()<<16)|(rand()<<1)|(rand()&1);}
void bsrand(){srand(GetTickCount());}
void cls(){system("cls");}
void retr(){//退出程序 
    HWND hWnd=GetForegroundWindow();
    ShowWindow(hWnd,SW_HIDE);
    exit(0);
}
void Window_Hide(HWND hWnd){ShowWindow(hWnd,0);}//隐藏窗口
void Window_Show(HWND hWnd){ShowWindow(hWnd,1);}//显示窗口
int getmouse_y(){//获取鼠标在屏幕中x的位置 
    POINT pt; 
    GetCursorPos(&pt);
    return pt.x;
}
int getmouse_x(){//获取鼠标在屏幕中y的位置 
    POINT pt; 
    GetCursorPos(&pt);
    return pt.y;
}
void setmouse(int y,int x){SetCursorPos(x,y);}//设置鼠标在屏幕中的位置 
void click_left(){//鼠标左键点击
    mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);  
    Sleep(5);//要留给某些应用的反应时间   
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); 
}
void click_right(){//鼠标右键点击
    mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);  
    Sleep(5);   
    mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);  
}
void GOTO(int x,int y){//将光标移动到屏幕中的位置
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    HANDLE hConsoleOut;
    hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
    csbiInfo.dwCursorPosition.Y = x;
    csbiInfo.dwCursorPosition.X = y;
    SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}
/* 
附录1:(COLOR) 
<span style="white-space:pre">    </span>字
    1   深蓝色
    2   深绿色
    3   深青色
    4   深红色
    5   深粉色
    6   黄色
    7   深白色
    8   灰色
    9   浅蓝色
    10  浅绿色
    11  浅青色
    12  浅红色
    13  浅粉色
    14  浅黄色
    15  浅白色

    背景 
    1~15        黑色
    16~31       深蓝色
    32~47       深绿色
    48~63       深青色
    64~79       深红色
    80~95       深粉色
    96~111      深黄色
    112~127     深白色
    128~143     灰色
    144~159     浅蓝色
    160~175     浅绿色
    176~191     浅青色
    192~207     浅红色
    208~223     浅粉色
    224~239     浅黄色
    240~255     浅白色

附录2(KEY NUMBER) 
    VK_LBUTTON             鼠标左键                      0x01 
    VK_RBUTTON             鼠标右键                      0x02 
    VK_CANCEL              Ctrl + Break                  0x03 
    VK_MBUTTON             鼠标中键                      0x04 

    VK_BACK                Backspace 键                   0x08 
    VK_TAB                 Tab 键                        0x09 

    VK_RETURN              回车键                        0x0D 


    VK_SHIFT               Shift 键                      0x10 
    VK_CONTROL             Ctrl 键                       0x11 
    VK_MENU                Alt 键                         0x12 
    VK_PAUSE               Pause 键                      0x13 
    VK_CAPITAL             Caps Lock 键                  0x14 

    VK_ESCAPE              Esc 键                        0x1B 

    VK_SPACE               空格键                       0x20 
    VK_PRIOR               Page Up 键                    0x21 
    VK_NEXT                Page Down 键                  0x22 
    VK_END                 End 键                        0x23 
    VK_HOME                Home 键                       0x24 
    VK_LEFT                左箭头键                      0x25 
    VK_UP                  上箭头键                      0x26 
    VK_RIGHT               右箭头键                      0x27 
    VK_DOWN                下箭头键                      0x28 
    VK_SNAPSHOT            Print Screen 键               0x2C 
    VK_Insert              Insert 键                     0x2D 
    VK_Delete              Delete 键                     0x2E 

    '0' – '9'             数字 0 - 9                    0x30 - 0x39 
    'A' – 'Z'             字母 A - Z                    0x41 - 0x5A 

    VK_LWIN                左WinKey(104键盘才有)         0x5B 
    VK_RWIN                右WinKey(104键盘才有)         0x5C 
    VK_APPS                AppsKey(104键盘才有)          0x5D 

    VK_NUMPAD0            小键盘 0 键                    0x60 
    VK_NUMPAD1            小键盘 1 键                    0x61 
    VK_NUMPAD2            小键盘 2 键                    0x62 
    VK_NUMPAD3            小键盘 3 键                    0x63 
    VK_NUMPAD4            小键盘 4 键                    0x64 
    VK_NUMPAD5            小键盘 5 键                    0x65 
    VK_NUMPAD6            小键盘 6 键                    0x66 
    VK_NUMPAD7            小键盘 7 键                    0x67 
    VK_NUMPAD8            小键盘 8 键                    0x68 
    VK_NUMPAD9            小键盘 9 键                    0x69 

    VK_F1 - VK_F24        功能键F1 – F24                0x70 - 0x87 

    VK_NUMLOCK            Num Lock 键                    0x90 
    VK_SCROLL             Scroll Lock 键                 0x91 
*/

(v1.1版本)

#include "all.h"
using namespace std;
const int flg[4][2]={{1,0},{0,2},{0,-2},{-1,0}};
int n=28,m=76,tim;
struct xcw{int x,y;}tan[1000005];
int tot,f,score,food,ground=0;
bool vis[1005][1005];
int main();
void ret(){
    HWND hWnd=GetForegroundWindow();
    ShowWindow(hWnd,SW_HIDE);
    exit(0);
}
bool check(int x,int y){ 
    if(x<1||x>n||y<2||y>m) return 0;
    bool t=1;
    for(int i=1;i<=tot;i++)
    if(x==tan[i].x&&y==tan[i].y){t=0;break;}
    return t;
}
void fnd(int x,int y){
    if(check(x,y)) return;
    setcolor(7+ground);cls();
    printf("Lose\n");
    printf("分数:%d\n",score);
    printf("E键退出,R键重来\n");
    char ch=getch();
    while(ch!='E'&&ch!='e'&&ch!='R'&&ch!='r') ch=getch();
    if(ch=='E'||ch=='e') ret();
    else{main();exit(0);}
}
void rand_food(){
    setcolor(12+ground);
    int x=brand()%(n+1),y=(brand()%m/2)*2;
    while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
    GOTO(x,y);printf("▇");
    if(!vis[x][y]) food++;vis[x][y]=1;
    x=brand()%(n+1),y=(brand()%m/2)*2;
    while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
    GOTO(x,y);printf("▇");
    if(!vis[x][y]) food++;vis[x][y]=1;
    setcolor(10+ground);
}
void draw(){
    setcolor(14+ground);
    for(int i=0;i<=n+1;i++) GOTO(i,m+2),printf("▇"),GOTO(i,0),printf("▇");
    for(int i=1;i<=m/2+1;i++) GOTO(n+1,i*2),printf("▇"),GOTO(0,i*2),printf("▇");
    setcolor(10+ground);
}
int main(){
    system("mode con cols=80 lines=31"); 
    cls();
    printf("设置速度(豪秒/格)(建议100):");
    cin>>tim;bsrand();MEM(vis,0);food=0;MEM(tan,0);score=0;
    setcolor(10+ground); 
    cls();
    draw();
    f=1;tan[1]=(xcw){1,6};tan[2]=(xcw){1,4};tan[tot=3]=(xcw){1,2};
    for(int i=1;i<=tot;i++) GOTO(tan[i].x,tan[i].y),printf("▇");
    while(1){
        while(!kbhit()){
            Sleep(tim);
            if(food==0) rand_food();
            int x=tan[1].x,y=tan[1].y;
            x+=flg[f][0],y+=flg[f][1];
            for(int i=tot;i;i--) tan[i+1]=tan[i];
            GOTO(tan[tot+1].x,tan[tot+1].y);
            printf("  ");
            if(vis[x][y]) vis[x][y]=0,score++,food--,++tot,GOTO(tan[tot].x,tan[tot].y),printf("▇");
            fnd(x,y);
            tan[1]=(xcw){x,y};
            GOTO(tan[1].x,tan[1].y);
            printf("▇");
        }
        char ch=getch();
        bool t=0;
        if(ch=='E'||ch=='e') ret();
        if(ch==-32) ch=getch(),t=1;
        if((ch==75&&t||ch=='A'||ch=='a')&&f^1) f=2;
        if((ch==77&&t||ch=='D'||ch=='d')&&f^2) f=1;
        if((ch==80&&t||ch=='S'||ch=='s')&&f^3) f=0;
        if((ch==72&&t||ch=='W'||ch=='w')&&f^0) f=3;
    }
    return 0;
}

(v1.2版本)

#include "all.h"
using namespace std;
const int flg[4][2]={{1,0},{0,2},{0,-2},{-1,0}};
int n=28,m=76,tim;
struct xcw{int x,y;}tan[5][1000005],foodd[2];
int tot[5],f[5],score,food,ground=0,ms,ans_len=1e9;
bool vis[1005][1005];
void ret();
void result();
bool check();
void fnd();
void rand_food();
void draw();
int choose();
void stop();
int mods();
int ads();
int get_food();
int other();
void machine();
int change();
int main();
void ret(){
    HWND hWnd=GetForegroundWindow();
    ShowWindow(hWnd,SW_HIDE);
    exit(0);
}
void Ending(){
    printf("E键退出,R键重来\n");
    char ch=getch();
    while(ch!='E'&&ch!='e'&&ch!='R'&&ch!='r') ch=getch();
    if(ch=='E'||ch=='e') ret();
    else{main();exit(0);}
}
void result(int t){
    setcolor(7+ground);cls();
    if(ms==2){
        if(t==0) printf("Win!!!");else
        printf("Lose...\n");
        printf("机器人:%d\n你:%d\n",tot[2],tot[0]);
    }else
    if(ms==3) if(t==1) printf("White Lose\n");else printf("White win\n");else
    if(ms==5) if(t==1) printf("Player 2 win\n");else printf("Player 1 win\n");
    Ending();
}
bool check(int x,int y){
    if(x<1||x>n||y<2||y>m) return 0;
    bool t=1;
    if(ms!=3)
    for(int i=1;i<=tot[0];i++)
    if(x==tan[0][i].x&&y==tan[0][i].y){t=0;break;}

    if(ms==1||ms==4||ms==5)
    for(int i=1;i<=tot[1];i++)
    if(x==tan[1][i].x&&y==tan[1][i].y){t=0;break;}

    if(ms==2||ms==3)
    for(int i=1;i<=tot[2];i++)
    if(x==tan[2][i].x&&y==tan[2][i].y){t=0;break;}

    if(ms==3)
    for(int i=1;i<=tot[3];i++)
    if(x==tan[3][i].x&&y==tan[3][i].y){t=0;break;}
    return t;
}
void fnd(int t,int x,int y){
    if(check(x,y)) return;
    setcolor(7+ground);cls();
    if(ms==3) if(t==3) printf("White lose\n");else printf("White win\n");else
    if(ms==4||ms==5) if(t==1) printf("Player 1 win\n");else printf("Player 2 win\n");
    else{
        if(t==2) printf("Win!!!\n");else printf("Lose...\n");
        printf("分数:%d\n",score);score=0;
    }
    Ending();
}
void rand_food(){
    if(!vis[foodd[0].x][foodd[0].y]){
        setcolor(12+ground);
        int x=brand()%(n+1),y=(brand()%m/2)*2;
        while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
        GOTO(x,y);printf("▇");
        if(!vis[x][y]) food++;vis[x][y]=1;foodd[0]=(xcw){x,y};
    }
    if(!vis[foodd[1].x][foodd[1].y]){
        setcolor(12+ground);
        int x=brand()%(n+1),y=(brand()%m/2)*2;
        while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
        GOTO(x,y);printf("▇");
        food++;vis[x][y]=1;foodd[1]=(xcw){x,y};
    }
}
void draw(){
    setcolor(14+ground);
    for(int i=0;i<=n+1;i++) GOTO(i,m+2),printf("▇"),GOTO(i,0),printf("▇");
    for(int i=1;i<=m/2+1;i++) GOTO(n+1,i*2),printf("▇"),GOTO(0,i*2),printf("▇");
}
int choose(){
    printf("0.退出\n");
    printf("1.单人模式\n");
    printf("2.双人模式\n");
    printf("3.人机对抗(谁先吃20个)\n");
    printf("4.机机对抗(谁先吃20个)\n");
    printf("5.对抗模式\n");
    printf("6.对抗模式(谁先吃20个)\n");
    printf("快捷键:\n");
    printf("P:暂停\n");
    printf("E:退出\n");
    char ch=getch();
    while(ch<'0'||ch>'6') ch=getch();
    if(ch=='0') ret();else
    if(ch=='1') ms=0;else
    if(ch=='2') ms=1;else
    if(ch=='3') ms=2;else
    if(ch=='4') ms=3;else
    if(ch=='5') ms=4;else
    if(ch=='6') ms=5;
}
void stop(){
    char ch=getch();
    while(ch!='P'&&ch!='p') ch=getch();
}
int mods(){
    setcolor(10+ground);
    if(ms!=3){
        tan[0][1]=(xcw){1,6};tan[0][2]=(xcw){1,4};tan[0][tot[0]=3]=(xcw){1,2};f[0]=1;
        for(int i=1;i<=tot[0];i++) GOTO(tan[0][i].x,tan[0][i].y),printf("▇");
    }
    if(ms==1||ms==4||ms==5){
        setcolor(7+ground);
        tan[1][1]=(xcw){n,m-6};tan[1][2]=(xcw){n,m-4};tan[1][tot[1]=3]=(xcw){n,m-2};f[1]=2;
        for(int i=1;i<=tot[1];i++) GOTO(tan[1][i].x,tan[1][i].y),printf("▇");
    }
    if(ms==2||ms==3){
        setcolor(15+ground);
        tan[2][1]=(xcw){n,m-6};tan[2][2]=(xcw){n,m-4};tan[2][tot[2]=3]=(xcw){n,m-2};f[2]=2;
        for(int i=1;i<=tot[2];i++) GOTO(tan[2][i].x,tan[2][i].y),printf("▇");
    }
    if(ms==3){
        setcolor(13+ground);
        tan[3][1]=(xcw){1,6};tan[3][2]=(xcw){1,4};tan[3][tot[3]=3]=(xcw){1,2};f[3]=1;
        for(int i=1;i<=tot[3];i++) GOTO(tan[3][i].x,tan[3][i].y),printf("▇");
    }
}
int ads(int x){return x<0?-x:x;}
int get_food(int x,int y,xcw z){return ads(x-z.x)+ads(y-z.y);}
int other(int x){
    if(x==0) return 3;else
    if(x==1) return 2;else
    if(x==2) return 1;else
    return 0;
}
void machine(int t,int x,int y){
    bool tt=0;int foodid,minn=1e9,newf=f[t];
    if(get_food(x,y,foodd[0])<=get_food(x,y,foodd[1])&&vis[foodd[0].x][foodd[0].y]||!vis[foodd[1].x][foodd[1].y]) foodid=0;else foodid=1;
    for(int i=0;i<4;i++)
    if(f[t]^other(i)){
        if(check(x+flg[i][0],y+flg[i][1])){
            int now=get_food(x+flg[i][0],y+flg[i][1],foodd[foodid]);
            if(now<minn) newf=i,tt=1,minn=now;
            if(!tt) newf=i;
        }
    }
    f[t]=newf;
}
int change(int t){
    if(t==0) setcolor(10+ground);else
    if(t==1) setcolor(7+ground);else
    if(t==2) setcolor(15+ground);else
    if(t==3) setcolor(13+ground);
    int x=tan[t][1].x,y=tan[t][1].y;
    if(t==2||t==3) machine(t,x,y);
    x+=flg[f[t]][0],y+=flg[f[t]][1];
    for(int i=tot[t];i;i--) tan[t][i+1]=tan[t][i];
    GOTO(tan[t][tot[t]+1].x,tan[t][tot[t]+1].y);
    printf("  ");
    if(vis[x][y]){
        vis[x][y]=0,score+=(t==0||t==1),food--;
        if(++tot[t]>=23&&(ms==3||ms==5)) result(t);
        GOTO(tan[t][tot[t]].x,tan[t][tot[t]].y),printf("▇");
    }
    fnd(t,x,y);
    tan[t][1]=(xcw){x,y};
    GOTO(tan[t][1].x,tan[t][1].y);
    printf("▇");
}
int main(){
    bsrand();score=0;
    system("title ");
    system("mode con cols=80 lines=31");
    choose();cls();
    printf("设置速度(毫秒/格)(建议100):");
    cin>>tim;
    MEM(vis,0);food=0;MEM(tan,0);
    cls();draw();mods();
    while(1){
        while(!kbhit()){
            Sleep(tim);
            rand_food();
            if(ms!=3) change(0);
            rand_food();
            if(ms==1||ms==4||ms==5) change(1);else
            if(ms==2) change(2);else
            if(ms==3) change(2),change(3);
        }
        char ch=getch();
        bool t=0;
        if(ch=='E'||ch=='e') ret();else
        if(ch=='P'||ch=='p') stop();else
        if(ms==0||ms==2){
            if(ch==-32) ch=getch(),t=1;
            if((ch==75&&t||ch=='A'||ch=='a')&&f[0]^1) f[0]=2;else
            if((ch==77&&t||ch=='D'||ch=='d')&&f[0]^2) f[0]=1;else
            if((ch==80&&t||ch=='S'||ch=='s')&&f[0]^3) f[0]=0;else
            if((ch==72&&t||ch=='W'||ch=='w')&&f[0]^0) f[0]=3;
        }else
        if(ms==1||ms==4||ms==5){
            if((ch=='W'||ch=='w')&&f[0]^0) f[0]=3;else
            if((ch=='A'||ch=='a')&&f[0]^1) f[0]=2;else
            if((ch=='D'||ch=='d')&&f[0]^2) f[0]=1;else
            if((ch=='S'||ch=='s')&&f[0]^3) f[0]=0;

            if(ch==-32) ch=getch(),t=1;
            if(ch==72&&t&&f[1]^0) f[1]=3;else
            if(ch==75&&t&&f[1]^1) f[1]=2;else
            if(ch==77&&t&&f[1]^2) f[1]=1;else
            if(ch==80&&t&&f[1]^3) f[1]=0;
        }
    }
    return 0;
}

转载:https://blog.csdn.net/qq_40559873/article/details/101381825
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场