13 #include <unordered_map>
28 fourConnected =
false;
62 bool up=
false, down=
false;
76 if (!fourConnected && (up && (map->CanStep(
loc.
x,
loc.
y,
loc.
x-1,
loc.
y-1))))
78 if (!fourConnected && (down && (map->CanStep(
loc.
x,
loc.
y,
loc.
x-1,
loc.
y+1))))
84 if (!fourConnected && (up && (map->CanStep(
loc.
x,
loc.
y,
loc.
x+1,
loc.
y-1))))
86 if (!fourConnected && (down && (map->CanStep(
loc.
x,
loc.
y,
loc.
x+1,
loc.
y+1))))
93 xyLoc &next,
double &currHCost, uint64_t &special,
97 return GetNext4Successor(currOpenNode, goal, next, currHCost, special, validMove);
98 return GetNext8Successor(currOpenNode, goal, next, currHCost, special, validMove);
103 xyLoc &next,
double &currHCost, uint64_t &special,
135 const double hIncrease[8][8] =
137 {1.0, 0.0, 0.0, 0.0},
138 {1.0, 0.0, 0.0, 0.0},
139 {1.0, 0.0, 0.0, 0.0},
140 {1.0, 0.0, 0.0, 0.0},
141 {0.0, 1.0, 0.0, 0.0},
142 {0.0, 1.0, 0.0, 0.0},
143 {0.0, 1.0, 0.0, 0.0},
144 {0.0, 1.0, 0.0, 0.0},
147 if (currOpenNode.
x == goal.
x && currOpenNode.
y > goal.
y)
149 else if (currOpenNode.
x == goal.
x && currOpenNode.
y < goal.
y)
151 else if (currOpenNode.
x > goal.
x && currOpenNode.
y == goal.
y)
153 else if (currOpenNode.
x < goal.
x && currOpenNode.
y == goal.
y)
155 else if (currOpenNode.
x > goal.
x && currOpenNode.
y > goal.
y)
157 else if (currOpenNode.
x > goal.
x && currOpenNode.
y < goal.
y)
159 else if (currOpenNode.
x < goal.
x && currOpenNode.
y > goal.
y)
161 else if (currOpenNode.
x < goal.
x && currOpenNode.
y < goal.
y)
169 currHCost += hIncrease[theEntry][special];
170 ApplyAction(next, order[theEntry][special]);
172 if (map->CanStep(currOpenNode.
x, currOpenNode.
y, next.
x, next.
y))
180 currHCost += hIncrease[theEntry][special];
181 ApplyAction(next, order[theEntry][special]);
183 if (map->CanStep(currOpenNode.
x, currOpenNode.
y, next.
x, next.
y))
192 currHCost += hIncrease[theEntry][special];
193 ApplyAction(next, order[theEntry][special]);
195 if (map->CanStep(currOpenNode.
x, currOpenNode.
y, next.
x, next.
y))
203 currHCost += hIncrease[theEntry][special];
204 ApplyAction(next, order[theEntry][special]);
206 if (map->CanStep(currOpenNode.
x, currOpenNode.
y, next.
x, next.
y))
220 xyLoc &next,
double &currHCost, uint64_t &special,
357 bool up=
false, down=
false;
361 actions.push_back(
kS);
366 actions.push_back(
kN);
373 actions.push_back(
kNW);
375 actions.push_back(
kSW);
377 actions.push_back(
kW);
384 actions.push_back(
kNE);
386 actions.push_back(
kSE);
388 actions.push_back(
kE);
397 case -1: result =
kE;
break;
399 case 1: result =
kW;
break;
407 case -1: result = result|
kS;
break;
409 case 1: result = result|
kN;
break;
419 case kN: a =
kS;
break;
421 case kE: a =
kW;
break;
423 case kS: a =
kN;
break;
425 case kW: a =
kE;
break;
437 case kN: s.
y-=1;
break;
438 case kS: s.
y+=1;
break;
439 case kE: s.
x+=1;
break;
440 case kW: s.
x-=1;
break;
441 case kNW: s.
y-=1; s.
x-=1;
break;
442 case kSW: s.
y+=1; s.
x-=1;
break;
443 case kNE: s.
y-=1; s.
x+=1;
break;
444 case kSE: s.
y+=1; s.
x+=1;
break;
460 h1 = abs(l1.
x-l2.
x)+abs(l1.
y-l2.
y);
463 double a = ((l1.
x>l2.
x)?(l1.
x-l2.
x):(l2.
x-l1.
x));
464 double b = ((l1.
y>l2.
y)?(l1.
y-l2.
y):(l2.
y-l1.
y));
466 h1 = (a>b)?(b*DIAGONAL_COST+a-b):(a*DIAGONAL_COST+b-a);
472 int n1 = map->GetNodeNum(l1.
x, l1.
y);
473 int n2 = map->GetNodeNum(l2.
x, l2.
y);
474 if ((n1 != -1) && (n2 != -1))
478 h2 = h->HCost(nn1, nn2);
487 double multiplier = 1.0;
494 case kN:
return 1.0*multiplier;
495 case kS:
return 1.0*multiplier;
496 case kE:
return 1.0*multiplier;
497 case kW:
return 1.0*multiplier;
498 case kNW:
return DIAGONAL_COST*multiplier;
499 case kSW:
return DIAGONAL_COST*multiplier;
500 case kNE:
return DIAGONAL_COST*multiplier;
501 case kSE:
return DIAGONAL_COST*multiplier;
509 double multiplier = 1.0;
510 if (map->GetTerrainType(l1.
x, l1.
y) ==
kSwamp)
514 if (l1 == l2)
return 0.0;
515 if (l1.
x == l2.
x)
return 1.0*multiplier;
516 if (l1.
y == l2.
y)
return 1.0*multiplier;
517 return DIAGONAL_COST*multiplier;
526 return ((
node.x == goal.
x) && (
node.y == goal.
y));
531 return map->GetMapWidth()*map->GetMapHeight();
537 return node.y*map->GetMapWidth()+
node.x;
543 s.
x = parent%map->GetMapWidth();
544 s.
y = parent/map->GetMapWidth();
549 return (uint32_t) act;
575 GLdouble xx, yy, zz, rad;
576 map->GetOpenGLCoord(l.
x, l.
y, xx, yy, zz, rad);
579 glColor4f(r, g, b, t);
586 GLdouble xx, yy, zz, rad;
587 GLdouble xx2, yy2, zz2;
591 map->GetOpenGLCoord(l1.
x, l1.
y, xx, yy, zz, rad);
592 map->GetOpenGLCoord(l2.
x, l2.
y, xx2, yy2, zz2, rad);
599 glColor4f(r, g, b, t);
616 GLdouble xx, yy, zz, rad;
617 map->GetOpenGLCoord(s.
x, s.
y, xx, yy, zz, rad);
619 glColor3f(0.5, 0.5, 0.5);
620 glBegin(GL_LINE_STRIP);
621 glVertex3f(xx, yy, zz-rad/2);
625 case kN: s.
y-=1;
break;
626 case kS: s.
y+=1;
break;
627 case kE: s.
x+=1;
break;
628 case kW: s.
x-=1;
break;
629 case kNW: s.
y-=1; s.
x-=1;
break;
630 case kSW: s.
y+=1; s.
x-=1;
break;
631 case kNE: s.
y-=1; s.
x+=1;
break;
632 case kSE: s.
y+=1; s.
x+=1;
break;
637 map->GetOpenGLCoord(s.
x, s.
y, xx, yy, zz, rad);
638 glVertex3f(xx, yy, zz-rad/2);
645 GLdouble xx1, yy1, zz1, rad;
646 GLdouble xx2, yy2, zz2;
647 map->GetOpenGLCoord(a.
x, a.
y, xx1, yy1, zz1, rad);
648 map->GetOpenGLCoord(b.
x, b.
y, xx2, yy2, zz2, rad);
650 double angle = atan2(yy1-yy2, xx1-xx2);
651 double xoff = sin(2*
PI-angle)*rad*0.1;
652 double yoff = cos(2*
PI-angle)*rad*0.1;
656 GLfloat rr, gg, bb, t;
658 glColor4f(rr, gg, bb, t);
662 glVertex3f(xx1, yy1, zz1-rad/2);
663 glVertex3f(xx2, yy2, zz2-rad/2);
690 GLdouble xx, yy, zz, rad;
691 map->GetOpenGLCoord(s.
x, s.
y, xx, yy, zz, rad);
694 glColor4f(r, g, b, t);
696 glTranslatef(xx-rad, yy+rad/2, zz-2*rad);
697 glScalef(scale*rad/(300.0), scale*rad/300.0, 1);
698 glRotatef(180, 0.0, 0.0, 1.0);
699 glRotatef(180, 0.0, 1.0, 0.0);
701 glDisable(GL_LIGHTING);
704 glEnable(GL_LIGHTING);
713 GLdouble xx, yy, zz, rad;
714 map->GetOpenGLCoord(s.
x, s.
y, xx, yy, zz, rad);
717 glColor4f(r, g, b, t);
719 glTranslatef(xx-rad, yy+rad/2, zz-rad);
720 glScalef(rad/(300.0), rad/300.0, 1);
721 glRotatef(180, 0.0, 0.0, 1.0);
722 glRotatef(180, 0.0, 1.0, 0.0);
724 glDisable(GL_LIGHTING);
727 glEnable(GL_LIGHTING);
736 s =
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width = \""+std::to_string(10*map->GetMapWidth())+
"\" height = \""+std::to_string(10*map->GetMapHeight())+
"\" ";
737 s +=
"viewBox=\""+std::to_string(-map->GetMapWidth())+
" "+std::to_string(-map->GetMapHeight())+
" ";
738 s += std::to_string(12*map->GetMapWidth())+
" "+std::to_string(12*map->GetMapHeight())+
"\" ";
739 s +=
"preserveAspectRatio = \"none\" ";
750 for (
int y = 0; y < map->GetMapHeight(); y++)
752 for (
int x = 0; x < map->GetMapWidth(); x++)
755 if (map->GetTerrainType(x, y) ==
kGround)
762 else if (map->GetTerrainType(x, y) ==
kTrees)
768 else if (map->GetTerrainType(x, y) ==
kWater)
774 else if (map->GetTerrainType(x, y) ==
kSwamp)
792 for (
int y = 0; y < map->GetMapHeight(); y++)
794 for (
int x = 0; x < map->GetMapWidth(); x++)
808 for (
int y = 0; y < map->GetMapHeight(); y++)
810 for (
int x = 0; x < map->GetMapWidth(); x++)
813 if (map->GetTerrainType(x, y) ==
kGround)
815 if (x == map->GetMapWidth()-1)
817 if (y == map->GetMapHeight()-1)
820 else if (map->GetTerrainType(x, y) ==
kTrees)
822 if (x == map->GetMapWidth()-1)
824 if (y == map->GetMapHeight()-1)
827 else if (map->GetTerrainType(x, y) ==
kWater)
829 if (x == map->GetMapWidth()-1)
831 if (y == map->GetMapHeight()-1)
834 else if (map->GetTerrainType(x, y) ==
kSwamp)
843 SetColor(0.0, 0.0, 0.0);
846 if (map->GetTerrainType(x, y) != map->GetTerrainType(x-1, y))
848 SetColor(0.0, 0.0, 0.0);
853 if (map->GetTerrainType(x, y) != map->GetTerrainType(x, y-1))
859 if (map->GetTerrainType(x, y) != map->GetTerrainType(x+1, y))
865 if (map->GetTerrainType(x, y) != map->GetTerrainType(x, y+1))
882 if (map->GetTerrainType(l.
x, l.
y) ==
kGround)
927 s +=
SVGDrawText(l.
x+0.5+1+xoff, l.
y+0.5+1+1+yoff, str, c, scale);
957 bool successx =
true;
958 bool successy =
true;
960 if (endy+1 >= map->GetMapHeight() || endx+1 >= map->GetMapWidth())
962 for (
int x = startx; x < endx+1; x++)
964 if (map->GetTerrainType(x, endy+1) != terrain)
970 for (
int y = starty; y < endy+1; y++)
972 if (map->GetTerrainType(endx+1, y) != terrain)
978 if (successx && successy)
980 if (map->GetTerrainType(endx+1, endy+1) != terrain)
987 if (!successx && !successy)
990 GLdouble x1, x2, y1, y2, tmp, rad;
991 map->GetOpenGLCoord(startx, starty, x1, y1, tmp, rad);
992 map->GetOpenGLCoord(endx, endy, x2, y2, tmp, rad);
994 for (
int y = starty; y <= endy; y++)
996 for (
int x = startx; x <= endx; x++)
998 drawn[y*map->GetMapWidth()+x] =
true;
1005 rgbColor groundColor = {0.9, 0.9, 0.9};
1006 rgbColor treeColor = {0.0, 0.5, 0.0};
1007 rgbColor waterColor = {0.0, 0.0, 1.0};
1008 rgbColor swampColor = {0.5, 0.7, 0.8};
1009 rgbColor grassColor = {0.5, 1.0, 0.6};
1012 for (
int y = 0; y < map->GetMapHeight(); y++)
1014 for (
int x = 0; x < map->GetMapWidth(); x++)
1016 if (map->GetTerrainType(x, y) != terrain)
1019 if (!drawn[y*map->GetMapWidth()+x])
1023 case kGround: c = groundColor;
break;
1024 case kTrees: c = treeColor;
break;
1025 case kWater: c = waterColor;
break;
1026 case kSwamp: c = swampColor;
break;
1027 case kGrass: c = grassColor;
break;
1028 default: c = otherColor;
break;
1032 GetMaxRect(terrain, x, y, x, y, drawn, r);
1045 rgbColor groundColor = {0.9, 0.9, 0.9};
1046 rgbColor treeColor = {0.0, 0.5, 0.0};
1047 rgbColor waterColor = {0.0, 0.0, 1.0};
1048 rgbColor swampColor = {0.5, 0.7, 0.8};
1049 rgbColor grassColor = {0.5, 1.0, 0.6};
1058 int g = 0, t = 0, w = 0, s = 0, o = 0;
1060 for (
int y = 0; y < map->GetMapHeight(); y++)
1062 for (
int x = 0; x < map->GetMapWidth(); x++)
1064 switch (map->GetTerrainType(x, y))
1070 default: o++;
break;
1075 GLdouble px, py,
px1,
py1, tmp, rad;
1076 map->GetOpenGLCoord(0, 0, px, py, tmp, rad);
1077 map->GetOpenGLCoord((
int)map->GetMapWidth()-1, (
int)map->GetMapHeight()-1,
px1,
py1, tmp, rad);
1083 if (g >= t && g >= w && g >= s && g >= o)
1088 else if (t >= w && t >= s && t >= o)
1093 else if (w >= s && w >= o)
1109 std::vector<bool> drawn(map->GetMapHeight()*map->GetMapWidth());
1111 DrawSingleTerrain(
kSwamp, disp, drawn);
1113 DrawSingleTerrain(
kGround, disp, drawn);
1115 DrawSingleTerrain(
kTrees, disp, drawn);
1117 DrawSingleTerrain(
kWater, disp, drawn);
1125 for (
int y = 0; y < map->GetMapHeight(); y++)
1127 for (
int x = 0; x < map->GetMapWidth(); x++)
1130 GLdouble px, py, t, rad;
1131 map->GetOpenGLCoord(x, y, px, py, t, rad);
1140 switch (map->GetTerrainType(x, y))
1142 case kGround: c = groundColor;
break;
1143 case kTrees: c = treeColor;
break;
1144 case kWater: c = waterColor;
break;
1145 case kSwamp: c = swampColor;
break;
1146 case kGrass: c = grassColor;
break;
1147 default: draw=
false;
break;
1188 std::vector<std::pair<point, point>> lines;
1189 for (
int y = 0; y < map->GetMapHeight(); y++)
1191 for (
int x = 0; x < map->GetMapWidth(); x++)
1193 GLdouble
px1,
py1, t1, rad1;
1194 map->GetOpenGLCoord(x, y,
px1,
py1, t1, rad1);
1195 float px=
static_cast<float>(
px1);
1196 float py=
static_cast<float>(
py1);
1197 float t=
static_cast<float>(t1);
1198 float rad=
static_cast<float>(rad1);
1201 if ((map->GetTerrainType(x, y) ==
kGround) ||
1202 (map->GetTerrainType(x, y) ==
kTrees) ||
1203 (map->GetTerrainType(x, y) ==
kWater))
1205 if (x == map->GetMapWidth()-1)
1207 point s = {px+rad, py-rad};
1208 point g = {px+rad, py+rad};
1210 lines.push_back({s, g});
1212 if (y == map->GetMapHeight()-1)
1214 point s = {px-rad, py+rad};
1215 point g = {px+rad, py+rad};
1217 lines.push_back({s, g});
1220 else if (map->GetTerrainType(x, y) ==
kSwamp)
1230 if (map->GetTerrainType(x, y) != map->GetTerrainType(x-1, y))
1232 point s = {px-rad, py-rad};
1233 point g = {px-rad, py+rad};
1235 lines.push_back({s, g});
1238 if (map->GetTerrainType(x, y) != map->GetTerrainType(x, y-1))
1240 point s = {px-rad, py-rad};
1241 point g = {px+rad, py-rad};
1243 lines.push_back({s, g});
1246 if (map->GetTerrainType(x, y) != map->GetTerrainType(x+1, y))
1248 point s = {px+rad, py-rad};
1249 point g = {px+rad, py+rad};
1251 lines.push_back({s, g});
1254 if (map->GetTerrainType(x, y) != map->GetTerrainType(x, y+1))
1256 point s = {px-rad, py+rad};
1257 point g = {px+rad, py+rad};
1259 lines.push_back({s, g});
1265 std::vector<point> points;
1266 while (lines.size() > 0)
1270 points.push_back(lines.back().first);
1271 points.push_back(lines.back().second);
1276 for (
int x = 0; x < lines.size(); x++)
1278 if (lines[x].first == points.back())
1280 points.push_back(lines[x].second);
1281 lines.erase(lines.begin()+x);
1285 if (lines[x].second == points.back())
1287 points.push_back(lines[x].first);
1288 lines.erase(lines.begin()+x);
1301 GLdouble px, py, t, rad;
1302 map->GetOpenGLCoord(l.
x, l.
y, px, py, t, rad);
1331 map->GetOpenGLCoord(l1.
x, l1.
y, px, py, t, rad);
1342 map->GetOpenGLCoord(l2.
x, l2.
y, px, py, t, rad);
1363 GLdouble px, py, t, rad;
1364 map->GetOpenGLCoord(l.
x, l.
y, px, py, t, rad);
1365 if (l.
x < 0 || l.
x >= map->GetMapWidth() || l.
y < 0 || l.
y >= map->GetMapHeight())
1380 disp.
FrameCircle({
static_cast<float>(px),
static_cast<float>(py)}, rad, c, rad);
1387 GLdouble px, py, t, rad;
1388 map->GetOpenGLCoord(l.
x, l.
y, px, py, t, rad);
1394 GLdouble px, py, t, rad;
1395 map->GetOpenGLCoord(l.
x, l.
y, px, py, t, rad);
1402 disp.
DrawText(txt, {
static_cast<float>(px),
static_cast<float>(py)}, c, rad);
1411 map->GetOpenGLCoord(l1.
x, l1.
y, px, py, t, rad);
1416 GLdouble px, py, t, rad;
1417 map->GetOpenGLCoord(l2.
x, l2.
y, px, py, t, rad);
1418 p.
x = (1-v)*p.
x + (v)*px;
1419 p.
y = (1-v)*p.
y + (v)*py;
1432 GLdouble xx1, yy1, zz1, rad;
1433 GLdouble xx2, yy2, zz2;
1434 map->GetOpenGLCoord(a.
x, a.
y, xx1, yy1, zz1, rad);
1435 map->GetOpenGLCoord(b.
x, b.
y, xx2, yy2, zz2, rad);
1441 disp.
DrawLine({
static_cast<float>(xx1),
static_cast<float>(yy1)},
1442 {
static_cast<float>(xx2),
static_cast<float>(yy2)},
width*rad*0.1, c);
1447 GLdouble xx1, yy1, zz1, rad;
1448 GLdouble xx2, yy2, zz2;
1449 map->GetOpenGLCoord(a.
x, a.
y, xx1, yy1, zz1, rad);
1450 map->GetOpenGLCoord(b.
x, b.
y, xx2, yy2, zz2, rad);
1456 disp.
DrawArrow({
static_cast<float>(xx1),
static_cast<float>(yy1)},
1457 {
static_cast<float>(xx2),
static_cast<float>(yy2)}, 0.1*rad*
width, c);
1496 case kN: news.
y-=1;
break;
1497 case kS: news.
y+=1;
break;
1498 case kE: news.
x+=1;
break;
1499 case kW: news.
x-=1;
break;
1500 case kNW: news.
y-=1; news.
x-=1;
break;
1501 case kSW: news.
y+=1; news.
x-=1;
break;
1502 case kNE: news.
y-=1; news.
x+=1;
break;
1503 case kSE: news.
y+=1; news.
x+=1;
break;
1547 bitvec.resize(mapWidth*mapHeight);
1580 assert( (s.
x<mapWidth) && (s.
y<mapHeight));
1582 bitvec[CalculateIndex(s.
x,s.
y)] = occupied;
1596 assert( s.
x<=mapWidth && s.
y<=mapHeight);
1598 return bitvec[CalculateIndex(s.
x,s.
y)];
1615 return (y * mapWidth) + x;
1631 SetStateOccupied(oldState,
false);
1632 SetStateOccupied(newState,
true);
1637 if (!(GetStateOccupied(l2)))