您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 贪吃蛇AI版(C++)
#includeiostream#includequeue//STL中的队列;#includestringusingnamespacestd;#includemath.h#includeconio.h#includewindows.h#includetime.h//使用当前时间做种子;enumdir{up_,down_,left_,right_};//枚举类型enumdir;charversa_trend;//versa_trend是和蛇头将要走的方向相反的方向;inttime_,score;//停顿时间和得分;intfoodX,foodY;//食物坐标;intmap;//地图大小;charstr[100];//防止玩游戏者乱输入内容;charmap_[100];//防止玩游戏者乱输入内容;voidGotoxy(intx,inty)//光标定位函数{COORDpos={y,x};HANDLEhOut=GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFOcursor_info;GetConsoleCursorInfo(hOut,&cursor_info);cursor_info.bVisible=false;cursor_info.dwSize=20;SetConsoleCursorPosition(hOut,pos);SetConsoleCursorInfo(hOut,&cursor_info);}classFence//围墙;{public:chargame[20][20];public:voidInitFence();voidOutputF();}f;//定义对象;voidFence::InitFence()//画框框;{for(inti=0;imap;i++){for(intj=0;jmap;j++){if(i==0||i==map-1)game[i][j]='-';elseif(j==0||j==map-1)game[i][j]='I';elsegame[i][j]='';}}game[0][0]='*';game[0][map-1]='*';game[map-1][0]='*';game[map-1][map-1]='*';}voidFence::OutputF()//显示框框和蛇;{if(score==(map-2)*(map-2)-3)system(cls);for(inti=0;imap;i++){for(intj=0;jmap;j++)printf(%c,game[i][j]);coutendl;}if(score)cout最终得分:;elsecout当前得分:;coutscoreendl;//score=(map-2)*(map-2)-3时通关;if(score==(map-2)*(map-2)-3){cout恭喜通关!!!按任意键退出游戏。endl;system(pause);exit(0);}}classSnakeNode//蛇结点;{private:intx,y;SnakeNode*prior,*next;//结点之前,结点之后;public:intget_x();intget_y();voidadd_head(intx,inty);SnakeNodeget_prior();SnakeNodeget_next();voiddelete_tail();voidPopAllSnakeNode();}*head=NULL,*tail=NULL;SnakeNodeSnakeNode::get_prior(){return*prior;}SnakeNodeSnakeNode::get_next(){return*next;}voidSnakeNode::add_head(intx,inty)//插入头结点;{if(head){f.game[(*head).get_x()][(*head).get_y()]='*';//蛇身标记;Gotoxy((*head).get_x()+2,2*(*head).get_y());//光标定位;cout*;}SnakeNode*q=newSnakeNode;(*q).x=x;(*q).y=y;(*q).next=head;(*q).prior=NULL;if(head)(*head).prior=q;head=q;if(!tail)tail=head;f.game[x][y]='O';//蛇头标记;Gotoxy(x+2,2*y);coutO;}intSnakeNode::get_x(){returnx;}intSnakeNode::get_y(){returny;}voidSnakeNode::delete_tail()//删除尾结点;{f.game[(*tail).get_x()][(*tail).get_y()]='';//把尾结点的坐标表示的*置为空格;Gotoxy((*tail).get_x()+2,2*(*tail).get_y());cout;if(tail==head)tail=NULL;else{SnakeNode*q;q=tail;tail=(*tail).prior;(*tail).next=NULL;deleteq;}}classmove//move移动;{public:dirpoint;//枚举变量point:控制方向;intfood_x;intfood_y;public:voidmoving();voidchange_point(char);//改变方向;voidget_food();};voidmove::moving(){inta,b;a=(*head).get_x();//取得头结点横坐标;b=(*head).get_y();//取得头结点纵坐标;switch(point){caseup_:--a,versa_trend='s';break;casedown_:++a,versa_trend='w';break;caseleft_:--b,versa_trend='d';break;caseright_:++b,versa_trend='a';break;}if((a==map-1||b==map-1||a==0||b==0||f.game[a][b]=='*')&&(a!=(*tail).get_x()||b!=(*tail).get_y()))//判断是否撞墙和撞自己;{system(cls);//清屏函数;printf(最终得分:%d\n,score);printf(gameover!!!\n);printf(是否再来一局?请输入Y或N\n);while(1){cinstr;if((str[0]=='N'||str[0]=='Y')&&str[1]=='\0')break;elsecout输入错误,请重新输入:;}system(cls);if(str[0]=='N')exit(0);}elseif(a==foodX&&b==foodY)//吃food;{(*head).add_head(a,b);if(score(map-2)*(map-2)-4)get_food();score++;Gotoxy(map-10+12,9);coutscore;if(score==(map-2)*(map-2)-3)f.OutputF();}else{(*head).delete_tail();//删除尾结点;(*head).add_head(a,b);//插入头结点;}}voidmove::change_point(charkeydown)//keydown记录蛇头将要走的方向;{switch(keydown){case'w':point=up_;break;case's':point=down_;break;case'a':point=left_;break;case'd':point=right_;break;}}voidmove::get_food()//随机出food;{srand((unsigned)time(NULL));//做种子(程序运行时间);do{food_x=rand()%(map-2)+1;food_y=rand()%(map-2)+1;foodX=food_x;foodY=food_y;if(f.game[food_x][food_y]=='')f.game[food_x][food_y]='$';//防止food出现在蛇上;}while(f.game[food_x][food_y]!='$');Gotoxy(food_x+2,2*food_y);//光标定位;cout$;}classPoint//点坐标类,入队列用;{public:intx;inty;};boolbfs(intfuture_head_x,intfuture_head_y)//广度优先搜索,从蛇头出发经过空格找蛇尾;{if(future_head_x==(*tail).get_x()&&future_head_y==(*tail).get_y())returntrue;//该点为蛇尾;if(f.game[future_head_x][future_head_y]=='-'||f.game[future_head_x][future_head_y]=='I'||f.game[future_head_x][future_head_y]=='*')returnfalse;//该点不可走;Pointnode,tem,t;node.x=future_head_x;node.y=future_head_y;boolvis[20][20]={0};//标记该点是否走过,0没走过,1已走过;vis[node.x][node.y]=1;inti,dx[]={-1,0,1,0},dy[]={0,-1,0,1};//记录四个方向;queuePointq;q.push(node);//结点入队;if(f.game[future_head_x][future_head_y]!='$')f.game[(*tail).get_x()][(*tail).get_y()]='';//如果该结点不为食物,蛇尾结点变为蛇尾前面的结点prior,忽略原本的蛇尾结点;while(!q.empty())//队列非空;{t=q.front(),q.pop();//取出队首元素;for(i=0;i4;i++){tem.x=t.x+dx[i],tem.y=t.y+dy[i];//下一个方向;if(f.game[future_head_x][future_head_y]=='$')//如果该结点为食物;{if(tem.x==(*tail).get_x()&&tem.y==(*tail).get_y())//找到蛇尾;{while(!q.empty())q.pop();//清空对列;returntrue;}}elseif(tem.x==(*tail).get_prior().get_x()&&tem.y==(*tail).get_prior().get_y())//如果该结点为空格且找到变化后的蛇尾结点;{while(!q.empty())q.pop();//清空对列;f.game[(*tail).get_x()][(*tail).get_y()]='*';//把忽略的蛇尾结点补上;returntrue;}if(tem.x=0&&tem.y=0&&tem.x=map-1&&tem.y=map-1&&!vis[tem.x][tem.y]&&(f.game[tem.x][tem.y]==''||f.game[tem.x][tem.y]=='$'))//该结点可走且未走过;{q.push(tem);//该结点入队;vis[tem.x][tem.y]=
本文标题:贪吃蛇AI版(C++)
链接地址:https://www.777doc.com/doc-5853462 .html