随手写个控制台贪吃蛇(C/C++)

随手用C/C++写了一个控制台贪吃蛇,用_kbhit()判断输入缓存区是否有输入字符,{ 72, 77, 80, 75 } 分别表示上右下左的编码,实际上按一下方向键“上”会输入ascii值为-32和72两个字符;方向数组下标+2再模4能得到相反的方向。

#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <dos.h>
#include <windows.h>

const int MAXN = 3;
int length = 2;

char cha[][5] = {
    "  ",   //0:空
    "※",    //1:墙
    "◆",    //2:头
    "●",    //3:身体
    "●",    //4:尾巴
    "□",    //5:身体被吃
    "○"     //6:食物
};

int dir[4][2] = {
    { -1, 0 },  //上
    { 0, 1 },   //右
    { 1, 0 },   //下
    { 0, -1 }   //左
};
int keyCode[4] = { 72, 77, 80, 75 };
int map[MAXN][MAXN] = { 0 };
int body[MAXN][MAXN];
int headX, headY;
int tailX, tailY;

bool createFood() {
    bool OK = false;
    for (int i = 0; i < MAXN; i++) {
        for (int j = 0; j < MAXN; j++) {
            if (map[i][j] == 0) {
                OK = true;
                break;
            }
        }
    }
    if (!OK) return false;
    int x, y;
    do {
        x = rand() % MAXN;
        y = rand() % MAXN;
    } while (map[x][y] != 0);
    map[x][y] = 6;
    return true;
}

bool init() {
    srand((unsigned)time(NULL));
    memset(body, -1, sizeof(body));
    tailX = -1; tailY = -1;
    if (length < 2) {
        printf("蛇初始长度过短");
        return false;
    }
    if (MAXN < 3 || MAXN < length) {
        printf("地图宽度过小");
        return false;
    }
    for (int i = 0; i <= length - 2; i++) {
        if (i == 0) {
            tailX = MAXN / 2; tailY = (MAXN - length) / 2;
            map[tailX][tailY] = 4;
            body[tailX][tailY] = 1;
        } else {
            map[MAXN / 2][(MAXN - length) / 2 + i] = 3;
            body[MAXN / 2][(MAXN - length) / 2 + i] = 1;
        }
    }
    headX = MAXN / 2; headY = (MAXN - length) / 2 + length - 1;
    map[headX][headY] = 2;
    body[headX][headY] = -1;
    createFood();
    return true;
}

void print() {
    system("CLS");
    for (int i = 0; i < MAXN + 2; i++) {
        printf("%s", cha[1]);
    }
    printf("\n");
    for (int i = 0; i < MAXN; i++) {
        printf("%s", cha[1]);
        for (int j = 0; j < MAXN; j++) {
            printf("%s", cha[map[i][j]]);
        }
        printf("%s\n", cha[1]);
    }
    for (int i = 0; i < MAXN + 2; i++) {
        printf("%s", cha[1]);
    }
    printf("\n");
}

int move(char ch) {
    for (int i = 0; i < 4; i++) {
        if (int(ch) == keyCode[i]) {
            int nextX = (MAXN + headX + dir[i][0]) % MAXN;
            int nextY = (MAXN + headY + dir[i][1]) % MAXN;

            if (map[nextX][nextY] == 3) {
                if ((body[nextX][nextY] + 2) % 4 == i) {
                    return 2;
                }
                map[nextX][nextY] = 5;
                return 0;
            }

            if (tailX >= 0 && tailY >= 0 && map[nextX][nextY] != 6) {
                int x = (MAXN + tailX + dir[ body[tailX][tailY] ][0]) % MAXN;
                int y = (MAXN + tailY + dir[ body[tailX][tailY] ][1]) % MAXN;
                map[x][y] = 4;
                map[tailX][tailY] = 0;
                body[tailX][tailY] = -1;
                tailX = x; tailY = y;
            }

            if (map[nextX][nextY] == 6 && !createFood()) {
                map[nextX][nextY] = 2;
                map[headX][headY] = 3;
                return 1;
            }

            map[nextX][nextY] = 2;
            map[headX][headY] = 3;
            body[headX][headY] = i;
            body[nextX][nextY] = -1;
            headX = nextX; headY = nextY;

            break;
        }
    }
    return -1;
}

int main() {
    if (!init()) {
        return 0;
    }
    print();
    Sleep(1000);
    char ch = keyCode[1];
    char temp = ch;
    while(true) {
        if(_kbhit()) {
            do {
                ch = _getch();
            } while ((ch == -32 && _kbhit()) || 
                (ch == temp && _kbhit()));
        }
        int r;
        do {
            r = move(ch);
            if (r == 0) {
                print();
                printf("You Lose!\n");
                return 0;
            } else if (r == 1) {
                print();
                printf("You Win!\n");
                return 0;
            } else if (r == 2){
                ch = temp;
            }
        } while (r == 2);
        temp = ch;
        print();
        Sleep(500);
    }
    return 0;
}

截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值