1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
//-----------------------------------------------------------------------------
/** @file libboardgame_base/Point.h
@author Markus Enzenberger
@copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------
#ifndef LIBBOARDGAME_BASE_POINT_H
#define LIBBOARDGAME_BASE_POINT_H
#include <limits>
#include "Assert.h"
namespace libboardgame_base {
using namespace std;
//-----------------------------------------------------------------------------
/** Coordinate on the board.
Depending on the game, a point represents a field or intersection (in Go)
on the board. The class is a lightweight wrapper around an integer. All
information about points including the coordinates are contained in
Geometry. The convention for the coordinates is that the top left corner of
the board has the coordinates (0,0). Point::null() has the meaning
"no point".
@tparam M The maximum number of on-board points of all geometries this
point is used in (excluding the null point). This may be smaller than
W*H if the geometries are not rectangular.
@tparam W The maximum width of all geometries this point is used in.
@tparam H The maximum height of all geometries this point is used in.
@tparam I An unsigned integer type to store the point value. */
template<unsigned M, unsigned W, unsigned H, typename I>
class Point
{
public:
using IntType = I;
static constexpr unsigned range_onboard = M;
static constexpr unsigned max_width = W;
static constexpr unsigned max_height = W;
static_assert(numeric_limits<I>::is_integer);
static_assert(! numeric_limits<I>::is_signed);
static_assert(range_onboard <= max_width * max_height);
static constexpr unsigned range = range_onboard + 1;
static Point null() { return Point(value_null); }
Point();
explicit Point(unsigned i);
bool operator==(const Point& p) const;
bool operator!=(const Point& p) const;
bool operator<(const Point& p) const;
bool is_null() const;
/** Return point as an integer between 0 and Point::range */
IntType to_int() const;
private:
static constexpr IntType value_uninitialized = range;
static constexpr IntType value_null = range - 1;
IntType m_i;
#ifdef LIBBOARDGAME_DEBUG
bool is_initialized() const { return m_i < value_uninitialized; }
#endif
};
template<unsigned M, unsigned W, unsigned H, typename I>
inline Point<M, W, H, I>::Point()
{
#ifdef LIBBOARDGAME_DEBUG
m_i = value_uninitialized;
#endif
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline Point<M, W, H, I>::Point(unsigned i)
{
LIBBOARDGAME_ASSERT(i < range);
m_i = static_cast<I>(i);
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline bool Point<M, W, H, I>::operator==(const Point& p) const
{
LIBBOARDGAME_ASSERT(is_initialized());
LIBBOARDGAME_ASSERT(p.is_initialized());
return m_i == p.m_i;
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline bool Point<M, W, H, I>::operator!=(const Point& p) const
{
return ! operator==(p);
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline bool Point<M, W, H, I>::operator<(const Point& p) const
{
LIBBOARDGAME_ASSERT(is_initialized());
LIBBOARDGAME_ASSERT(p.is_initialized());
return m_i < p.m_i;
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline bool Point<M, W, H, I>::is_null() const
{
LIBBOARDGAME_ASSERT(is_initialized());
return m_i == value_null;
}
template<unsigned M, unsigned W, unsigned H, typename I>
inline auto Point<M, W, H, I>::to_int() const -> IntType
{
LIBBOARDGAME_ASSERT(is_initialized());
return m_i;
}
//-----------------------------------------------------------------------------
} // namespace libboardgame_base
#endif // LIBBOARDGAME_BASE_POINT_H
|