180 lines
6.6 KiB
C++
180 lines
6.6 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 <BWAPI.h>
|
|
#include "utils.h"
|
|
#include "defs.h"
|
|
#include <vector>
|
|
|
|
namespace BWEM {
|
|
|
|
|
|
namespace BWAPI_ext {
|
|
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline std::ostream & operator<<(std::ostream & out, BWAPI::Point<T, Scale> A) { out << "(" << A.x << ", " << A.y << ")"; return out; }
|
|
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline BWAPI::Position center(BWAPI::Point<T, Scale> A) { return BWAPI::Position(A) + BWAPI::Position(Scale/2, Scale/2); }
|
|
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline BWAPI::Point<T, Scale> operator+(BWAPI::Point<T, Scale> A, int b) { return A + BWAPI::Point<T, Scale>(b, b); }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline BWAPI::Point<T, Scale> operator+(int a, BWAPI::Point<T, Scale> B) { return B + a; }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline BWAPI::Point<T, Scale> operator-(BWAPI::Point<T, Scale> A, int b) { return A + (-b); }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline BWAPI::Point<T, Scale> operator-(int a, BWAPI::Point<T, Scale> B) { return a + (B*-1); }
|
|
|
|
|
|
// Enlarges the bounding box [TopLeft, BottomRight] so that it includes A.
|
|
template<typename T, int Scale = 1>
|
|
inline void makeBoundingBoxIncludePoint(BWAPI::Point<T, Scale> & TopLeft, BWAPI::Point<T, Scale> & BottomRight, const BWAPI::Point<T, Scale> & 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<typename T, int Scale = 1>
|
|
inline void makePointFitToBoundingBox(BWAPI::Point<T, Scale> & A, const BWAPI::Point<T, Scale> & TopLeft, const BWAPI::Point<T, Scale> & 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<typename T, int Scale = 1>
|
|
bool inBoundingBox(const BWAPI::Point<T, Scale> & A, const BWAPI::Point<T, Scale> & topLeft, const BWAPI::Point<T, Scale> & bottomRight)
|
|
{
|
|
return (A.x >= topLeft.x) && (A.x <= bottomRight.x) &&
|
|
(A.y >= topLeft.y) && (A.y <= bottomRight.y);
|
|
}
|
|
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline int queenWiseDist(BWAPI::Point<T, Scale> A, BWAPI::Point<T, Scale> B){ A -= B; return utils::queenWiseNorm(A.x, A.y); }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline int squaredDist(BWAPI::Point<T, Scale> A, BWAPI::Point<T, Scale> B) { A -= B; return squaredNorm(A.x, A.y); }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline double dist(BWAPI::Point<T, Scale> A, BWAPI::Point<T, Scale> B) { A -= B; return utils::norm(A.x, A.y); }
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline int roundedDist(BWAPI::Point<T, Scale> A, BWAPI::Point<T, Scale> 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<typename T, int Scale = 1>
|
|
inline std::vector<BWAPI::Point<T, Scale>> innerBorder(BWAPI::Point<T, Scale> TopLeft, BWAPI::Point<T, Scale> Size, bool noCorner = false)
|
|
{
|
|
std::vector<BWAPI::Point<T, Scale>> 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<T, Scale>(dx, dy));
|
|
|
|
return Border;
|
|
}
|
|
|
|
template<typename T, int Scale = 1>
|
|
inline std::vector<BWAPI::Point<T, Scale>> outerBorder(BWAPI::Point<T, Scale> TopLeft, BWAPI::Point<T, Scale> Size, bool noCorner = false)
|
|
{
|
|
return innerBorder(TopLeft - 1, Size + 2, noCorner);
|
|
}
|
|
|
|
|
|
inline std::vector<BWAPI::WalkPosition> outerMiniTileBorder(BWAPI::TilePosition TopLeft, BWAPI::TilePosition Size, bool noCorner = false)
|
|
{
|
|
return outerBorder(BWAPI::WalkPosition(TopLeft), BWAPI::WalkPosition(Size), noCorner);
|
|
}
|
|
|
|
|
|
inline std::vector<BWAPI::WalkPosition> 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<typename T, int Scale = 1>
|
|
inline bool overlap(const BWAPI::Point<T, Scale> & TopLeft1, const BWAPI::Point<T, Scale> & Size1, const BWAPI::Point<T, Scale> & TopLeft2, const BWAPI::Point<T, Scale> & 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<typename T, int Scale = 1>
|
|
inline bool disjoint(const BWAPI::Point<T, Scale> & TopLeft1, const BWAPI::Point<T, Scale> & Size1, const BWAPI::Point<T, Scale> & TopLeft2, const BWAPI::Point<T, Scale> & 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
|
|
|