////////////////////////////////////////////////////////////////////////// // // This file is part of the BWEM Library. // BWEM is free software, licensed under the MIT/X11 License. // A copy of the license is provided with the library in the LICENSE file. // Copyright (c) 2015, 2017, Igor Dimitrijevic // ////////////////////////////////////////////////////////////////////////// #ifndef BWEM_BWAPI_EXT_H #define BWEM_BWAPI_EXT_H #include #include "utils.h" #include "defs.h" #include namespace BWEM { namespace BWAPI_ext { template inline std::ostream & operator<<(std::ostream & out, BWAPI::Point A) { out << "(" << A.x << ", " << A.y << ")"; return out; } template inline BWAPI::Position center(BWAPI::Point A) { return BWAPI::Position(A) + BWAPI::Position(Scale/2, Scale/2); } template inline BWAPI::Point operator+(BWAPI::Point A, int b) { return A + BWAPI::Point(b, b); } template inline BWAPI::Point operator+(int a, BWAPI::Point B) { return B + a; } template inline BWAPI::Point operator-(BWAPI::Point A, int b) { return A + (-b); } template inline BWAPI::Point operator-(int a, BWAPI::Point B) { return a + (B*-1); } // Enlarges the bounding box [TopLeft, BottomRight] so that it includes A. template inline void makeBoundingBoxIncludePoint(BWAPI::Point & TopLeft, BWAPI::Point & BottomRight, const BWAPI::Point & A) { if (A.x < TopLeft.x) TopLeft.x = A.x; if (A.x > BottomRight.x) BottomRight.x = A.x; if (A.y < TopLeft.y) TopLeft.y = A.y; if (A.y > BottomRight.y) BottomRight.y = A.y; } // Makes the smallest change to A so that it is included in the bounding box [TopLeft, BottomRight]. template inline void makePointFitToBoundingBox(BWAPI::Point & A, const BWAPI::Point & TopLeft, const BWAPI::Point & BottomRight) { if (A.x < TopLeft.x) A.x = TopLeft.x; else if (A.x > BottomRight.x) A.x = BottomRight.x; if (A.y < TopLeft.y) A.y = TopLeft.y; else if (A.y > BottomRight.y) A.y = BottomRight.y; } template bool inBoundingBox(const BWAPI::Point & A, const BWAPI::Point & topLeft, const BWAPI::Point & bottomRight) { return (A.x >= topLeft.x) && (A.x <= bottomRight.x) && (A.y >= topLeft.y) && (A.y <= bottomRight.y); } template inline int queenWiseDist(BWAPI::Point A, BWAPI::Point B){ A -= B; return utils::queenWiseNorm(A.x, A.y); } template inline int squaredDist(BWAPI::Point A, BWAPI::Point B) { A -= B; return squaredNorm(A.x, A.y); } template inline double dist(BWAPI::Point A, BWAPI::Point B) { A -= B; return utils::norm(A.x, A.y); } template inline int roundedDist(BWAPI::Point A, BWAPI::Point B) { return int(0.5 + dist(A, B)); } inline int distToRectangle(const BWAPI::Position & a, const BWAPI::TilePosition & TopLeft, const BWAPI::TilePosition & Size) { auto topLeft = BWAPI::Position(TopLeft); auto bottomRight = BWAPI::Position(TopLeft + Size) - 1; if (a.x >= topLeft.x) if (a.x <= bottomRight.x) if (a.y > bottomRight.y) return a.y - bottomRight.y; // S else if (a.y < topLeft.y) return topLeft.y - a.y; // N else return 0; // inside else if (a.y > bottomRight.y) return roundedDist(a, bottomRight); // SE else if (a.y < topLeft.y) return roundedDist(a, BWAPI::Position(bottomRight.x, topLeft.y)); // NE else return a.x - bottomRight.x; // E else if (a.y > bottomRight.y) return roundedDist(a, BWAPI::Position(topLeft.x, bottomRight.y)); // SW else if (a.y < topLeft.y) return roundedDist(a, topLeft); // NW else return topLeft.x - a.x; // W } template inline std::vector> innerBorder(BWAPI::Point TopLeft, BWAPI::Point Size, bool noCorner = false) { std::vector> Border; for (int dy = 0 ; dy < Size.y ; ++dy) for (int dx = 0 ; dx < Size.x ; ++dx) if ((dy == 0) || (dy == Size.y-1) || (dx == 0) || (dx == Size.x-1)) if (!noCorner || !(((dx == 0) && (dy == 0)) || ((dx == Size.x-1) && (dy == Size.y-1)) || ((dx == 0) && (dy == Size.y-1)) || ((dx == Size.x-1) && (dy == 0)))) Border.push_back(TopLeft + BWAPI::Point(dx, dy)); return Border; } template inline std::vector> outerBorder(BWAPI::Point TopLeft, BWAPI::Point Size, bool noCorner = false) { return innerBorder(TopLeft - 1, Size + 2, noCorner); } inline std::vector outerMiniTileBorder(BWAPI::TilePosition TopLeft, BWAPI::TilePosition Size, bool noCorner = false) { return outerBorder(BWAPI::WalkPosition(TopLeft), BWAPI::WalkPosition(Size), noCorner); } inline std::vector innerMiniTileBorder(BWAPI::TilePosition TopLeft, BWAPI::TilePosition Size, bool noCorner = false) { return innerBorder(BWAPI::WalkPosition(TopLeft), BWAPI::WalkPosition(Size), noCorner); } void drawDiagonalCrossMap(BWAPI::Position topLeft, BWAPI::Position bottomRight, BWAPI::Color col); template inline bool overlap(const BWAPI::Point & TopLeft1, const BWAPI::Point & Size1, const BWAPI::Point & TopLeft2, const BWAPI::Point & Size2) { if (TopLeft2.x >= TopLeft1.x + Size1.x) return false; if (TopLeft2.y >= TopLeft1.y + Size1.y) return false; if (TopLeft1.x >= TopLeft2.x + Size2.x) return false; if (TopLeft1.y >= TopLeft2.y + Size2.y) return false; return true; } template inline bool disjoint(const BWAPI::Point & TopLeft1, const BWAPI::Point & Size1, const BWAPI::Point & TopLeft2, const BWAPI::Point & Size2) { if (TopLeft2.x > TopLeft1.x + Size1.x) return true; if (TopLeft2.y > TopLeft1.y + Size1.y) return true; if (TopLeft1.x > TopLeft2.x + Size2.x) return true; if (TopLeft1.y > TopLeft2.y + Size2.y) return true; return false; } }} // namespace BWEM::BWAPI_ext #endif