利用BFS实现贪吃蛇自动寻路

#include<vector>
#include<iostream>
#include<stack>
#include<graphics.h>
#include<ctime>
using namespace std;
const int COL=20;                                                                            
const int ROW=20;                                                                           
const int scole=20;
enum{                                                                                       
    UP,
    RIGHT,
    DOWN,
    LEFT,
};
class COORD_{                                                                                        //[x]CLASS COORD
public:
    int x,y;
    COORD_(){

    }
    COORD_(int x,int y){                                                                             
        this->x=x;
        this->y=y;
    }
    COORD_& operator=(COORD_&coord){
        this->x=coord.x;
        this->y=coord.y;
        return *this;
    }
    bool operator==(COORD_ coord){
        return (x==coord.x&&y==coord.y);
    }
};
class treeNode{
public:
    treeNode*pre;                                                                                   //previous node
    vector<treeNode*>next;                                                                          //next nodes
    COORD_ coord;                                                                                    //correct coord
    treeNode(COORD_ c){
        coord=c;
        pre=NULL;
    }
    treeNode& operator=(treeNode&t){
        this->next=t.next;
        this->coord=t.coord;
        this->pre=t.pre;
        return *this;
    }
};
class Node{
public:
    Node*next;
    COORD_ coord;
    Node(){};
    Node(COORD_ c){
        next=NULL;
        coord=c;
    }
};
class food{
public:
    COORD_ coord;
    bool is_exist;
    void creat_Food(Node*n){
        bool isok=0;
        while(!isok){
            Node*p=n;
            coord.x=rand()%COL;
            coord.y=rand()%ROW;
            while(p){
                if(p->coord==coord)
                    break;
                else
                    p=p->next;
            }
            if(p==NULL)
                isok=1;
        }
       
    }
    void draw_Food(){
        setfillcolor(GREEN);                                                                  //[x]red stands for head of snake 
        fillrectangle(coord.x*scole,coord.y*scole,(coord.x+1)*scole,(coord.y+1)*scole);
    }
};
void draw_map(){
    for(int i=0;i<ROW;i++){
            for(int j=0;j<COL;j++)
                rectangle(j*scole,i*scole,(j+1)*scole,(i+1)*scole);
        }
}
Node*get_Tail(Node*head){
    while(head->next){
        head=head->next;
    }
    return head;
}
Node*get_PreTail(Node*head){
    while(head->next->next){
        head=head->next;
    }
    return head;
}
Node*creat_Node(){
    Node*n=new Node;
    n->coord.y=10;
    n->coord.x=12;
    n->next=NULL;
    return n;
}
void insert_Tail(Node*head,int x,int y){
    Node*oldtail=get_Tail(head);
    Node*newtail=creat_Node();
    newtail->coord.x=x;
    newtail->coord.y=y;
    oldtail->next=newtail;
}
void creat_Body(Node*head){
    Node*Old_tail=get_Tail(head);
    Node*Old_Pre_Tali=get_PreTail(head);
    if(Old_Pre_Tali->coord.y<Old_tail->coord.y)
        insert_Tail(head,Old_tail->coord.x,Old_tail->coord.y+1);
    if(Old_Pre_Tali->coord.y>Old_tail->coord.y)
        insert_Tail(head,Old_tail->coord.x,Old_tail->coord.y-1);
    if(Old_Pre_Tali->coord.x<Old_tail->coord.x)
        insert_Tail(head,Old_tail->coord.x+1,Old_tail->coord.y);
    if(Old_Pre_Tali->coord.x>Old_tail->coord.x)
        insert_Tail(head,Old_tail->coord.x-1,Old_tail->coord.y);
    
}

bool can_Go(COORD_ c,int(*m)[COL],int(*hm)[COL]){                                                    //determine whether to go
    if(c.x<0||c.x>=COL||c.y<0||c.y>=ROW||hm[c.y][c.x]||m[c.y][c.x])
        return 0;
    return 1;
}


void insert_Tail(Node*head,COORD_ c){
    Node*oldtail=get_Tail(head);
    Node*newtail=new Node(c);
    oldtail->next=newtail;
}

void init_Snake(Node*head){
    for(int i=0;i<3;i++){
        COORD_ c={11-i,10};
        insert_Tail(head,c);
    }
}
                                                                             //map
void Move(Node**head,COORD_ c){
    Node*newhead=new Node(c);
    newhead->next=*head;
    Node*Old_pretail=get_PreTail(*head);
    Node*Old_tail=get_Tail(*head);
    delete Old_tail;
    Old_pretail->next=NULL;
    *head=newhead;
}
void draw_Snake(Node*head){
    
    setfillcolor(RED);                                                                  //[x]red stands for head of snake 
    fillrectangle(head->coord.x*scole,head->coord.y*scole,(head->coord.x+1)*scole,(head->coord.y+1)*scole);
    head=head->next;                                                                          
    setfillcolor(RGB(211,181,44));                                                                //[x]white stands for body of snake
    while(head){
        fillrectangle(head->coord.x*scole,head->coord.y*scole,(head->coord.x+1)*scole,(head->coord.y+1)*scole);
        head=head->next;
    }
}
void updateMap(int(*m)[COL],Node*n){
    while(n){
        m[n->coord.y][n->coord.x]=1;
        n=n->next;
    }
}
void run(Node**head,food* f){
    int help_map[ROW][COL]={0};                                                                         //Auxiliary map
    int map[ROW][COL]={0};  
    updateMap(map,*head);
    COORD_ beginCoord=(*head)->coord;
    COORD_ endCoord=f->coord;
    help_map[beginCoord.y][beginCoord.x]=1;                                                         //Mark the coordinates of the starting point in the auxiliary map and walk through
    treeNode*Root=new treeNode(beginCoord);
    vector<treeNode*>currect_Layer;
    vector<treeNode*>next_Layer;
    currect_Layer.push_back(Root);
    COORD_ tentative_Point;                                                                          //tentative_Point
    treeNode*correct_TreeNode=NULL;
    bool is_Find=0;
    stack<COORD_>path;
    while(1){
        next_Layer.clear();
        for(int i=0;i<currect_Layer.size();i++){
            
            for(int j=0;j<4;j++){
                switch(j){
                    case UP:
                        tentative_Point.x=currect_Layer[i]->coord.x;
                        tentative_Point.y=currect_Layer[i]->coord.y-1;
                    break;
                    case LEFT:
                        tentative_Point.x=currect_Layer[i]->coord.x-1;
                        tentative_Point.y=currect_Layer[i]->coord.y;
                    break;
                    case DOWN:
                        tentative_Point.x=currect_Layer[i]->coord.x;
                        tentative_Point.y=currect_Layer[i]->coord.y+1;
                    break;
                    case RIGHT:
                        tentative_Point.x=currect_Layer[i]->coord.x+1;
                        tentative_Point.y=currect_Layer[i]->coord.y;
                    break;
                }
                if(can_Go(tentative_Point,map,help_map)){
                    help_map[tentative_Point.y][tentative_Point.x]=1;
                    correct_TreeNode=new treeNode(tentative_Point);
                    correct_TreeNode->pre=currect_Layer[i];
                    currect_Layer[i]->next.push_back(correct_TreeNode);
                    next_Layer.push_back(correct_TreeNode);
                    if(tentative_Point==endCoord){
                        is_Find=1;
                        break;
                    }
                }
            }//j
            if(is_Find){
                break;
            }
        }//i

        if(!next_Layer.size())
            break;
        currect_Layer=next_Layer;
        if(is_Find){
            break;
        }
    }//while
    if(is_Find){
        
        while(correct_TreeNode){
            path.push(correct_TreeNode->coord);
            correct_TreeNode=correct_TreeNode->pre;
        }
        path.pop();
        DWORD t1,t2;
        t1=GetTickCount();
        BeginBatchDraw();
        //while(!path.empty()){
           
            t2=GetTickCount();
            while(t2-t1<50){
                t2=GetTickCount();
            }
                cleardevice();
                
                draw_map();
                f->draw_Food();
                Move(head,path.top());
                draw_Snake(*head);
                
                EndBatchDraw();
                path.pop();
                
                
            
            
            
            
            
        //}
        if((*head)->coord==endCoord){
            creat_Body(*head);
            f->creat_Food(*head);
        }
        
    }
    else
        exit(0);
    
}

int main(){
    srand((unsigned)time(NULL));
    initgraph(COL*scole,ROW*scole);
    Node *head;
    head=creat_Node();
    init_Snake(head);
    food* f;
    f=new food;
    f->creat_Food(head);
    draw_Snake(head);
    while(1){
        run(&head,f);
    }
    
   

    
    return 0;
}

运行exe文件后会出现一点bug

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值