#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