#include #include #include #include"eyebot++.h" #include"maze_func.h" #include"maze_parameter.h" using namespace std; /*---检查单元格各方向是否已被到访---*/ bool check_mark() { bool check = false; int x, y; x = rob_x; //机器人当前x坐标 y = rob_y; //机器人当前y坐标 int size_x = mark.size(); int size_y = mark[0].size(); bool N_mark; bool W_mark; bool S_mark; bool E_mark; if (x>0 && y>0) //情况1 { if (y == size_y - 1) //N { N_mark = true; } else { N_mark = mark[x][y+1]; } W_mark = mark[x-1][y]; //W S_mark = mark[x][y-1]; //S if (x == size_x -1) //E { E_mark = true; } else { E_mark = mark[x+1][y]; } } else if (x==0 && y>0) //情况2 { if (y == size_y - 1) //N { N_mark = true; } else { N_mark = mark[x][y+1]; } W_mark = true; //W S_mark = mark[x][y-1]; //S if (x == size_x - 1) //E { E_mark = true; } else { E_mark = mark[x+1][y]; } } else if (x>0 && y==0) //情况3 { if (y == size_y - 1) //N { N_mark = true; } else { N_mark = mark[x][y+1]; } W_mark = mark[x-1][y]; //W S_mark = true; //S if (x == size_x -1) //E { E_mark = true; } else { E_mark = mark[x+1][y]; } } else //(x==0 && y==0) { if (y == size_y - 1) //N { N_mark = true; } else { N_mark = mark[x][y+1]; } W_mark = true; //W S_mark = true; //S if (x == size_x -1) //E { E_mark = true; } else { E_mark = mark[x+1][y]; } } bool N_road = (! wall[x][y+1][0] && N_mark); bool W_road = (! wall[x][y][1] && W_mark); bool S_road = (! wall[x][y][0] && S_mark); bool E_road = (! wall[x+1][y][1] && E_mark); if (N_road && W_road && S_road && E_road) { check = true; } return check; } /*---maze_entry函数,用于写入到wall数组中,1:有墙 0:通路---*/ void maze_entry(int x, int y, int dir, int open) { int maze_dir = (dir + 4) % 4; switch (maze_dir) { case 0: //0表示北(上),表示(x,y+1)坐标单元格的下方墙壁信息 if (y == mark[0].size() - 1 && open) //检测是否超出容器范围,如果超出,则扩大容器:对每一个内层尾插数据 { for (i = 0; i < mark.size() - 1; i++) { mark[i].emplace_back(0); } for (i = 0; i < wall.size() - 1; i++) { wall[i].emplace_back(vector(2,0)); } } wall[x][y+1][0] = ! open; break; case 1: //1表示西(左),表示(x,y)坐标单元格的左侧墙壁信息 if (x == 0 && open) //检测是否超出容器范围,如果超出,则扩大容器:头插一个内层 { mark.emplace(mark.begin(), mark[0].size(), 0); wall.emplace(wall.begin(), wall[0].size(), vector(2,0)); } wall[x][y][1] = ! open; break; case 2: //2表示南(下),表示(x,y)坐标单元格的下侧墙壁信息 if (y == 0 && open) //检测是否超出容器范围,如果超出,则扩大容器:对每一个内层头插数据 { for (i = 0; i < mark.size() - 1; i++) { mark[i].emplace(mark[i].begin(), 0); } for (i = 0; i < wall.size() - 1; i++) { wall[i].emplace(wall[i].begin(), vector(2,0)); } } wall[x][y][0] = ! open; break; case 3: //3表示东(右),表示(x+1,y)坐标单元格的左侧墙壁信息 if (x == mark.size() - 1 && open) //检测是否超出容器范围,如果超出,则扩大容器:尾插一个内层 { mark.emplace_back(mark[0].size(), 0); wall.emplace_back(wall[0].size(), vector(2,0)); } wall[x+1][y][1] = ! open; break; } } /*---检查该方向是否已被标记---*/ bool unmarked(int x, int y, int dir) { bool check = false; int maze_dir = (dir + 4) % 4; switch(maze_dir) { case 0: if (y < mark[0].size() - 2) { if (mark[x][y+1] == 0) { check = true; } } break; case 1: if (x > 1) { if (mark[x-1][y] == 0) { check = true; } } break; case 2: if (y > 1) { if (mark[x][y-1] == 0) { check = true; } } break; case 3: if (x < mark.size() - 2) { if (mark[x+1][y] == 0) { check = true; } } break; } return check; } /*---递归函数---*/ void explore() { int F_open,L_open,R_open,old_dir; bool check; mark[rob_x][rob_y] = 1; //将当前的单元格设置为已到访 F_open = PSDGetRaw(1) > DIST_cell; //获取前侧空间状况 L_open = PSDGetRaw(2) > DIST_cell; //获取左侧空间状况 R_open = PSDGetRaw(3) > DIST_cell; //获取右侧空间状况 maze_entry(rob_x, rob_y, rob_dir, F_open); //写入前方墙壁信息 maze_entry(rob_x, rob_y, rob_dir + 1, L_open); //写入左侧墙壁信息 maze_entry(rob_x, rob_y, rob_dir - 1, R_open); //写入右侧墙壁信息 check = check_mark(); //检查3个方向是否到访 if (check) { goto end_explore; } old_dir = rob_dir; if (F_open && unmarked(rob_x, rob_y, old_dir)) //如果前方有通路且前方单元格未被探索 { go_to(old_dir); //向前移动一格 explore(); //进行递归,在完成所有可到达单元格的访问前,一直循环在explore中 go_to(old_dir + 2); //返回到移动前的单元格 } if (L_open && unmarked(rob_x, rob_y, old_dir + 1)) //如果左侧有通路且前方单元格未被探索 { go_to(old_dir + 1); //向左移动一格 explore(); //进行递归,在完成所有可到达单元格的访问前,一直循环在explore中 go_to(old_dir - 1); //返回到移动前的单元格 } if (R_open && unmarked(rob_x, rob_y, old_dir - 1)) //如果右侧有通路且前方单元格未被探索 { go_to(old_dir - 1); //向右移动一格 explore(); //进行递归,在完成所有可到达单元格的访问前,一直循环在explore中 go_to(old_dir + 1); //返回到移动前的单元格 } end_explore: //check_mark函数确认三个方向都被探索的话,直接跳转到此处结束此次循环 VWWait(); } //递归结束