├── Snake ├── Snake.pro ├── main.cpp ├── variables.cpp ├── total.h ├── games.cpp ├── ai.cpp └── Snake.pro.user └── LICENSE /Snake/Snake.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | CONFIG += console c++11 3 | CONFIG -= app_bundle 4 | CONFIG -= qt 5 | 6 | SOURCES += main.cpp \ 7 | ai.cpp \ 8 | games.cpp \ 9 | variables.cpp 10 | 11 | HEADERS += \ 12 | total.h 13 | -------------------------------------------------------------------------------- /Snake/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "total.h" 3 | #include 4 | 5 | void test(){ 6 | system("python3 E:\\Documents\\QtProjects\\Sokoban\\ai.cpp"); 7 | Snake.push_back(Point(3,0)); 8 | Snake.push_back(Point(4,0)); 9 | for(int y=1;y<=4;y++) Snake.push_back(Point(4,y)); 10 | for(int x=3;x>=0;x--) Snake.push_back(Point(x,4)); 11 | for(int y=5;y<=7;y++) Snake.push_back(Point(0,y)); 12 | 13 | Point x=GetDirectPoint(); 14 | cout< Snake=vector(); 4 | Point Food(0,0); 5 | int Score=0; 6 | AI ai=AI(); 7 | 8 | ImaginaryMap::ImaginaryMap(vector input_snake){ 9 | int x,y; 10 | isnake=input_snake; 11 | for(y=0;y<=MAP_Y-1;y++){ 12 | for(x=0;x<=MAP_X-1;x++){ 13 | ditu[x][y]=0; 14 | } 15 | } 16 | for(int t=1;t<=isnake.size()-1;t++){ 17 | ditu[isnake.at(t).x][isnake.at(t).y]=2; 18 | } 19 | if(isnake.at(0).x>=0&&isnake.at(0).x<=MAP_X-1&&isnake.at(0).y>=0&&isnake.at(0).y<=MAP_Y-1) ditu[isnake.at(0).x][isnake.at(0).y]=1; 20 | ditu[Food.x][Food.y]=3; 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Snake/total.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOTAL_H_ 2 | #define _TOTAL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define MAP_X 12 13 | #define MAP_Y 12 14 | 15 | using namespace std; 16 | 17 | class Point 18 | { 19 | public: 20 | int x; 21 | int y; 22 | bool operator ==(Point p2){ 23 | if(x==p2.x&&y==p2.y){ 24 | return true; 25 | }else{ 26 | return false; 27 | } 28 | } 29 | int operator -(Point p2){ //定义两个点之间的曼哈顿距离 30 | return abs(p2.x-x)+abs(p2.y-y); 31 | } 32 | 33 | Point(int input_x,int input_y){ 34 | x=input_x; 35 | y=input_y; 36 | } 37 | Point(){ 38 | 39 | } 40 | }; 41 | 42 | //class PathPoint: public Point //和上面的Point的区别是这里包含了从起点到达这个点的路径 43 | //{ 44 | //public: 45 | // vector Path; 46 | // PathPoint(int input_x,int input_y):Point(input_x, input_y){ 47 | // Path=vector(); 48 | // } 49 | // PathPoint(){ 50 | // Path=vector(); 51 | // } 52 | //}; 53 | 54 | class ImaginaryMap //假想的地图 55 | { 56 | public: 57 | int ditu[MAP_X][MAP_Y]; 58 | vector isnake; 59 | ImaginaryMap(vector input_snake); 60 | }; 61 | 62 | class AI 63 | { 64 | public: 65 | vector PlanPath; 66 | Point direct_point; 67 | int wander_step; 68 | int play(); 69 | AI(){ 70 | wander_step=0; 71 | PlanPath=vector(); 72 | direct_point=Point(-1,-1); 73 | } 74 | }; 75 | 76 | void MapShow(int print_map[MAP_X][MAP_Y]); 77 | void PrintMap(); 78 | int game_move(int drction); 79 | int gameover(); 80 | void generate_food(); 81 | void game_init(); 82 | void game_play(); 83 | 84 | vector FindPath(Point start, Point end, int use_imap, vector body,int food_valid); 85 | Point GetDirectPoint(); 86 | int AiPlay(); 87 | 88 | extern vector Snake; 89 | extern Point Food; 90 | extern int Score; 91 | extern AI ai; 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /Snake/games.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * @brief print_map 显示 5 | */ 6 | void MapShow(int print_map[MAP_X][MAP_Y]){ 7 | int x,y; 8 | //system("clear"); //linux 9 | system("cls"); //windows 10 | for(x=0;x<=MAP_X+1;x++){ 11 | printf("█"); 12 | } 13 | printf("\n"); 14 | for(y=0;y<=MAP_Y-1;y++){ 15 | printf("█"); 16 | for(x=0;x<=MAP_X-1;x++){ 17 | switch(print_map[x][y]){ 18 | case 0: //空地 19 | printf(" "); 20 | break; 21 | case 1: //头部 22 | printf("●"); 23 | break; 24 | case 2: //身 25 | printf("※"); 26 | break; 27 | case 3: //食物 28 | printf("□"); 29 | break; 30 | } 31 | } 32 | printf("█\n"); 33 | } 34 | for(x=0;x<=MAP_X+1;x++){ 35 | printf("█"); 36 | } 37 | printf("\n"); 38 | } 39 | 40 | void PrintMap(){ 41 | int print_map[MAP_X][MAP_Y]; 42 | int x,y; 43 | for(y=0;y<=MAP_Y-1;y++){ 44 | for(x=0;x<=MAP_X-1;x++){ 45 | print_map[x][y]=0; 46 | } 47 | } 48 | for(int t=1;t<=Snake.size()-1;t++){ 49 | print_map[Snake[t].x][Snake[t].y]=2; 50 | } 51 | if(Snake.at(0).x>=0&&Snake.at(0).x<=MAP_X-1&&Snake.at(0).y>=0&&Snake.at(0).y<=MAP_Y-1) print_map[Snake.at(0).x][Snake.at(0).y]=1; 52 | print_map[Food.x][Food.y]=3; 53 | MapShow(print_map); 54 | } 55 | 56 | int game_move(int drction){ 57 | //方向:1左2上3右4下 58 | //首先根据前两个位置来确定不能移动的方向 59 | //返回值为1表示可以这么移动(如果移动之后撞墙,也认为是可以移动,这部分在gameover函数中判定) 60 | //返回值为0表示不能这么移动(掉头) 61 | int x_diff=Snake.at(1).x-Snake.at(0).x; 62 | int y_diff=Snake.at(1).y-Snake.at(0).y; 63 | int drction_deny; 64 | if(x_diff==1) drction_deny=2; 65 | else if(x_diff==-1) drction_deny=0; 66 | else if(y_diff==1) drction_deny=3; 67 | else if(y_diff==-1) drction_deny=1; 68 | //执行移动操作 69 | if(drction==drction_deny){ 70 | return 0; 71 | }else{ 72 | Point head_point=Point(); 73 | switch(drction){ 74 | case 0://左 75 | head_point.x=Snake.at(0).x-1; 76 | head_point.y=Snake.at(0).y; 77 | break; 78 | case 1://上 79 | head_point.x=Snake.at(0).x; 80 | head_point.y=Snake.at(0).y-1; 81 | break; 82 | case 2://右 83 | head_point.x=Snake.at(0).x+1; 84 | head_point.y=Snake.at(0).y; 85 | break; 86 | case 3://下 87 | head_point.x=Snake.at(0).x; 88 | head_point.y=Snake.at(0).y+1; 89 | break; 90 | } 91 | if(head_point==Food){ //撞上食物 92 | Snake.insert(Snake.begin(), head_point); 93 | Score += 1; 94 | generate_food(); //重新生成一个食物 95 | }else{ 96 | Snake.insert(Snake.begin(), head_point); 97 | Snake.pop_back(); 98 | } 99 | return 1; 100 | } 101 | } 102 | 103 | int gameover(){ 104 | //判断游戏是否结束 1为成功 0为未结束 -1为失败 105 | if(Snake.at(0).x<=-1||Snake.at(0).x>=MAP_X||Snake.at(0).y<=-1||Snake.at(0).y>=MAP_Y){ 106 | return -1; 107 | } 108 | for(int t=1;t<=Snake.size()-1;t++){ 109 | if(Snake.at(t)==Snake.at(0)){ 110 | return -1; 111 | } 112 | } 113 | if(Snake.size()==MAP_X*MAP_Y-1){ 114 | return 1; 115 | } 116 | return 0; 117 | } 118 | 119 | void generate_food(){ 120 | //生成食物 121 | set pset=set(); //先找出不能生成食物的地方 122 | for(int t=0;t<=Snake.size()-1;t++){ 123 | pset.insert(Snake.at(t).y*MAP_X+Snake.at(t).x); 124 | } 125 | vector plist=vector(); //再找出可以生成食物的地方 126 | for(int y=0;y<=MAP_Y-1;y++){ 127 | for(int x=0;x<=MAP_X-1;x++){ 128 | Point p(x,y); 129 | if(pset.find(p.y*MAP_X+p.x)==pset.end()){ 130 | plist.push_back(p); 131 | } 132 | } 133 | } 134 | int foodindex=rand()%plist.size(); //生成食物 135 | Food=plist[foodindex]; 136 | } 137 | 138 | void game_init(){ 139 | srand(time(NULL)); 140 | for(int x=4;x>=0;x--){ 141 | Point p(x,0); 142 | Snake.push_back(p); 143 | } 144 | // Snake.push_back(Point(1,1)); 145 | // Snake.push_back(Point(0,1)); 146 | // Snake.push_back(Point(0,2)); 147 | // for(int x=0;x<=2;x++) Snake.push_back(Point(x,3)); 148 | // for(int y=3;y>=1;y--) Snake.push_back(Point(3,y)); 149 | // for(int x=3;x>=1;x--) Snake.push_back(Point(x,0)); 150 | generate_food(); 151 | // PrintMap(); 152 | // system("pause"); 153 | } 154 | 155 | void game_play(){ 156 | game_init(); 157 | _sleep(25); 158 | while(1){ 159 | int drction=ai.play(); 160 | game_move(drction); 161 | PrintMap(); 162 | printf("Score: %d\n", Score); 163 | int game_status=gameover(); 164 | if(game_status==1){ 165 | cout<<"获胜!\n"; 166 | break; 167 | } 168 | if(game_status==-1){ 169 | cout<<"失败!\n"; 170 | break; 171 | } 172 | // if(!ai.PlanPath.empty()){ 173 | // for(int t=0;t<=ai.PlanPath.size()-1;t++){ 174 | // cout< 2 | 3 | vector findNextPointList(Point thispoint,Point lastpoint,ImaginaryMap imap,int food_valid){ 4 | vector availpointlist = vector(); 5 | Point pl[4]= {Point(thispoint.x-1,thispoint.y),Point(thispoint.x,thispoint.y-1),Point(thispoint.x+1,thispoint.y),Point(thispoint.x,thispoint.y+1)}; //左上右下四个点 6 | for(int t=0;t<=3;t++){ //从四个点中筛选出可以通行的点 7 | if(pl[t].x<=-1||pl[t].x>=MAP_X||pl[t].y<=-1||pl[t].y>=MAP_Y) continue; 8 | if(food_valid==1){ 9 | if(imap.ditu[pl[t].x][pl[t].y]!=0&&imap.ditu[pl[t].x][pl[t].y]!=3) continue; 10 | }else{ 11 | if(imap.ditu[pl[t].x][pl[t].y]!=0) continue; 12 | } 13 | if(pl[t]==lastpoint) continue; 14 | availpointlist.push_back(pl[t]); 15 | } 16 | return availpointlist; 17 | } 18 | 19 | int FindPoint(vector vp,Point p){ 20 | if(!vp.empty()){ 21 | for(int t=0;t<=vp.size()-1;t++){ 22 | if(vp.at(t)==p){ 23 | return t; 24 | } 25 | } 26 | } 27 | return -1; 28 | } 29 | 30 | /** 31 | * @brief FindPath 32 | * @param start 33 | * @param method 策略:0为寻找两点间最短路径 1为寻找两点间最长路径 34 | * @param end 35 | */ 36 | vector FindPath(Point start, Point end, int use_imap, vector body,int food_valid){ 37 | vector opentable=vector(); 38 | vector closetable=vector(); 39 | vector imap_list=vector(); //每一步对应的虚拟地图 40 | int fscore[MAP_X][MAP_Y]; 41 | int G[MAP_X][MAP_Y]; //从起点到这里走了多少步 42 | Point parent[MAP_X][MAP_Y]; //记录每个节点的父节点 (-1,-1)代表没有父节点 43 | int x,y; 44 | for(y=0;y<=MAP_Y-1;y++){ 45 | for(x=0;x<=MAP_X-1;x++){ 46 | fscore[x][y]=MAP_X*MAP_Y; 47 | parent[x][y]=Point(-1,-1); 48 | G[x][y]=0; 49 | } 50 | } 51 | opentable.push_back(start); //将开始节点插入到open表中 52 | imap_list.push_back(ImaginaryMap(body)); 53 | fscore[start.x][start.y]=start-end; 54 | while(!opentable.empty()){ 55 | Point selectpoint = opentable.at(0); 56 | vector isnake=imap_list.at(0).isnake; 57 | int fm=selectpoint-end; 58 | vector::iterator m_distance_location=opentable.begin(); 59 | vector::iterator m_distance_imap=imap_list.begin(); 60 | vector::iterator imap_it=imap_list.begin(); 61 | if(opentable.size()>=2){ 62 | for(vector::iterator t=opentable.begin()+1;t!=opentable.end();t++){ //从open表中选取f值最小的节点 63 | imap_it++; 64 | if(fscore[(*t).x][(*t).y] nextpointlist = findNextPointList(selectpoint,parent[selectpoint.x][selectpoint.y],ImaginaryMap(isnake),food_valid); 79 | imap_list.erase(m_distance_imap); 80 | if(!nextpointlist.empty()){ 81 | for(int t=0;t<=nextpointlist.size()-1;t++){ 82 | Point p=nextpointlist.at(t); 83 | if(FindPoint(closetable,p)!=-1) continue; 84 | int distance=p-end; 85 | int fpoint=G[selectpoint.x][selectpoint.y]+distance+1; 86 | int pindex=FindPoint(opentable,p); 87 | vector isnake_new=isnake; 88 | if(use_imap==1){ 89 | isnake_new.pop_back(); 90 | isnake_new.insert(isnake_new.begin(),p); 91 | } 92 | if(pindex!=-1){ 93 | if(fpoint result=vector(); 112 | if(opentable.empty()){ //列表为空 说明不可能到达终点 返回一个空列表 113 | return result; 114 | } 115 | Point cur=end; 116 | result.push_back(cur); 117 | while(parent[cur.x][cur.y].x!=-1){ 118 | cur=parent[cur.x][cur.y]; 119 | result.push_back(cur); 120 | } 121 | return result; 122 | } 123 | 124 | int inaccessable(ImaginaryMap imap, int x, int y){ 125 | if(x<0||x>=MAP_X){ 126 | return 1; 127 | } 128 | if(y<0||y>=MAP_Y){ 129 | return 1; 130 | } 131 | if(imap.ditu[x][y]==1||imap.ditu[x][y]==2){ 132 | return 1; 133 | } 134 | return 0; 135 | } 136 | 137 | int JudgeWaySafe(vector way, int way_to_food, int food_valid){ 138 | //way的第一项为目标 最后一项为当前头部 139 | vector body=Snake; 140 | if(way_to_food==1){ 141 | if(way.size()>=3){ 142 | for(int t=way.size()-2;t>=1;t--){ 143 | body.pop_back(); 144 | body.insert(body.begin(),way.at(t)); 145 | } 146 | } 147 | body.insert(body.begin(),way.at(0)); 148 | }else{ 149 | if(way.size()>=2){ 150 | for(int t=way.size()-2;t>=0;t--){ 151 | body.pop_back(); 152 | body.insert(body.begin(),way.at(t)); 153 | } 154 | }else{ 155 | return 0; 156 | } 157 | } 158 | ImaginaryMap imap=ImaginaryMap(body); 159 | if(Snake.size()>=0.9*MAP_X*MAP_Y){ 160 | // if(way_to_food==1){ 161 | // cout< new_path=FindPath(way.at(0),body.at(body.size()-1),1,body,food_valid); 170 | if(new_path.empty()){ 171 | return 0; 172 | }else{ 173 | return 1; 174 | } 175 | } 176 | 177 | Point ChaseTail(){ 178 | ImaginaryMap imap=ImaginaryMap(Snake); 179 | Point thispoint=Snake.at(0); 180 | Point lastpoint=Snake.at(1); 181 | vector nextpointlist=findNextPointList(thispoint, lastpoint, imap,1); 182 | if(!nextpointlist.empty()){ 183 | int distance=-1; 184 | int m_distance_index=-1; 185 | for(int t=0;t<=nextpointlist.size()-1;t++){ 186 | vector way={nextpointlist.at(t), Snake.at(0)}; 187 | float straight=0.5*(nextpointlist.at(t).x-Snake.at(0).x==Snake.at(0).x-Snake.at(1).x&&nextpointlist.at(t).y-Snake.at(0).y==Snake.at(0).y-Snake.at(1).y); 188 | if(JudgeWaySafe(way,0,1)){ //寻找到尾巴的安全路线 189 | if(nextpointlist.at(t)-Snake.at(Snake.size()-1)+straight>distance){ 190 | distance=nextpointlist.at(t)-Snake.at(Snake.size()-1); 191 | m_distance_index=t; 192 | } 193 | } 194 | } 195 | if(m_distance_index!=-1){ 196 | return nextpointlist.at(m_distance_index); 197 | }else{ 198 | return Point(-1,-1); 199 | } 200 | }else{ 201 | return Point(-1,-1); 202 | } 203 | } 204 | 205 | Point GetDirectPoint(){ 206 | int m_score=-1; 207 | vector close_point_list=vector(); 208 | vector next_point_list=vector(); 209 | Point this_point=Snake.at(0); 210 | Point m_score_point=Point(-1,-1); 211 | // ImaginaryMap map=ImaginaryMap(Snake); 212 | int score_map[MAP_X][MAP_Y]; 213 | int x,y; 214 | for(y=0;y<=MAP_Y-1;y++){ 215 | for(x=0;x<=MAP_X-1;x++) score_map[x][y]=0; 216 | } 217 | for(int t=0;t<=Snake.size()-1;t++){ 218 | score_map[Snake.at(t).x][Snake.at(t).y]=t+1; 219 | } 220 | do 221 | { 222 | Point pl[4]= {Point(this_point.x-1,this_point.y),Point(this_point.x,this_point.y-1),Point(this_point.x+1,this_point.y),Point(this_point.x,this_point.y+1)}; //左上右下四个点 223 | for(int t=0;t<=3;t++){ 224 | if(pl[t].x>=0&&pl[t].x<=MAP_X-1&&pl[t].y>=0&&pl[t].y<=MAP_Y-1){ 225 | if(score_map[pl[t].x][pl[t].y]==0){ 226 | if((FindPoint(close_point_list,pl[t])==-1)&&(FindPoint(next_point_list,pl[t])==-1)){ 227 | next_point_list.push_back(Point(pl[t].x,pl[t].y)); 228 | } 229 | }else{ 230 | if(score_map[pl[t].x][pl[t].y]>m_score&&score_map[this_point.x][this_point.y]==0){ 231 | m_score=score_map[pl[t].x][pl[t].y]; 232 | m_score_point=this_point; 233 | } 234 | } 235 | } 236 | } 237 | if(score_map[this_point.x][this_point.y]==0){ 238 | close_point_list.push_back(this_point); 239 | next_point_list.erase(next_point_list.begin()); 240 | } 241 | if(!next_point_list.empty()){ 242 | this_point=next_point_list.at(0); 243 | } 244 | }while(!next_point_list.empty()); 245 | return m_score_point; 246 | } 247 | 248 | Point Wander(Point direct_point){ 249 | ImaginaryMap imap=ImaginaryMap(Snake); 250 | Point thispoint=Snake.at(0); 251 | Point lastpoint=Snake.at(1); 252 | vector nextpointlist=findNextPointList(thispoint, lastpoint, imap, 1); 253 | if(!nextpointlist.empty()){ 254 | int distance=-1; 255 | int m_distance_index=-1; 256 | for(int t=0;t<=nextpointlist.size()-1;t++){ 257 | vector way={nextpointlist.at(t), Snake.at(0)}; 258 | if(JudgeWaySafe(way,0,1)){ //寻找到目标点的安全路线 259 | if(nextpointlist.at(t)-direct_point>distance){ 260 | distance=nextpointlist.at(t)-direct_point; 261 | m_distance_index=t; 262 | } 263 | } 264 | } 265 | if(m_distance_index!=-1){ 266 | return nextpointlist.at(m_distance_index); 267 | }else{ 268 | vector nextpointlist=findNextPointList(thispoint, lastpoint, imap, 1); 269 | if(!nextpointlist.empty()){ 270 | return nextpointlist.at(0); 271 | } 272 | return Point(-1,-1); 273 | } 274 | }else{ 275 | return Point(-1,-1); 276 | } 277 | } 278 | 279 | float AroundScore(int score_map[MAP_X][MAP_Y],int x, int y){ 280 | if(x<0||x>=MAP_X||y<0||y>=MAP_Y){ 281 | return Snake.size()*0.6; 282 | } 283 | return score_map[x][y]; 284 | } 285 | 286 | Point Around(){ 287 | ImaginaryMap imap=ImaginaryMap(Snake); 288 | Point thispoint=Snake.at(0); 289 | Point lastpoint=Snake.at(1); 290 | vector nextpointlist=findNextPointList(thispoint, lastpoint, imap,1); 291 | if(!nextpointlist.empty()){ 292 | float m_score=-1; 293 | int m_score_index=-1; 294 | for(int t=0;t<=nextpointlist.size()-1;t++){ 295 | vector isnake=Snake; 296 | isnake.pop_back(); 297 | isnake.insert(isnake.begin(),nextpointlist.at(t)); 298 | int score_map[MAP_X][MAP_Y]; 299 | int x,y; 300 | for(y=0;y<=MAP_Y-1;y++){ 301 | for(x=0;x<=MAP_X-1;x++) score_map[x][y]=0; 302 | } 303 | for(int t=0;t<=Snake.size()-1;t++){ 304 | score_map[isnake.at(t).x][isnake.at(t).y]=Snake.size()-t; 305 | } 306 | score_map[Food.x][Food.y]=Snake.size(); 307 | vector way={nextpointlist.at(t), Snake.at(0)}; 308 | if(JudgeWaySafe(way,0,1)){ //寻找到尾巴的安全路线 309 | float score=AroundScore(score_map,nextpointlist.at(t).x-1,nextpointlist.at(t).y)+AroundScore(score_map,nextpointlist.at(t).x,nextpointlist.at(t).y-1)+AroundScore(score_map,nextpointlist.at(t).x+1,nextpointlist.at(t).y)+AroundScore(score_map,nextpointlist.at(t).x,nextpointlist.at(t).y+1); 310 | float straight=10*(nextpointlist.at(t).x-Snake.at(0).x==Snake.at(0).x-Snake.at(1).x&&nextpointlist.at(t).y-Snake.at(0).y==Snake.at(0).y-Snake.at(1).y); 311 | // cout<m_score){ 314 | m_score=score+straight; 315 | m_score_index=t; 316 | } 317 | } 318 | } 319 | if(m_score_index!=-1){ 320 | return nextpointlist.at(m_score_index); 321 | }else{ 322 | return Point(-1,-1); 323 | } 324 | }else{ 325 | return Point(-1,-1); 326 | } 327 | } 328 | 329 | int AI::play(){ 330 | Point current_point=Snake.at(0); 331 | Point nextpoint=Point(-1,-1); 332 | // if(Snake.size()>=60){ 333 | // system("pause"); 334 | // } 335 | if(PlanPath.empty()){ 336 | if(Snake.size()<=0.7*MAP_X*MAP_Y||wander_step>=MAP_X*MAP_Y){ 337 | // if(wander_step>=MAP_X*MAP_Y){ 338 | // cout<<"G"< plan_path; 342 | if(Snake.size()>=0.8*MAP_X*MAP_Y) plan_path=FindPath(current_point,Food,0,Snake,1); 343 | else plan_path=FindPath(current_point,Food,1,Snake,1); 344 | if(!plan_path.empty()){ 345 | if(JudgeWaySafe(plan_path,1,1)){ 346 | PlanPath=plan_path; //找到通往食物的一条路 347 | } 348 | if(!PlanPath.empty()){ 349 | PlanPath.pop_back(); 350 | } 351 | } 352 | }else{ 353 | wander_step++; 354 | PlanPath=vector(); 355 | } 356 | } 357 | if(!PlanPath.empty()){ 358 | nextpoint=PlanPath.at(PlanPath.size()-1); 359 | PlanPath.pop_back(); 360 | }else{ 361 | if(Snake.size()>0.7*MAP_X*MAP_Y){ 362 | nextpoint=Around(); 363 | }else{ 364 | nextpoint=ChaseTail(); 365 | } 366 | if(nextpoint==Point(-1,-1)){ //也找不到尾巴 367 | // system("pause"); 368 | if(direct_point==Point(-1,-1)){ 369 | direct_point=GetDirectPoint(); 370 | } 371 | if(direct_point.x>=0){ 372 | nextpoint=Wander(direct_point); 373 | } 374 | }else{ 375 | direct_point=Point(-1,-1); 376 | } 377 | } 378 | if(Food==nextpoint){ 379 | wander_step=0; 380 | } 381 | if(nextpoint==Point(-1,-1)){ 382 | return rand()%4; 383 | }else{ 384 | if(nextpoint.x-current_point.x==-1&&nextpoint.y-current_point.y==0){ 385 | return 0; 386 | }else if(nextpoint.x-current_point.x==0&&nextpoint.y-current_point.y==-1){ 387 | return 1; 388 | }else if(nextpoint.x-current_point.x==1&&nextpoint.y-current_point.y==0){ 389 | return 2; 390 | }else if(nextpoint.x-current_point.x==0&&nextpoint.y-current_point.y==1){ 391 | return 3; 392 | }else{ 393 | return rand()%4; 394 | } 395 | } 396 | } 397 | -------------------------------------------------------------------------------- /Snake/Snake.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {2a0de064-b1cb-4211-a369-dc2363de6834} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.7.0 MSVC2015_64bit 63 | Desktop Qt 5.7.0 MSVC2015_64bit 64 | qt.57.win64_msvc2015_64_kit 65 | 1 66 | 0 67 | 0 68 | 69 | E:/Documents/QtProjects/BoringGames/Snake/build-Snake-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | 构建 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | 清理 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | E:/Documents/QtProjects/BoringGames/Snake/build-Snake-Desktop_Qt_5_7_0_MSVC2015_64bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | 132 | false 133 | false 134 | false 135 | 136 | 137 | true 138 | Make 139 | 140 | Qt4ProjectManager.MakeStep 141 | 142 | false 143 | 144 | 145 | 146 | 2 147 | 构建 148 | 149 | ProjectExplorer.BuildSteps.Build 150 | 151 | 152 | 153 | true 154 | Make 155 | 156 | Qt4ProjectManager.MakeStep 157 | 158 | true 159 | clean 160 | 161 | 162 | 1 163 | 清理 164 | 165 | ProjectExplorer.BuildSteps.Clean 166 | 167 | 2 168 | false 169 | 170 | Release 171 | 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | true 175 | 176 | 177 | E:/Documents/QtProjects/BoringGames/Snake/build-Snake-Desktop_Qt_5_7_0_MSVC2015_64bit-Profile 178 | 179 | 180 | true 181 | qmake 182 | 183 | QtProjectManager.QMakeBuildStep 184 | true 185 | 186 | false 187 | true 188 | false 189 | 190 | 191 | true 192 | Make 193 | 194 | Qt4ProjectManager.MakeStep 195 | 196 | false 197 | 198 | 199 | 200 | 2 201 | 构建 202 | 203 | ProjectExplorer.BuildSteps.Build 204 | 205 | 206 | 207 | true 208 | Make 209 | 210 | Qt4ProjectManager.MakeStep 211 | 212 | true 213 | clean 214 | 215 | 216 | 1 217 | 清理 218 | 219 | ProjectExplorer.BuildSteps.Clean 220 | 221 | 2 222 | false 223 | 224 | Profile 225 | 226 | Qt4ProjectManager.Qt4BuildConfiguration 227 | 0 228 | true 229 | 230 | 3 231 | 232 | 233 | 0 234 | 部署 235 | 236 | ProjectExplorer.BuildSteps.Deploy 237 | 238 | 1 239 | 在本地部署 240 | 241 | ProjectExplorer.DefaultDeployConfiguration 242 | 243 | 1 244 | 245 | 246 | false 247 | false 248 | 1000 249 | 250 | true 251 | 252 | false 253 | false 254 | false 255 | false 256 | true 257 | 0.01 258 | 10 259 | true 260 | 1 261 | 25 262 | 263 | 1 264 | true 265 | false 266 | true 267 | valgrind 268 | 269 | 0 270 | 1 271 | 2 272 | 3 273 | 4 274 | 5 275 | 6 276 | 7 277 | 8 278 | 9 279 | 10 280 | 11 281 | 12 282 | 13 283 | 14 284 | 285 | 2 286 | 287 | Snake 288 | Snake2 289 | Qt4ProjectManager.Qt4RunConfiguration:E:/Documents/BoringGames/Snake/Snake.pro 290 | true 291 | 292 | Snake.pro 293 | false 294 | 295 | E:/Documents/QtProjects/BoringGames/Snake/build-Snake-Desktop_Qt_5_7_0_MSVC2015_64bit-Release 296 | 3768 297 | false 298 | true 299 | false 300 | false 301 | true 302 | 303 | 1 304 | 305 | 306 | 307 | ProjectExplorer.Project.TargetCount 308 | 1 309 | 310 | 311 | ProjectExplorer.Project.Updater.FileVersion 312 | 18 313 | 314 | 315 | Version 316 | 18 317 | 318 | 319 | --------------------------------------------------------------------------------