来个贪吃蛇的进阶~简单的智能蛇

由于上篇关于贪吃蛇的做法,我已将自己的做法详述地介绍,所以此片不做多余的介绍关于贪吃蛇,这里主要介绍贪吃蛇的进阶版。
首先,我们要思考如何写出一条智能设,使它‘思考’,所以想想,蛇每打算走一步,都先想想是往四个方向的哪个走,所以它先计算每个方向到食物的位置,然后选出最小的方向,但最小的方向也可能有它的身体或墙,所以必须判断一下,看看是否有障碍,如果有,就在另外三条中选择,以此内推,先写出伪代码。
控制方向

 // Hx,Hy: 头的位置
    // Fx,Fy:食物的位置
    function whereGoNext(Hx,Hy,Fx,Fy) {
    // 用数组movable[3]={“a”,”d”,”w”,”s”} 记录可走的方向
    // 用数组distance[3]={0,0,0,0} 记录离食物的距离
    // 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
    //     例如:假设输入”a” 则distance[0] = |Fx – (Hx-1)| + |Fy – Hy|
    //           如果 Hx-1,Hy 位置不是Blank,则 distance[0] = 9999
    // 选择distance中存最小距离的下标p,注意最小距离不能是9999
    // 返回 movable[p]
    }

程序框架

输出字符矩阵
    WHILE not 游戏结束 DO
        wait(time)
        ch=whereGoNext(Hx,Hy,Fx,Fy)
        CASE ch DO
        ‘A’:左前进一步,break 
        ‘D’:右前进一步,break    
        ‘W’:上前进一步,break    
        ‘S’:下前进一步,break    
        END CASE
        输出字符矩阵
    END WHILE
    输出 Game Over!!! 

开始,先计算距离

int cal_dis(int m,int n)
{
    int ins_x = snake_x[snake_length-1];
    int ins_y = snake_y[snake_length-1];
    int dis;
    dis = abs(food_x-(ins_y-m))+abs(food_y-(ins_x-n));// notice
    return dis;
}
int abs(int a)
{
    if(a>=0)
    return a;
    return -a;
}

选择最小

int*get_min(int*a,int*b,int*c,int*d)
{
    int*jmin;
    jmin = *a<=*b?a:b;
    jmin = *jmin<=*c?jmin:c;
    jmin = *jmin<=*d?jmin:d;
    return jmin;
}

然后选择方向

int snake_where_to_go(int min1,int dist_a,int dist_s,int dist_d,int dist_w)
{
    if(min1 == dist_a)
    {
        snakeHeadMove(-1,0);
        if(map[snake_y[snake_length-1]][snake_x[snake_length-1]-1]!='x'&&map[snake_y[snake_length-1]][snake_x[snake_length-1]-1]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;
    }
    if(min1 == dist_s)
    {
        snakeHeadMove(0,1);
        if (map[snake_y[snake_length-1]+1][snake_x[snake_length-1]]!='x'&&map[snake_y[snake_length-1]+1][snake_x[snake_length-1]]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;
    }
    if(min1 == dist_d )
    {
        snakeHeadMove(1,0);
        if( map[snake_y[snake_length-1]][snake_x[snake_length-1]+1]!='x'&&map[snake_y[snake_length-1]][snake_x[snake_length-1]+1]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;       
    }
    if(min1 == dist_w)
    {
        snakeHeadMove(0,-1);
        if(map[snake_y[snake_length-1]-1][snake_x[snake_length-1]]!='x'&&map[snake_y[snake_length-1]-1][snake_x[snake_length-1]]!='*')
        {
            gameover();
            return 1;
        }
        else 
            return 0;
    }
    return 0;
}

蛇的控制逻辑

while(!input)
        {
            int i,j,mid;
            char ins;
            distan[0]= cal_dis(0,1);
            distan[1]= cal_dis(-1,0);
            distan[2]= cal_dis(0,-1);
            distan[3]= cal_dis(1,0);
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            break;
        }
    printf("Game over!!!");

所以我们得到的智能蛇的完全代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#define max_length 100
#define snake_body 'x'
#define snake_head 'H'
void output(void);
void put_money(void);
int*get_min(int*a,int *b,int *c,int *d);
int judge(int a ,int b);
int abs(int a);
int snake_where_to_go(int min,int dist_a,int dist_s,int dist_d,int dist_w);
int cal_dis(int m,int n);
void snakeHeadMove(int m,int n);
//int get_min1(int a,int b,int c);
//int get_min2(int a,int b);;
int min_dis(void);
int food_x=0,food_y=0;
int gameover(void);
void snakemove(void);
int min_x=0,min_y=0;
char map[12][12]=
     {"***********",
      "*xxxxH    *",
      "*         *",
      "*    *    *",
      "*    *    *",
      "*    *    *",
      "*    *    *",
      "*    *    *",
      "*         *",
      "*         *",
      "*         *",
      "***********"};//initialize the picture
int snake_length=5;
int distan[4]={0};
int snake_x[max_length]={1,2,3,4,5};
int snake_y[max_length]={1,1,1,1,1};
int main()
{
    int *min,i=0;
    char input=0,c;
    put_money();
    output();//output the picture
    while(!input)
    {
        c = getch();//read the botton
        switch (c) //move the snake head
            {
                case 'w': snakeHeadMove(0,-1); break;
                case 's': snakeHeadMove(0,1); break;
                case 'a': snakeHeadMove(-1,0); break;
                case 'd': snakeHeadMove(1,0); break;
                case 'z': goto part;
            }
        input = gameover();
        if(input) break;//judge if game is over
        /*while(getchar() != '\n')//cancel the '\n' when to entry the botton 
            break;*/    
    }
    part :
    while(!input)
        {
            int i,j,mid;
            char ins;
            distan[0]= cal_dis(0,1);
            distan[1]= cal_dis(-1,0);
            distan[2]= cal_dis(0,-1);
            distan[3]= cal_dis(1,0);
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            *min = 999;
            min = get_min(&distan[0],&distan[1],&distan[2],&distan[3]);
            i = snake_where_to_go(*min,distan[0],distan[1],distan[2],distan[3]);
            if(i)
            continue;
            break;
        }
    printf("Game over!!!");
}
int*get_min(int*a,int*b,int*c,int*d)
{
    int*jmin;
    jmin = *a<=*b?a:b;
    jmin = *jmin<=*c?jmin:c;
    jmin = *jmin<=*d?jmin:d;
    return jmin;
}
int snake_where_to_go(int min1,int dist_a,int dist_s,int dist_d,int dist_w)
{
    if(min1 == dist_a)
    {
        snakeHeadMove(-1,0);
        if(map[snake_y[snake_length-1]][snake_x[snake_length-1]-1]!='x'&&map[snake_y[snake_length-1]][snake_x[snake_length-1]-1]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;
    }
    if(min1 == dist_s)
    {
        snakeHeadMove(0,1);
        if (map[snake_y[snake_length-1]+1][snake_x[snake_length-1]]!='x'&&map[snake_y[snake_length-1]+1][snake_x[snake_length-1]]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;
    }
    if(min1 == dist_d )
    {
        snakeHeadMove(1,0);
        if( map[snake_y[snake_length-1]][snake_x[snake_length-1]+1]!='x'&&map[snake_y[snake_length-1]][snake_x[snake_length-1]+1]!='*')
        {
            gameover();
            return 1;
        }
        else
            return 0;       
    }
    if(min1 == dist_w)
    {
        snakeHeadMove(0,-1);
        if(map[snake_y[snake_length-1]-1][snake_x[snake_length-1]]!='x'&&map[snake_y[snake_length-1]-1][snake_x[snake_length-1]]!='*')
        {
            gameover();
            return 1;
        }
        else 
            return 0;
    }
    return 0;
}
int cal_dis(int m,int n)
{
    int ins_x = snake_x[snake_length-1];
    int ins_y = snake_y[snake_length-1];
    int dis;
    dis = abs(food_x-(ins_y-m))+abs(food_y-(ins_x-n));// notice
    return dis;
}
int abs(int a)
{
    if(a>=0)
    return a;
    return -a;
}
void output(void)// output the picture
{
        #ifdef _WIN32
    system("cls");
    #else
    system("clear");
    #endif
    int i =0;
    while(i<12)
    {
        printf("%s\n",map[i]);
        i++;
    }
        printf("if you want to play you self,press 'a' 's' 'd' 'w'\n");
    printf("if you want to look intelligent snake ,press 'z'\n");
}
void put_money(void)//put the money randomly
{ 
    srand((unsigned int)time(0));
    while(map[food_x][food_y]=='*'||map[food_x][food_y]==snake_body||map[food_x][food_y]==snake_head)
    {
        food_x = rand()%10 + 1;
        food_y = rand()%10 + 1;
    }
    map[food_x][food_y] = '$';
}

void snakeHeadMove(int m,int n)// move the snake head
{
    snake_x[snake_length]=snake_x[snake_length-1]+m;
    snake_y[snake_length]=snake_y[snake_length-1]+n;
}

int gameover(void)
{
    int i,j,mid;
    char ins;
    if(map[snake_y[snake_length]][snake_x[snake_length]]==snake_body||map[snake_y[snake_length]][snake_x[snake_length]]=='*')
        return 1;//return 1 if snake is dead
    else if(map[snake_y[snake_length]][snake_x[snake_length]]=='$')//eat the money
        {
            mid = snake_length;
            map[snake_y[mid]][snake_x[mid]] = snake_body;//put 'x' in the front of head
            ins = map[snake_y[mid-1]][snake_x[mid-1]];
            map[snake_y[mid-1]][snake_x[mid-1]] = map[snake_y[mid]][snake_x[mid]];
            map[snake_y[mid]][snake_x[mid]] = ins;//change the position of snakehead and 'x'
            snake_length++;//the length of snake add 1
            put_money();//put money
            output();
            return 0;
        }
    else 
        {
            snakemove();// move the snake
            output();
            return 0;
        }
}

void snakemove(void)//move the snake
{
    int i,j;
    char ins;
    for(i=snake_length;i > 0;i--)
        {
            ins=map[snake_y[i]][snake_x[i]];
            map[snake_y[i]][snake_x[i]]=map[snake_y[i-1]][snake_x[i-1]];
            map[snake_y[i-1]][snake_x[i-1]]=ins;//move
        }
        for(j=0;j<=snake_length;j++)//change the ordinate of snake 
        {
            snake_x[j]=snake_x[j+1];
            snake_y[j]=snake_y[j+1];
        }
        snake_x[snake_length]=0;
        snake_y[snake_length]=0;
}

终于,我们可以看到我们的贪吃蛇即可以自己躲避障碍物(就算是自己添加的,也只需在代码中补充一点点就可以了),但这条蛇不能主动地选出最佳路线,可能会走到死胡同,如何选择路线,请读者自行思悟(作者能力有限),当然这篇博客较于上一篇还是有些省略,请读者仔细思考上面的代码,再写出自己的智能贪吃蛇
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值