File: MoveInfo.h

package info (click to toggle)
pentobi 29.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,892 kB
  • sloc: cpp: 25,719; javascript: 875; xml: 40; makefile: 13; sh: 6
file content (131 lines) | stat: -rw-r--r-- 4,324 bytes parent folder | download | duplicates (4)
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