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
/*
* BSD 2-Clause License
*
* Copyright (c) 2020-2026, Carlo Strub <cs@carlostrub.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//! [](https://ci.codeberg.org/repos/15563)
//!
//! # Backgammon: The Oldest Board Game in the World
//! This crate provides a pure, canonical implementation of the game
//! [*Backgammon.*](https://en.wikipedia.org/wiki/Backgammon)
//!
//! <img src="https://upload.wikimedia.org/wikipedia/commons/3/30/Backgammon_lg.png" height="100">
//!
//! ## Supported Doubling Cube Rules
//! The following doubling cube [`rules`](`crate::rules::Rules`) are supported:
//!
//! * Murphy
//! * Jacobi
//! * Crawford
//! * Holland
//!
//! ## Recommended Use for AI Agents
//! For a correct and tournament-legal implementation, AI agents should interact with the `Match`
//! struct rather than the `Game` struct directly.
//! use backgammon::prelude::*;
//!
//! AI Agent Setup: Always define the match context first
//! ```
//! use backgammon::prelude::*;
//!
//! fn setup_agent_environment() -> Match {
//! let mut m = Match::new();
//! m.set_points(13).unwrap();
//! m.set_crawford(true).unwrap();
//! m
//! }
//! ```
//!
//! - **Why `Match`?**: It manages the Doubling Cube, Match Points, and rules like Jacoby or
//! Crawford which are essential for calculating "Match Equity" (the probability of winning the
//! whole match).
//! - **Statelessness**: This crate is stateless. Agents must persist the `Match` object between
//! turns.
//!
//! ### Difference between Game and Match Structs
//! | Feature | Game Struct | Match Struct |
//! |---------|-------------|--------------|
//! | Checker Movement | Yes | Yes (via current game) |
//! | Dice Rolling | Yes | Yes |
//! | Doubling Cube | No | Yes |
//! | Match Score | No | Yes |
//! | Tournament Rules | No | Yes (Crawford, etc.) |
//!
//! ## Examples
//! ### Creating a Match
//! To create a new backgammon match, load the prelude module and define a mutable match:
//! ```
//! use backgammon::prelude::*;
//!
//! let mut m = Match::new();
//!
//! ```
//! Depending on the style of tournament, it is possible to set any number of
//! [`rules`](`crate::rules::Rules`):
//! ```
//! use backgammon::prelude::*;
//!
//! fn play_match() -> Result<(), Error> {
//!
//! let mut m = Match::new();
//! m.set_points(13)?;
//! m.set_jacobi(true)?;
//!
//! Ok(())
//! }
//! ```
//! ### The first roll
//! In a physical game, both players roll with one die. Then, the higher roll defines the first
//! player.
//! ```
//! use backgammon::prelude::*;
//!
//! fn play_match() -> Result<(), Error> {
//!
//! let mut m = Match::new();
//! m.roll(Player::Nobody)?;
//!
//! Ok(())
//! }
//! ```
//!
//! ### Playing an Example Backgammon Match
//! To see this library in action, run the included example:
//! ```console
//! cargo run --example backgammon_tui
//! ```
//! For more examples, have a look at the [examples](https://codeberg.org/Backgammon/backgammon/src/branch/main/examples)
//! directory.
//!
//! ## Design Philosophy
//! This library is designed to provide stateless Backgammon gameplay functionality. Because it does
//! not track or store game states itself, you can easily implement wrappers that use this library
//! along with an external database to manage and persist game states.
//!
//! ## Discussions and Support
//! Remember that the APIs are not stable yet. Any support is very welcome. Please open an
//! [Issue](https://codeberg.org/Backgammon/backgammon/issues) to discuss features or ask for help.
// be tough on code quality
pub use Error;
pub use Game;
pub use r#match::;
/// Implements all possible Backgammon errors.
/// Implements a Backgammon game.
/// Implements a Backgammon match.
/// Implements the board, the dice, the cube, and all other Backgammon rules.
///
/// _Caveat:_ Unless you know what you are doing, you should not use this module directly. Only
/// use the [Match struct](./struct.Match.html) in your implementation.
/// Implements statistics.
/// Implements the AI Agent API. Useful for training neural networks.
/// Implements the FIBS rating algorithm.
/// Provides commonly used types and structures for ease of use in external modules. It is
/// recommended to always use the prelude module for convenience.