智能蛇

      博主初学c,简单的做了一个贪吃蛇,在此记录下我做贪吃蛇的过程,不足之处望各位博友见谅。

      因为博主才疏学浅,所以博主这次只用数组来完成这个程序。

      话不多说,直接上码。

      主函数:

int main()
  {
      int dir=UP;
      while (1){
        print_game();
         dir=get_dir(dir);
          move_snake(dir);
          if (!isalive())
              break;
     }
     printf("Game Over\n");
 }

正如博客名所示,博主只用数组。那么我们用一个二维数组char map[17][17]来表示地图,用一维数组unsigned char snake[15]来表示蛇的坐标。这里之所以用char是因为本着能省则省的原则,我们这是一个17*17大小的小游戏,char足够了。

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


#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define SNAKE 1
#define FOOD 2
#define BAR 3


char map[17][17] = { 0 };
unsigned char snake[50] = { 77 };
unsigned char food = 68;
char len = 1;


void tran(unsigned char num,unsigned char *x, unsigned char *y)
{
    *x = num >> 4;
    *y = (unsigned char)(num << 4) >> 4;
}

碰到被调用函数需要返回两个以上参数的时候,应该像上述函数一样,将要返回的值写成指针参数。

接下来,让我们把主函数里调用的函数一一填上。

void print_game(void)
{
    int i, j;
    for (i = 0; i<17; i++) {
        for (j = 0; j<17; j++) {
            if (map[i][j] == 0)
                putchar(' ');
            else if (map[i][j] == SNAKE)
                putchar('*');
            else if (map[i][j] == BAR)
                putchar('#');
            else if(map[i][j]==FOOD)
                putchar('!');
        }
        putchar('\n');
    }
    Sleep(100);
    system("cls");
}

int get_dir(int old_dir)
{
    int new_dir = old_dir;
    if (_kbhit()) {
        _getch();
        new_dir = _getch();
        if (len > 1 && (abs(new_dir - old_dir) == 2 || abs(new_dir - old_dir) == 8))
            new_dir = old_dir;
    }
    return new_dir;
}

接下来是移动蛇身的函数(游戏的大部分内容都在其中):

void move_snake(int dir)
{
    int last = snake[0],current;
    int i, j;
    int grow=0;
    unsigned char x, y,fx,fy;
    tran(food, &fx, &fy);
    tran(snake[0], &x, &y);
    switch (dir){
    case UP:
        y--;
        break;
    case DOWN:
        y++;
        break;
    case LEFT:
        x--;
        break;
    case RIGHT:
        x++;
        break;
    }
    snake[0] = ((x ^ 0) << 4) ^ y;
    if (snake[0] == food) {
        grow = 1;
        food = generate_food();
    }
    for (i = 0; i<len; i++) {
        if (i == 0)
            continue;
        current = snake[i];
        snake[i] = last;
        last = current;
    }
    if (grow) {
        snake[len] = last;
        len++;
    }
    for (i = 0; i < 17; i++)
        for (j = 0; j < 17; j++)
            if (i == 0 || i == 16 || j == 0 || j == 16)
                map[i][j] = BAR;
            else if (i == fy&&j == fx)
                map[i][j] = FOOD;
            else
                map[i][j] = 0;
    for (i = 0; i < len; i++) {
        tran(snake[i], &x, &y);
        if (snake[i] > 0)
            map[y][x] = 1;
    }
}

其中有个生产食物的函数,generate_food(),它利用随机数生成函数生成食物坐标,代码如下:

unsigned char generate_food(void)
{
    unsigned char food_,fx,fy;
    int in_snake=0,i;
    srand((unsigned int)time(NULL));
    do {
        food_ = rand() % 255;
        tran(food_, &fx, &fy);
        for (i = 0; i < len; i++)
            if (food_ == snake[i])
                in_snake = 1;
    } while (fx == 0 || fx == 16 || fy == 0 || fy == 16 || in_snake);
    return food_;
}

随机数生成函数,一般由srand()和rand()函数组成,前者以当前时间为参数提供种子供rand()函数生成更为随机的数。这里用do while语句做了一个筛选,最后产生在边界内且不再蛇身上的食物。

最好剩下一个判断蛇死活的函数,直接上代码吧:

int isalive(void)
{
    int self_eat = 0, i;
    unsigned char x, y;
    tran(snake[0], &x, &y);
    for (i = 1; i < len; i++)
        if (snake[0] == snake[i])
            self_eat = 1;
    return (x == 0 || x == 16 || y == 0 || y >= 16 || self_eat) ? 0 : 1;
}

好了,有了这些函数,把他们组装起来就成了我们的简易贪吃蛇游戏。游戏画面如下:


原创文章 12 获赞 4 访问量 3276

猜你喜欢

转载自blog.csdn.net/zdxy921/article/details/78866380
今日推荐