字符游戏-智能蛇

在有了上一篇博客中的普通贪吃蛇的基础后,我们来思考一下如何制作一个智能蛇。也就是说写出一个程序让这个贪吃蛇自己前进,自己寻找食物,但同时又要让它不要撞到墙壁或者自己的身体,并且不要让它太过于目光短浅,为了吃到当前食物而将自己困死。

首先我们来考虑一下最简单的情况:知道头和食物的坐标,怎样用最短路线走到食物。 这种情况确实特别简单,因为我们知道两点的坐标,通过比较横坐标大小就可以知道是向左走还是右走,比较纵坐标就可以知道是向上走还是下走。 而且适用这种算法的情况也很明确:只要头和食物坐标之间的区域什么都没有,我们就可以选择这么走。 代码如下:

int explorer(int x1,int y1,int x2,int y2)
{
    int i,j,mid;
    if(x2<x1) {
        mid=x1;
        x1=x2;
        x2=mid;
    }
    if(y2<y1) {
        mid=y1;
        y1=y2;
        y2=mid;
    }
    for(i=x1;i<=x2;i++) {
        for(j=y1;j<=y2;j++) {
            if(map[j][i]=='*')return 1;
        }
    }
    return 0;
}
char AI(int x1,int y1,int x2,int y2,char direction)
{
    int wide,length,noa=0,nos=0,nod=0,now=0,M;
    char think;
    if(explorer(x1,y1,x2,y2)==1)goto run;
    wide=x1-x2;
    if(wide<0)wide*=-1;
    length=y1-y2;
    if(length<0)length*=-1;
    if(x1<x2)think='a';
    if(x1>x2)think='d';
    if(y1<y2)think='w';
    if(y1>y2)think='s'; 
    return think;
}

如果不是这种情况呢,其实大多数时候都不是这样的情况。这些时候,我们就要让这条蛇自己找路。但是找路不是漫无目的的乱走,即使在找路,也要尽可能的向食物的方向靠近,所以我引入了评分机制,也就是说对每个方向评分,用分数来评判那条路最好。
评分标准:
1.如果下一步走某个方向就会撞上障碍物,当然这条路是绝对不能走的,所以没有任何加分,也就是零分。
2.当然,很多时候有多个方向可走,那么给这些下一步可走的方向两分初始分。
3.有些时候走出下一步,结果所有方向都会被堵死,这样的方向是绝对不能走的,对与这些方向,即使有再多加分也直接清零。相当于这是对下一步的一种预判。
4.当蛇变长之后就会发现,如果蛇能够贴着自己身体走,比起满屏乱跑存活率要高的多。所以下一步如果能够贴着身体的话就再加一分。
5.当然在保证能够生存的前提下,我们应该尽可能的向食物靠近。比如食物在相对于蛇头在左上方,那么W、A两个方向的评分就会加一分。
6.以上五条评分方法后运行贪吃蛇发现,贪吃蛇的死法都是因为自己的身体围成了一个口袋形,然后这条傻蛇一头栽进去,一去不复返。观察发现,口袋形致死的很大程度原因因为蛇在进入口袋的时候把口袋入口给封死了。所以我在蛇的长度超过20之后加入一条评分,当该前进方向上第二格有障碍物时减一分。这样可以让蛇进入口袋时很大概率为自己留一条出路。
评分代码如下:

    if(map[y2][x2-1]==' ') {
            noa+=2;
            if(x1<x2)noa++;
            if((map[y2+1][x2-1]=='*')||(map[y2-1][x2-1]=='*'))noa++;
            if((map[y2+1][x2-1]=='*')&&(map[y2-1][x2-1]=='*'))noa--;
            if((map[y2][x2-2]=='*')&&(lenght>=20))noa--;
            if((map[y2+1][x2-1]=='*')&&(map[y2-1][x2-1]=='*')&&(map[y2][x2-2]=='*'))noa=0;
        }
        if(map[y2][x2+1]==' ') {
            nod+=2;
            if(x2<x1)nod++;
            if((map[y2+1][x2+1]=='*')||(map[y2-1][x2+1]=='*'))nod++;
            if((map[y2+1][x2+1]=='*')&&(map[y2-1][x2+1]=='*'))nod--;
            if((map[y2][x2+2]=='*')&&(lenght>=20))nod--;
            if((map[y2+1][x2+1]=='*')&&(map[y2-1][x2+1]=='*')&&(map[y2][x2+2]=='*'))nod=0;
        }
        if(map[y2-1][x2]==' ') {
            now+=2;
            if(y1<y2)now++;
            if((map[y2-1][x2+1]=='*')||(map[y2-1][x2-1]=='*'))now++;
            if((map[y2-1][x2+1]=='*')&&(map[y2-1][x2-1]=='*'))now--;
            if((map[y2-2][x2]=='*')&&(lenght>=20))now--;
            if((map[y2-1][x2+1]=='*')&&(map[y2-1][x2-1]=='*')&&(map[y2-2][x2]=='*'))now=0;
        }
        if(map[y2+1][x2]==' ') {
            nos+=2;
            if(y2<y1)nos++;
            if((map[y2+1][x2+1]=='*')||(map[y2+1][x2-1]=='*'))nos++;
            if((map[y2+1][x2+1]=='*')&&(map[y2+1][x2-1]=='*'))nos--;
            if((map[y2+2][x2]=='*')&&(lenght>=20))nos--;
            if((map[y2+1][x2+1]=='*')&&(map[y2+1][x2-1]=='*')&&(map[y2+2][x2]=='*'))nos=0;
        }
        M=max(noa,nos,nod,now);
        if(M==1)return 'a';
        if(M==2)return 's';
        if(M==3)return 'd';
        if(M==4)return 'w';

在这种评分机制下的最高得分是64分,这样的评分机制并不能解决蛇的长度增加后将自己围死的情况。
这里写图片描述

因为做这个贪吃蛇只用了一晚上时间,这个评分方法肯定存在很多漏洞。比如每种情况究竟该分配多少分,以及还应该考虑多少情况。最大的问题就是如何让蛇“更有远见”。 我会继续思考这个问题,并改进贪吃蛇,也欢迎大家提出意见。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值