如何打造一条低配贪吃蛇

贪吃蛇大概我们都玩过,作为一名优秀(并不)的程序猿,当然要自己造一条出来啦

整体的构思如下面的伪代码所示

输出字符矩阵
    WHILE not 游戏结束 DO
        ch=等待输入
        CASE ch DO
        ‘A’:左前进一步,break 
        ‘D’:右前进一步,break    
        ‘W’:上前进一步,break    
        ‘S’:下前进一步,break    
        END CASE
        输出字符矩阵
    END WHILE
    输出 Game Over!!! 

接着我们就一步一步实现


定义变量

我们在开始要定义一些要用的变量

char map[12][12];
int snakeX[100] = { 1, 1, 1, 1, 1 };
int snakeY[100] = { 1, 2, 3, 4, 5 };
int foodX = rand() % 10 + 1;
int foodY = rand() % 10 + 1;
int snake_head = 4;

这里的map就是整个游戏区域,下面两个snake就是我们的蛇了,food嘛自然就是吃的,这里给了个随机初始化让游戏开始的时候食物随机放,然后最底下的是蛇头所在的数组位置,可以当作蛇的长度


输出字符

作为一名PS玩家,我把画面分成几个“图层”,从底向上覆盖输出,虽然看上去就很麻烦很没效率,不过做起来简单啊,又不是不能用

void print_map() {
    system("cls");
    set_boundry();
    set_snake();
    set_food();
    print_all();
}

思路就是先清屏→画边框→画蛇→画食物,这里的set相当于逐步画图层,然后print就是输出最终结果。接下来再分解来看。


画边框

void set_boundry() {
    for (int i = 0; i < 12; i++) {
        map[0][i] = map[11][i] = '*';
    }
    for (int i = 1; i < 11; i++) {
        map[i][0] = map[i][11] = '*';
        for (int j = 1; j < 11; j++)
            map[i][j] = ' ';
    }
}

这个其实就没什么好说的了,超简单的是吧。


画蛇

这里就是照着蛇的数组给“图层”上的特点位置打上“H”和“X”

void set_snake() {
    map[snakeX[snake_head]][snakeY[snake_head]] = 'H'; //the head
    for (int i = snake_head - 1; i >= 0; i--) {
        map[snakeX[i]][snakeY[i]] = 'X';
    }//the body
}

画食物

这里的设定是蛇头碰到食物时重新设定食物位置,这里我直接用了个暴力的随机方法,到游戏后面空间小的时候电脑会挺惨的吧。。。不过我是玩不到那么厉害了

void set_food() {
    //if the snake eat the food, change the place of the food
    if (snakeX[snake_head] == foodX && snakeY[snake_head] == foodY) {
        srand(time(0));
        while (1) {
            foodX = rand() % 10 + 1;
            foodY = rand() % 10 + 1;
            if (map[foodX][foodY] == ' ') {
                break;
            }//place the food in a blank place
        }
    }
    map[foodX][foodY] = '$';
}

输出字符

这里就是把通过以上设定调教好的map数组输出就行了

void print_all() {
    for (int i = 0; i < 12; i++) {
        for (int j = 0; j < 12; j++)
            printf("%c", map[i][j]);
        printf("\n");
    }
}

游戏环节

这里的设定:按下按键一次,蛇往相应方向走一格,然后判定有没有吃自己/怼墙/吃到东西等判定,如果有前两个就game over,至于后一个就重设食物位置,以及给蛇续一格

判断游戏是否继续

int game_run() {
    //when the snake hits the wall
    if (snakeX[snake_head] == 0 || snakeX[snake_head] == 11)
        return 0;
    if (snakeY[snake_head] == 0 || snakeY[snake_head] == 11)
        return 0;
    //when the snake eats itself
    for (int i = 0; i < snake_head - 1; i++) {
        if (snakeX[snake_head] == snakeX[i] && snakeY[snake_head] == snakeY[i])
            return 0;
    }
    return 1;
}

如果游戏能愉快地继续就返回1,gg了的话就返回0。


蛇的移动

首先通过getch()读入字符,然后通过不同字符对数组进行不同操作

        char ch = _getch();
        switch (ch) {
        case 'w':
            snake_move(-1, 0);
            break;
        case 's':
            snake_move(1, 0);
            break;
        case 'a':
            snake_move(0, -1);
            break;
        case 'd':
            snake_move(0, 1);
            break;
        }
void snake_move(int X, int Y) {
    //the snake eat the food, replace the food with a new head
    if (snakeX[snake_head] + X == foodX && snakeY[snake_head] + Y == foodY) {
        snake_head++;
        snakeX[snake_head] = foodX;
        snakeY[snake_head] = foodY;
    }
    //the snake doesn't hit the food, move forward
    else {
        int tempX = snakeX[snake_head];
        int tempY = snakeY[snake_head];
        snakeX[snake_head] += X;
        snakeY[snake_head] += Y;
        for (int i = 0; i < snake_head - 1; i++) {
            snakeX[i] = snakeX[i + 1];
            snakeY[i] = snakeY[i + 1];
        }
        snakeX[snake_head - 1] = tempX;
        snakeY[snake_head - 1] = tempY;
    }
}

这里看着挺复杂的,大概就是:如果吃到东西了就把食物位置加在snake数组后面,同时数组长度变量+1;如果没吃到就将蛇头像相应方向移动一格,接着数组中从头开始将[i+1]的值赋给[i],实现蛇的前进。


这样来看,每次按键都给数组进行相应的操作,最后一层一层输出,这样我们的低配贪吃蛇就做好啦
完整代码如下:

#include "stdafx.h"
#include <conio.h>
#include <stdlib.h>
#include <time.h>

//create data of the game
char map[12][12];
int snakeX[100] = { 1, 1, 1, 1, 1 };
int snakeY[100] = { 1, 2, 3, 4, 5 };
int foodX = rand() % 10 + 1;
int foodY = rand() % 10 + 1;
int snake_head = 4;

//make the snake move
void snake_move(int X, int Y) {
    //the snake eat the food, replace the food with a new head
    if (snakeX[snake_head] + X == foodX && snakeY[snake_head] + Y == foodY) {
        snake_head++;
        snakeX[snake_head] = foodX;
        snakeY[snake_head] = foodY;
    }
    //the snake doesn't hit the food, move forward
    else {
        int tempX = snakeX[snake_head];
        int tempY = snakeY[snake_head];
        snakeX[snake_head] += X;
        snakeY[snake_head] += Y;
        for (int i = 0; i < snake_head - 1; i++) {
            snakeX[i] = snakeX[i + 1];
            snakeY[i] = snakeY[i + 1];
        }
        snakeX[snake_head - 1] = tempX;
        snakeY[snake_head - 1] = tempY;
    }
}

//determine if the game is over
int game_run() {
    //when the snake hits the wall
    if (snakeX[snake_head] == 0 || snakeX[snake_head] == 11)
        return 0;
    if (snakeY[snake_head] == 0 || snakeY[snake_head] == 11)
        return 0;
    //when the snake eats itself
    for (int i = 0; i < snake_head - 1; i++) {
        if (snakeX[snake_head] == snakeX[i] && snakeY[snake_head] == snakeY[i])
            return 0;
    }
    return 1;
}

//set the wall
void set_boundry() {
    for (int i = 0; i < 12; i++) {
        map[0][i] = map[11][i] = '*';
    }
    for (int i = 1; i < 11; i++) {
        map[i][0] = map[i][11] = '*';
        for (int j = 1; j < 11; j++)
            map[i][j] = ' ';
    }
}

//set the snake
void set_snake() {
    map[snakeX[snake_head]][snakeY[snake_head]] = 'H'; //the head
    for (int i = snake_head - 1; i >= 0; i--) {
        map[snakeX[i]][snakeY[i]] = 'X';
    }//the body
}

//set the food
void set_food() {
    //if the snake eat the food, change the place of the food
    if (snakeX[snake_head] == foodX && snakeY[snake_head] == foodY) {
        srand(time(0));
        while (1) {
            foodX = rand() % 10 + 1;
            foodY = rand() % 10 + 1;
            if (map[foodX][foodY] == ' ') {
                break;
            }//place the food in a blank place
        }
    }
    map[foodX][foodY] = '$';
}

//print the map
void print_all() {
    for (int i = 0; i < 12; i++) {
        for (int j = 0; j < 12; j++)
            printf("%c", map[i][j]);
        printf("\n");
    }
}

//a whole process to print
void print_map() {
    system("cls");
    set_boundry();
    set_snake();
    set_food();
    print_all();
}

int main() {
    print_map();
    while (game_run()) {
        char ch = _getch();
        switch (ch) {
        case 'w':
            snake_move(-1, 0);
            break;
        case 's':
            snake_move(1, 0);
            break;
        case 'a':
            snake_move(0, -1);
            break;
        case 'd':
            snake_move(0, 1);
            break;
        }
        print_map();
    }
    printf("Game Over!!!");
    getchar();
}

然后我们就可以愉快(?)地调戏这条蛇啦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值