Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/src/ab_search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#pragma once

#include <api/dds.h>
#include <api/dds_data_types.hpp>
#include <solver_context/solver_context.hpp>

auto ab_search(
Expand Down
14 changes: 14 additions & 0 deletions library/src/api/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,25 @@ exports_files(
visibility = ["//visibility:public"],
)

# Compile-time constants and macros shared with the whole solver. Kept as its
# own dependency-free target so //library/src/utility:constants can fold its
# bridge dimensions in here without a dependency cycle.
cc_library(
name = "dds_constants",
hdrs = ["dds_constants.hpp"],
include_prefix = "api",
visibility = ["//visibility:public"],
deps = [],
)

cc_library(
name = "api_definitions",
hdrs = [
"calc_dd_table.hpp",
"calc_par.hpp",
"dds.h",
"dds_c_data_types.h",
"dds_data_types.hpp",
"dll.h",
"dds_api.hpp",
"dds_c_api.h",
Expand All @@ -27,6 +40,7 @@ cc_library(
include_prefix = "api",
visibility = ["//visibility:public"],
deps = [
":dds_constants",
"//library/src/utility:constants",
],
)
Expand Down
2 changes: 1 addition & 1 deletion library/src/api/PBN.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#pragma once

#include <api/dll.h>
#include <api/dds_data_types.hpp>


/**
Expand Down
2 changes: 1 addition & 1 deletion library/src/api/calc_dd_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#pragma once

#include <api/dds.h>
#include <api/dds_data_types.hpp>
#include <solver_context/solver_context.hpp>

// Naming note: New C++ APIs in DDS 3 use snake_case (calc_dd_table).
Expand Down
2 changes: 1 addition & 1 deletion library/src/api/calc_par.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#pragma once

#include <api/dds.h>
#include <api/dds_data_types.hpp>
#include <solver_context/solver_context.hpp>

// Naming note: New C++ APIs in DDS 3 use snake_case (calc_par, calc_par_from_table).
Expand Down
202 changes: 6 additions & 196 deletions library/src/api/dds.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,199 +16,9 @@
#include <crtdbg.h>
#endif

// Project headers
#include <api/dll.h>


constexpr int THREADMEM_SMALL_MAX_MB = 30;
constexpr int THREADMEM_SMALL_DEF_MB = 20;
constexpr int THREADMEM_LARGE_MAX_MB = 160;
constexpr int THREADMEM_LARGE_DEF_MB = 95;

constexpr int MAXNODE = 1;
constexpr int MINNODE = 0;

constexpr int SIMILARDEALLIMIT = 5;
constexpr int SIMILARMAXWINNODES = 700000;


/* "hand" is leading hand, "relative" is hand relative leading
hand.
The handId macro implementation follows a solution
by Thomas Andrews.
All hand identities are given as
0=NORTH, 1=EAST, 2=SOUTH, 3=WEST. */

#include <utility/constants.h>

/**
* @brief Calculate relative hand position.
* @param hand Base hand position (0=NORTH, 1=EAST, 2=SOUTH, 3=WEST)
* @param relative Relative offset (0-3)
* @return Resulting hand position (0-3)
*/
#define HAND_ID(hand, relative) ((hand + relative) & 3)

/**
* @brief Represents a single card move in the game.
*
* Contains information about a card that can be played, including
* its suit, rank, sequence status, and sorting weight.
*/
struct MoveType
{
int suit; ///< Suit of the card (0-3: spades, hearts, diamonds, clubs)
int rank; ///< Rank of the card (2-14: 2 through Ace)
int sequence; ///< Whether this move is the first in a sequence
int weight; ///< Weight used for sorting during move generation
};

/**
* @brief Collection of moves available at a single ply.
*
* Stores all possible moves at a given point in the game,
* along with tracking of current and last move indices.
*/
struct MovePlyType
{
MoveType move[14]; ///< Array of possible moves (max 13 cards + sentinel)
int current; ///< Index of current move being considered
int last; ///< Index of last valid move in array
};

/**
* @brief Identifies a high card by rank and holding hand.
*
* Used to track high cards in each suit during analysis.
*/
struct HighCardType
{
int rank; ///< Rank of the high card (2-14)
int hand; ///< Hand holding the card (0-3: N, E, S, W)
};

/**
* @brief Complete position state during game analysis.
*
* Represents the full state of a bridge position including card distribution,
* trump information, and current play state. This is the core data structure
* used throughout the solver.
*/
struct Pos
{
unsigned short int rank_in_suit[DDS_HANDS][DDS_SUITS]; ///< Bitmask of ranks held by each hand in each suit
unsigned short int aggr[DDS_SUITS]; ///< Aggregate bitmask of all cards in each suit
unsigned char length[DDS_HANDS][DDS_SUITS]; ///< Number of cards each hand holds in each suit
int hand_dist[DDS_HANDS]; ///< Total number of cards held by each hand

unsigned short int win_ranks[50][DDS_SUITS]; ///< Cards that win by rank at each depth
int first[50]; ///< Hand that leads the trick for each ply
MoveType move[50]; ///< Presently winning move at each ply
int hand_rel_first; ///< Current hand, relative to first hand
int tricks_max; ///< Aggregated tricks won by maximizing side
HighCardType winner[DDS_SUITS]; ///< Winning rank of trick in each suit
HighCardType second_best[DDS_SUITS]; ///< Second best rank in each suit
};

/**
* @brief Trick-level data for current play state.
*
* Tracks information about the current trick being played,
* including play counts, best cards, and lead information.
*/
struct TrickDataType
{
int play_count[DDS_SUITS]; ///< Number of cards played in each suit
int best_rank; ///< Rank of best card played so far
int best_suit; ///< Suit of best card played so far
int best_sequence; ///< Sequence of best card
int rel_winner; ///< Relative position of current trick winner
int next_lead_hand; ///< Hand that will lead next trick
};

/**
* @brief Evaluation result for a position.
*
* Contains the number of tricks that can be won and which specific
* card ranks can win in each suit.
*/
struct EvalType
{
int tricks; ///< Number of tricks that can be won from this position
unsigned short int win_ranks[DDS_SUITS]; ///< Bitmask of winning ranks in each suit
};

/**
* @brief Simple card representation.
*
* Basic structure identifying a card by suit and rank.
*/
struct Card
{
int suit; ///< Suit of the card (0-3: spades, hearts, diamonds, clubs)
int rank; ///< Rank of the card (2-14: 2 through Ace)
};

/**
* @brief Extended card representation with sequence information.
*
* Like Card but includes sequence information for tracking
* equivalent cards during move generation.
*/
struct ExtCard
{
int suit; ///< Suit of the card (0-3: spades, hearts, diamonds, clubs)
int rank; ///< Rank of the card (2-14: 2 through Ace)
int sequence; ///< Sequence identifier for equivalent cards
};

/**
* @brief Absolute rank with holding hand.
*
* Compact representation (2 bytes) identifying a card rank
* and which hand holds it.
*/
struct AbsRankType // 2 bytes
{
char rank; ///< Rank of the card (2-14)
signed char hand; ///< Hand holding the card (0-3: N, E, S, W)
};

/**
* @brief Relative rank table for all suits.
*
* Contains absolute rank information for all possible card positions
* across all suits. Used for quick lookup during position analysis.
*/
struct RelRanksType // 120 bytes
{
AbsRankType abs_rank[15][DDS_SUITS]; ///< Rank information indexed by position and suit
};

/**
* @brief Parameters for batch board solving.
*
* Contains input/output structures for solving multiple boards
* in a single operation.
*/
struct ParamType
{
int no_of_boards; ///< Number of boards to solve
Boards const * bop; ///< Pointer to input boards
SolvedBoards * solvedp; ///< Pointer to output solutions
int error; ///< Error code from operation
};

/**
* @brief Execution mode for solver operations.
*
* Determines how the solver processes a position - solving for best play,
* calculating all possible outcomes, or tracing a specific line of play.
*/
enum class RunMode
{
DDS_RUN_SOLVE = 0, ///< Solve mode: find optimal play
DDS_RUN_CALC = 1, ///< Calculate mode: compute all outcomes
DDS_RUN_TRACE = 2, ///< Trace mode: analyze specific play sequence
DDS_RUN_SIZE = 3 ///< Size sentinel (not a valid mode)
};
// Aggregator for the solver's compile-time constants and data model. The
// public function-declaration surface (SolveBoard, CalcDDtable, ...) lives in
// <api/dll.h> and is included only by API consumers and the API implementation
// files, never by internal solver code.
#include <api/dds_constants.hpp>
#include <api/dds_data_types.hpp> // also pulls in <utility/constants.h>
11 changes: 6 additions & 5 deletions library/src/api/dds_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@
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 includes <api/dll.h>, whose flat API is
declared with C++ trailing-return syntax (auto ... -> int). 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
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/dll.h> /* struct Deal, FutureTricks, DdTableDeal, DdTableResults, ParResults */
#include <api/dds_c_data_types.h> /* struct Deal, FutureTricks, DdTableDeal, DdTableDealPBN, DdTableResults, ParResults; DLLEXPORT */

#ifdef __cplusplus
extern "C" {
Expand Down
81 changes: 81 additions & 0 deletions library/src/api/dds_c_data_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
DDS, a bridge double dummy solver.

Copyright (C) 2006-2014 by Bo Haglund /
2014-2018 by Bo Haglund & Soren Hein.

See LICENSE and README.
*/

#pragma once

/// @file dds_c_data_types.h
/// @brief The plain-old-data structures that cross the pure-C ABI shim.
///
/// This is the subset of the legacy data types that appear in
/// `dds_c_api.h` signatures (`struct Deal`, `struct FutureTricks`,
/// `struct DdTableDeal`, `struct DdTableDealPBN`, `struct DdTableResults`,
/// `struct ParResults`). It is split out from `dds_data_types.hpp` so the
/// C-ABI shim can pull in exactly what it passes by pointer and nothing
/// else. Every remaining legacy and internal type lives in
/// `dds_data_types.hpp`, which includes this header.

#include <api/dds_constants.hpp>

/**
* @brief Stores the result of a double dummy analysis for a single position.
*
* Contains the number of nodes searched, the number of cards in the result,
* and arrays for each card's suit, rank, equality group, and score.
*/
struct FutureTricks
{
int nodes;
int cards;
int suit[13];
int rank[13];
int equals[13];
int score[13];
};

/**
* @brief Represents a bridge Deal for double dummy analysis.
*
* @param trump The trump suit (0 = NT, 1 = Spades, ...)
* @param first The hand to play first (0 = N, 1 = E, ...)
* @param currentTrickSuit Suits of cards played in the current trick
* @param currentTrickRank Ranks of cards played in the current trick
* @param remainCards Remaining cards in each hand and suit
*/
struct Deal
{
int trump;
int first;
int currentTrickSuit[3];
int currentTrickRank[3];
unsigned int remainCards[DDS_HANDS][DDS_SUITS];
};

struct DdTableDeal
{
unsigned int cards[DDS_HANDS][DDS_SUITS];
};

struct DdTableDealPBN
{
char cards[80];
};

struct DdTableResults
{
int res_table[DDS_STRAINS][DDS_HANDS];
};

struct ParResults
{
/* index = 0 is NS view and index = 1
is EW view. By 'view' is here meant
which side that starts the bidding. */
char par_score[2][16];
char par_contracts_string[2][128];
};
Loading