设计简单的智能蛇

概念

智能蛇是让贪吃蛇在有限的地图内走动,吃食物使身体变长使得能够走的步数最多。

思路

既然是让步数最多,又由于对问题的简化局面中每次只会有一个食物,且无除边界外的障碍物。
可以想到比较 trick 的做法,当行数 n 或列数 m 为偶数时,可以构造哈密顿回路使得蛇必定可以在铺满整个地图后结束游戏。
当行数和列数都为奇数时,不存在哈密顿回路。所以只能设计估价函数来判断当前蛇应该走的方向。
一个比较简单容易想到的估价函数是,让蛇往最短路的方向走,并尽量让蛇走上一次移动的方向。

代码

下面的代码运行时会让你输入行数 n 和列数 m ,然后就可以看到智能(障)蛇了。
//蛇长度初始是5 H代表蛇的头部 X是蛇的身体
//输入行数为 n 列数为 m  
//0 1 2 3 分别代表右下左上
#include<bits/stdc++.h>
#define inf 1e9
#define rep(i,l,r) for (int i=l;i<=r;i++)
using namespace std;
int n,m,mcnt=0,x=1,y=5,pre,rx,ry,len=5;
struct node{int x,y;};
queue<node> q;
char Map[1005][1005];
void makemap(){
    puts("n=");
    scanf("%d",&n);
    system("cls");
    puts("m=");
    scanf("%d",&m);
    system("cls");
    rep(i,0,n+1) rep(j,0,m+1) Map[i][j]=' ';
    rep(i,0,m+1) Map[0][i]=Map[n+1][i]='*';
    rep(i,0,n+1) Map[i][0]=Map[i][m+1]='*';
    rep(i,1,4) Map[1][i]='X',q.push((node){1,i});
    Map[1][5]='H'; q.push((node){1,5}); 
}
void init(){
    while (1){
        if (mcnt) break;
        rx=rand()%n+1,ry=rand()%m+1;
        if (Map[rx][ry]==' ') Map[rx][ry]='M',mcnt++;   
    }
    rep(i,0,n+1) {
        rep(j,0,m+1) printf("%c",Map[i][j]); puts("");  
    }
}
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
int solve(int i){
    int xx=x+dx[i],yy=y+dy[i];
    if (Map[xx][yy]!=' '&&Map[xx][yy]!='M') return 0;
    if (Map[xx][yy]!='M') {
        Map[q.front().x][q.front().y]=' '; q.pop(); 
    } else mcnt--,len++;
    Map[x][y]='X'; 
    Map[xx][yy]='H'; q.push((node){xx,yy}); x=xx; y=yy;  
    return 1;
}
void trick(){
    if (x==m&&y==2) {solve(2); return;}
    if (x==1&&y==1) {solve(0); return;}
    if (y==1) solve(3);
    else {
        if (y==2) {
            if (!solve(0)) solve(1);
        }
        else if (y==m){
            if (!solve(2)) solve(1);    
        }
        else {
            if (!solve(0)) solve(2);    
        }
    }
}
void trick2(){
    if (x==1&&y==m) {solve(1); return;}
    if (x==2&&y==1) {solve(3); return;}
    if (x==1) solve(0);
    else {
        if (x==2) {
            if (!solve(1)) solve(2);    
        }
        else if (x==n){
            if (!solve(3)) solve(2);    
        }
        else if (!solve(1)) solve(3);
    }
}
int main(){
    srand(time(NULL));
    makemap();
    pre=0;
    while (1){
        init();
        int time=clock(); 
        while (clock()-time<100);
        int mn=inf,mni=-1;
        int xx=x+dx[pre],yy=y+dy[pre];
        if ((n&1)==0) {trick(); goto o;}
        if ((m&1)==0) {trick2(); goto o;}
        if (abs(xx-rx)+abs(yy-ry)<mn&&(Map[xx][yy]==' '||Map[xx][yy]=='M')) {
            mn=abs(xx-rx)+abs(yy-ry); mni=pre;  
        }
        rep(i,0,3) {
            int xx=x+dx[i],yy=y+dy[i];
            if (abs(xx-rx)+abs(yy-ry)<mn&&(Map[xx][yy]==' '||Map[xx][yy]=='M')) {
                mn=abs(xx-rx)+abs(yy-ry); mni=i;    
            }   
        }
        solve(mni); pre=mni;

        if (mni==-1) {puts("GAME OVER"); break;}
        o:;
        if (len==n*m) {puts("GAME OVER"); break;}
        system("cls");
    }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值