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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
DDS, a bridge double dummy solver.
Copyright (C) 2006-2014 by Bo Haglund /
2014-2018 by Bo Haglund & Soren Hein.
See LICENSE and README.
*/
/**
* @brief Representation of a suit bitmask as runs of adjacent ranks.
*
* A 13-bit vector encodes ranks 2..A (LSB = deuce, MSB = ace). This structure
* decomposes the vector into up to 7 contiguous runs of bits. It is used to
* generate move sequences and to reason about gaps between runs.
*
* Example: For bitmask 0x1D62 (binary 1 1101 0110 0010):
* - Group 0: rank 4 (top card), sequence 0x0002, gap 0x0000
* - Group 1: rank 6, sequence 0x0000, gap 0x0008
* - Group 2: rank 9, sequence 0x0040, gap 0x0020
* - Group 3: rank 14 (Ace), sequence 0x0C00, gap 0x0300
* - last_group = 3
*
* @note Maximum 7 groups due to 13-bit constraint (alternating runs)
*/
;
/**
* @brief Initialize all precomputed lookup tables for suit analysis.
*
* Precomputes and initializes all lookup tables used for move generation,
* rank calculations, and group decomposition. This includes:
* - highest_rank and lowest_rank tables
* - count_table for binary weight calculation
* - rel_rank for relative rank mapping
* - win_ranks for top-N card selection
* - group_data for run decomposition
*
* The tables are eagerly initialized at program startup via static initialization
* (DdsLutInitGuard). Explicit calls to this function are safe but redundant;
* they become no-ops after initial startup initialization.
*
* @note Thread-safe via std::call_once synchronization
* @note Initialization occurs automatically at program startup
* @note Explicit calls after startup are no-ops with minimal overhead
* @note Safe to call multiple times from any thread
*
* @see highest_rank, lowest_rank, count_table, rel_rank, win_ranks, group_data
*/
auto void;
/**
* @brief Read-only views of the precomputed lookup tables.
*
* These are exposed as const references to fixed-size arrays to provide
* zero-overhead indexing (e.g., highest_rank[i], rel_rank[i][j]). The
* underlying storage is initialized once via init_lookup_tables().
*
* All tables are indexed by an "aggregate" value - a 13-bit suit bitmask
* where bit 0 = deuce (2), bit 1 = 3, ..., bit 12 = Ace (14).
* Valid aggregate range: 0..8191 (0x0000 to 0x1FFF).
*/
/**
* @brief Highest absolute rank in the suit represented by an aggregate value.
*
* For a given aggregate (suit bitmask), returns the absolute rank (2..14)
* of the highest card, or 0 if the aggregate is empty.
*
* @note Indexed by aggregate value (0..8191)
* @note Return value: 0 (empty) or 2..14 (deuce..Ace)
* @see lowest_rank, count_table
*/
extern const int ;
/**
* @brief Lowest absolute rank in the suit represented by an aggregate value.
*
* For a given aggregate (suit bitmask), returns the absolute rank (2..14)
* of the lowest card, or 0 if the aggregate is empty.
*
* @note Indexed by aggregate value (0..8191)
* @note Return value: 0 (empty) or 2..14 (deuce..Ace)
* @see highest_rank, count_table
*/
extern const int ;
/**
* @brief Count of set bits (card count) in an aggregate value.
*
* Returns the number of cards represented by the aggregate bitmask.
* Also known as the binary weight or population count.
*
* @note Indexed by aggregate value (0..8191)
* @note Return value: 0..13 (number of cards in suit)
* @see highest_rank, lowest_rank
*/
extern const int ;
/**
* @brief Relative rank lookup table for cards in an aggregate.
*
* For a given aggregate and absolute rank, returns the relative rank
* (ordinal position from top) of that card within the suit.
* Example: In AKT, Ace has relative rank 1, King has 2, Ten has 3.
*
* @note First index: aggregate value (0..8191)
* @note Second index: absolute rank (2..14)
* @note Return value: 0 (not present) or 1..13 (relative rank from top)
* @see highest_rank, count_table
*/
extern const char ;
/**
* @brief Winners mask representing top N cards of an aggregate.
*
* For a given aggregate and count N, returns a bitmask containing only
* the top N cards from the original aggregate.
* Example: For AKQJT with N=3, returns AKQ (masking out JT).
*
* @note First index: aggregate value (0..8191)
* @note Second index: N = number of top cards to keep (0..13)
* @note Return value: bitmask with top N cards only
* @see highest_rank, count_table
*/
extern const unsigned short ;
/**
* @brief Run decomposition data for each aggregate value.
*
* For a given aggregate (suit bitmask), provides a decomposition into
* runs of consecutive ranks, including gap information between runs.
* This is essential for move generation and suit analysis.
*
* @note Indexed by aggregate value (0..8191)
* @note Contains up to 7 groups (runs) per aggregate
* @see MoveGroupType for structure details
*/
extern const ;