Repository navigation
Expand file tree
/
Copy pathdds_c_api.h
More file actions
170 lines (137 loc) · 8.29 KB
/
Copy pathdds_c_api.h
File metadata and controls
170 lines (137 loc) · 8.29 KB
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
/*
DDS, a bridge double dummy solver.
C-ABI shim over the modern SolverContext API (dds_api.hpp).
Every function here is C-callable and takes only pointers and plain-old-data
by value: the opaque handle is a void*, and non-POD C++ types (SolverConfig,
TTKind, C++ references) never appear. This gives Java (FFM/jextract), .NET,
and ctypes a single clean, stable ABI to bind against.
NOTE: the *exported symbols* are a pure C ABI, but this header is not itself
compilable by a C front-end: it pulls in <api/dds_c_data_types.h>, which in
turn includes <api/dds_constants.hpp>, where the shared constants are C++
`constexpr` (and other declarations use C++-only syntax). Consume the ABI by
binding to the compiled library's symbols (FFM/ctypes/.NET) or by parsing
the headers with a C++ mode (jextract); do not include this from a C
translation unit.
See LICENSE and README.
*/
#pragma once
#include <api/dds_c_data_types.h> /* struct Deal, FutureTricks, DdTableDeal, DdTableDealPBN, DdTableResults, ParResults; DLLEXPORT */
#ifdef __cplusplus
extern "C" {
#endif
/* Opaque solver-context handle. Owns per-context solver state and the
transposition table. Create with dds_c_create_solvercontext_default and
release with dds_c_destroy_solvercontext. Not thread-safe: use one handle
per thread. */
typedef void* DDS_C_SOLVER_CTX;
/* Creation / destruction. */
DLLEXPORT DDS_C_SOLVER_CTX dds_c_create_solvercontext_default(void);
DLLEXPORT void dds_c_destroy_solvercontext(DDS_C_SOLVER_CTX ctx);
/* Solve a single board. Returns a RETURN_* status code. */
DLLEXPORT int dds_c_solve_board(DDS_C_SOLVER_CTX ctx,
const struct Deal* dl,
int target, int solutions, int mode,
struct FutureTricks* futp);
/* Compute the double dummy table for a deal. */
DLLEXPORT int dds_c_calc_dd_table(DDS_C_SOLVER_CTX ctx,
const struct DdTableDeal* deal,
struct DdTableResults* results);
/* Compute the par result for a deal (computes the DD table internally). */
DLLEXPORT int dds_c_calc_par(DDS_C_SOLVER_CTX ctx,
const struct DdTableDeal* deal,
int vulnerable,
struct DdTableResults* results,
struct ParResults* par);
/* Creation with explicit transposition-table configuration. The C++ SolverConfig
is decomposed into scalars rather than mirrored as a struct: passing a struct
by value is exactly the ABI question this shim exists to avoid, and a mirror
type would be a second definition to keep in sync. tt_kind: 0 = Small,
1 = Large, 2 = Pattern (matching enum class TTKind). Returns NULL on
failure. */
DLLEXPORT DDS_C_SOLVER_CTX dds_c_create_solvercontext(int tt_kind,
int def_mb, int max_mb);
/* Compute the double dummy table from a PBN-format deal. */
DLLEXPORT int dds_c_calc_dd_table_pbn(DDS_C_SOLVER_CTX ctx,
const struct DdTableDealPBN* deal,
struct DdTableResults* results);
/* Parse a PBN deal string into the binary holdings block that both
struct Deal.remainCards and struct DdTableDeal.cards use: DDS_HANDS x
DDS_SUITS unsigned ints, row-major ([hand][suit]), so a caller can convert
straight into either struct field and then use the binary entry points. Only
the first hand carries a compass letter (N/E/S/W); the other three follow
clockwise. The terminator must occur within the first 80 bytes (a string of
79 content bytes plus terminator fits exactly); no more than 80 bytes are
read. Needs no SolverContext.
This is the general PBN entry point for bindings: a PBN-based caller converts
once with this function, then calls dds_c_solve_board or dds_c_calc_par
directly with the result -- which is why those two have no *_pbn twin on
this shim.
Returns RETURN_UNKNOWN_FAULT if either pointer is NULL -- checked before
pbn_deal is read at all, so on this path cards is untouched, not cleared --
RETURN_PBN_FAULT if a non-NULL string cannot be parsed, else RETURN_NO_FAULT.
Two limits matter once both pointers are non-NULL:
- RETURN_NO_FAULT means "parsed", not "describes a legal deal". A rank
character that is out of range or otherwise unrecognized is skipped
rather than refused, so a typo'd rank yields a short hand and still
converts -- except a compass letter (N/E/S/W, either case) found after
the first hand, which IS refused with RETURN_PBN_FAULT rather than
skipped. Deal validation lives in the entry points that consume the
block: they return RETURN_CARD_COUNT or RETURN_DUPLICATE_CARDS. Check
that status too -- a successful conversion is not a validated deal.
(Partial deals are legitimate, e.g. mid-trick, so this function cannot
count cards itself.)
- On RETURN_PBN_FAULT the output is NOT preserved: all DDS_HANDS x
DDS_SUITS entries are zeroed before parsing begins, so a rejected string
leaves the block zeroed or holding a partial parse. Convert into scratch
storage if the destination must survive a bad string. */
DLLEXPORT int dds_c_convert_from_pbn(const char* pbn_deal,
unsigned int cards[DDS_HANDS][DDS_SUITS]);
/* Transposition-table configuration. */
DLLEXPORT void dds_c_configure_tt(DDS_C_SOLVER_CTX ctx, int tt_kind,
int def_mb, int max_mb);
DLLEXPORT void dds_c_resize_tt(DDS_C_SOLVER_CTX ctx, int def_mb, int max_mb);
DLLEXPORT void dds_c_clear_tt(DDS_C_SOLVER_CTX ctx);
/* Per-solve state resets. */
DLLEXPORT void dds_c_reset_for_solve(DDS_C_SOLVER_CTX ctx);
DLLEXPORT void dds_c_reset_best_moves_lite(DDS_C_SOLVER_CTX ctx);
/* Logging passthrough. msg is a NUL-terminated UTF-8 string. */
DLLEXPORT void dds_c_log_append(DDS_C_SOLVER_CTX ctx, const char* msg);
DLLEXPORT void dds_c_log_clear(DDS_C_SOLVER_CTX ctx);
/* Context-free utilities. These operate on already-produced data (a
DdTableResults/ParResultsMaster) or static library info; they need no
SolverContext and so take no handle. */
/* Compute par from an already-computed double dummy table. */
DLLEXPORT int dds_c_par_from_table(const struct DdTableResults* table,
int vulnerable,
struct ParResults* par);
/* Compute par from both the NS and EW dealing sides' viewpoints. */
DLLEXPORT int dds_c_sides_par(const struct DdTableResults* table,
struct ParResultsDealer sides_res[2],
int vulnerable);
/* Compute par for a specific dealer. */
DLLEXPORT int dds_c_dealer_par(const struct DdTableResults* table,
struct ParResultsDealer* par,
int dealer, int vulnerable);
/* Binary (ContractType) variant of dds_c_dealer_par. */
DLLEXPORT int dds_c_dealer_par_bin(const struct DdTableResults* table,
struct ParResultsMaster* par,
int dealer, int vulnerable);
/* Binary (ContractType) variant of dds_c_sides_par. */
DLLEXPORT int dds_c_sides_par_bin(const struct DdTableResults* table,
struct ParResultsMaster sides_res[2],
int vulnerable);
/* Format a dds_c_dealer_par_bin() result as dealer-oriented text. */
DLLEXPORT int dds_c_convert_to_dealer_text_format(const struct ParResultsMaster* par,
char* resp);
/* Format a dds_c_sides_par_bin() result (both sides) as sides-oriented text.
par must point to a 2-element array, one entry per side, matching
dds_c_sides_par_bin's output -- not a single dds_c_dealer_par_bin() result. */
DLLEXPORT int dds_c_convert_to_sides_text_format(const struct ParResultsMaster par[2],
struct ParTextResults* resp);
/* Query library version/build information. */
DLLEXPORT void dds_c_get_dds_info(struct DDSInfo* info);
/* Map a RETURN_* status code to its human-readable text. */
DLLEXPORT void dds_c_error_message(int code, char line[80]);
#ifdef __cplusplus
}
#endif