1 //-----------------------------------------------------------------------------
2 /** @file libpentobi_base/Piece.h
3     @author Markus Enzenberger
4     @copyright GNU General Public License version 3 or later */
5 //-----------------------------------------------------------------------------
6 
7 #ifndef LIBPENTOBI_BASE_PIECE_H
8 #define LIBPENTOBI_BASE_PIECE_H
9 
10 #include <cstdint>
11 #include "libboardgame_base/Assert.h"
12 
13 namespace libpentobi_base {
14 
15 //-----------------------------------------------------------------------------
16 
17 /** Wrapper around an integer representing a piece type in a certain
18     game variant. */
19 class Piece
20 {
21 public:
22     using IntType = std::uint_fast8_t;
23 
24     /** Maximum number of unique pieces per color. */
25     static constexpr IntType max_pieces = 24;
26 
27     /** Integer range used for unique pieces without the null piece. */
28     static constexpr IntType range_not_null = max_pieces;
29 
30     /** Integer range used for unique pieces including the null piece */
31     static constexpr IntType range = max_pieces + 1;
32 
33 
null()34     static Piece null() { return Piece(value_null); }
35 
36 
37     Piece();
38 
39     explicit Piece(IntType i);
40 
41     bool operator==(Piece piece) const { return m_i == piece.m_i; }
42 
43     bool operator!=(Piece piece) const { return ! operator==(piece); }
44 
45     bool is_null() const;
46 
47     /** Return move as an integer between 0 and Piece::range */
48     IntType to_int() const;
49 
50 private:
51     static constexpr IntType value_null = range - 1;
52 
53     static constexpr IntType value_uninitialized = range;
54 
55     IntType m_i;
56 
57 
58 #ifdef LIBBOARDGAME_DEBUG
is_initialized()59     bool is_initialized() const { return m_i < value_uninitialized; }
60 #endif
61 };
62 
Piece()63 inline Piece::Piece()
64 {
65 #ifdef LIBBOARDGAME_DEBUG
66     m_i = value_uninitialized;
67 #endif
68 }
69 
Piece(IntType i)70 inline Piece::Piece(IntType i)
71 {
72     LIBBOARDGAME_ASSERT(i < range);
73     m_i = i;
74 }
75 
is_null()76 inline bool Piece::is_null() const
77 {
78     LIBBOARDGAME_ASSERT(is_initialized());
79     return m_i == value_null;
80 }
81 
82 inline auto Piece::to_int() const -> IntType
83 {
84     LIBBOARDGAME_ASSERT(is_initialized());
85     return m_i;
86 }
87 
88 //-----------------------------------------------------------------------------
89 
90 } // namespace libpentobi_base
91 
92 //-----------------------------------------------------------------------------
93 
94 #endif // LIBPENTOBI_BASE_PIECE_H
95