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
|
//-----------------------------------------------------------------------------
/** @file libpentobi_base/MoveInfo.h
@author Markus Enzenberger
@copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------
#ifndef LIBPENTOBI_BASE_MOVE_INFO_H
#define LIBPENTOBI_BASE_MOVE_INFO_H
#include "Move.h"
#include "MovePoints.h"
#include "Piece.h"
#include "PieceInfo.h"
namespace libpentobi_base {
//-----------------------------------------------------------------------------
/** Most frequently accessed move info.
Contains the points and the piece of the move. If the point list is smaller
than MAX_SIZE, values above end() up to MAX_SIZE may be accessed and
contain Point::null() to allow loop unrolling. The points correspond to
PieceInfo::get_points(), which includes certain junction points in Nexos,
see comment there.
Since this is the most performance-critical data structure, it takes
a template argument to make the space for move points not larger than
needed in the current game variant. */
template<unsigned MAX_SIZE>
class MoveInfo
{
public:
MoveInfo() = default;
MoveInfo(Piece piece, const MovePoints& points)
{
m_piece = static_cast<uint_least8_t>(piece.to_int());
m_size = static_cast<uint_least8_t>(points.size());
for (MovePoints::IntType i = 0; i < MAX_SIZE; ++i)
m_points[i] = points.get_unchecked(i);
}
const Point* begin() const { return m_points; }
const Point* end() const { return m_points + m_size; }
Piece get_piece() const { return Piece(m_piece); }
private:
uint_least8_t m_piece;
uint_least8_t m_size;
Point m_points[MAX_SIZE];
};
//-----------------------------------------------------------------------------
/** Less frequently accessed move info.
Stored separately from move points and move piece to improve CPU cache
performance.
Since this is a performance-critical data structure, it takes
a template argument to make the space for move points not larger than
needed in the current game variant.
@tparam MAX_ADJ_ATTACH Maximum total number of attach points and adjacent
points of a piece in the corresponding game variant. */
template<unsigned MAX_ADJ_ATTACH>
struct MoveInfoExt
{
/** Concatenated list of adjacent and attach points. */
Point points[MAX_ADJ_ATTACH];
uint_least8_t size_attach_points;
uint_least8_t size_adj_points;
const Point* begin_adj() const { return points; }
const Point* end_adj() const { return points + size_adj_points; }
const Point* begin_attach() const { return end_adj(); }
const Point* end_attach() const
{
return begin_attach() + size_attach_points;
}
};
//-----------------------------------------------------------------------------
/** Least frequently accessed move info.
Stored separately from move points and move piece to improve CPU cache
performance. */
struct MoveInfoExt2
{
/** Whether the move breaks rotational symmetry of the board.
Currently not initialized for classic and trigon_3 board types because
enforced rotational-symmetric draws are not used in the MCTS search on
these boards (trigon_3 has no 2-player game variant and classic_2
currently only supports colored starting points, which makes rotational
draws impossible. */
bool breaks_symmetry;
uint_least8_t scored_points_size;
/** The rotational-symmetric counterpart to this move.
Only initialized for game variants that have rotational-symmetric
boards and starting points. */
Move symmetric_move;
Point label_pos;
/** The points of a move that contribute to the score, which excludes
junction points in Nexos. */
Point scored_points[PieceInfo::max_scored_size];
const Point* begin_scored_points() const { return scored_points; }
const Point* end_scored_points() const
{
return scored_points + scored_points_size;
}
};
//-----------------------------------------------------------------------------
} // namespace libpentobi_base
//-----------------------------------------------------------------------------
#endif // LIBPENTOBI_BASE_MOVE_INFO_H
|